diff --git a/ucoinj-cesium/redirector.err b/ucoinj-cesium/redirector.err new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-cesium/redirector.out b/ucoinj-cesium/redirector.out new file mode 100644 index 0000000000000000000000000000000000000000..9b92690788c7c893ccbf3355051d9bede66ffe8e --- /dev/null +++ b/ucoinj-cesium/redirector.out @@ -0,0 +1,18 @@ +[1m[32mRunning live reload server:[39m[22m undefined +[1m[32mWatching:[39m[22m 0=www/**/*, 1=!www/lib/**/* +[1m[32mRunning dev server: [39m[22m http://localhost:8100 +[1m[32mIonic server commands, enter:[39m[22m + restart[32m or [39mr[32m to restart the client app from the root[39m + goto[32m or [39mg[32m and a url to have the app navigate to the given url[39m + consolelogs[32m or [39mc[32m to enable/disable console log output[39m + serverlogs[32m or [39ms[32m to enable/disable server log output[39m + quit[32m or [39mq[32m to shutdown the server and exit[39m + +ionic $ [1m[32mIonic server commands, enter:[39m[22m + restart[32m or [39mr[32m to restart the client app from the root[39m + goto[32m or [39mg[32m and a url to have the app navigate to the given url[39m + consolelogs[32m or [39mc[32m to enable/disable console log output[39m + serverlogs[32m or [39ms[32m to enable/disable server log output[39m + quit[32m or [39mq[32m to shutdown the server and exit[39m + +ionic $ \ No newline at end of file diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainBlock.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainBlock.java index 32dfb34d732d3dafef624c01c5d0acd017734b18..3702ae181a24800a3736f1c9a9e108f714679753 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainBlock.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainBlock.java @@ -39,29 +39,31 @@ public class BlockchainBlock implements Serializable { private String version; private Integer nonce; - private Integer powMin; private Integer number; + private Integer powMin; private Integer time; private Integer medianTime; private Integer membersCount; private BigInteger monetaryMass; + private Integer unitBase; private String currency; private String issuer; - private String signature; private String hash; private String parameters; private String previousHash; private String previousIssuer; + private String inner_hash; private BigInteger dividend; - private String[] membersChanges; private Identity[] identities; private Joiner[] joiners; - private String[] actives; - private String[] leavers; + private Joiner[] leavers; + private Joiner[] actives; + private Revoked[] revoked; private String[] excluded; private String[] certifications; -// private int actives": [], -// private int transactions": [], + private Transaction[] transactions; + private String signature; + // raw": "Version: 1\nType: Block\nCurrency: zeta_brouzouf\nNonce: 8233\nNumber: 1\nDate: 1416589860\nConfirmedDate: 1416589860\nIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nPreviousHash: 00006CD96A01378465318E48310118AC6B2F3625\nPreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nMembersCount: 4\nIdentities:\nJoiners:\nActives:\nLeavers:\nExcluded:\nCertifications:\nTransactions:\n" //private String raw; @@ -181,9 +183,74 @@ public class BlockchainBlock implements Serializable { this.joiners = joiners; } + public Integer getUnitBase() { + return unitBase; + } + + public void setUnitBase(Integer unitBase) { + this.unitBase = unitBase; + } + + public String getInnerHash() { + return inner_hash; + } + + public void setInnerHash(String inner_hash) { + this.inner_hash = inner_hash; + } + + public Joiner[] getLeavers() { + return leavers; + } + + public void setLeavers(Joiner[] leavers) { + this.leavers = leavers; + } + + public Joiner[] getActives() { + return actives; + } + + public void setActives(Joiner[] actives) { + this.actives = actives; + } + + public Revoked[] getRevoked() { + return revoked; + } + + public void setRevoked(Revoked[] revoked) { + this.revoked = revoked; + } + + public String[] getExcluded() { + return excluded; + } + + public void setExcluded(String[] excluded) { + this.excluded = excluded; + } + + public String[] getCertifications() { + return certifications; + } + + public void setCertifications(String[] certifications) { + this.certifications = certifications; + } + + public Transaction[] getTransactions() { + return transactions; + } + + public void setTransactions(Transaction[] transactions) { + this.transactions = transactions; + } + public String toString() { String s = "version=" + version; s += "\nnonce=" + nonce; + s += "\ninner_hash=" + inner_hash; s += "\nnumber=" + number; s += "\npowMin" + powMin; s += "\ntime=" + time; @@ -199,11 +266,6 @@ public class BlockchainBlock implements Serializable { s += "\npreviousIssuer=" + previousIssuer; s += "\ndividend=" + dividend; s += "\nmembersChanges:"; - if (membersChanges != null) { - for (String m : membersChanges) { - s += "\n\t" + m; - } - } s += "\nidentities:"; if (identities != null) { for (Identity i : identities) { @@ -216,10 +278,22 @@ public class BlockchainBlock implements Serializable { s += "\n\t" + j.toString(); } } + s += "\nactives:"; + if (actives != null) { + for (Joiner a : actives) { + s += "\n\t" + a.toString(); + } + } s += "\nleavers:"; if (leavers != null) { - for (String l : leavers) { - s += "\n\t" + l; + for (Joiner l : leavers) { + s += "\n\t" + l.toString(); + } + } + s += "\nrevoked:"; + if (leavers != null) { + for (Revoked r : revoked) { + s += "\n\t" + r.toString(); } } s += "\nexcluded:"; @@ -242,20 +316,20 @@ public class BlockchainBlock implements Serializable { private static final long serialVersionUID = 8080689271400316984L; - private String pubkey; + private String publicKey; private String signature; - private String uid; + private String blockUid; - private long timestamp = -1; + private String userId; - public String getPubkey() { - return pubkey; + public String getPublicKey() { + return publicKey; } - public void setPubkey(String pubkey) { - this.pubkey = pubkey; + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; } public String getSignature() { @@ -266,29 +340,30 @@ public class BlockchainBlock implements Serializable { this.signature = signature; } - public String getUid() { - return uid; + public String getUserId() { + return userId; } - public void setUid(String uid) { - this.uid = uid; + public void setUserId(String uid) { + this.userId = uid; } - public long getTimestamp() { - return timestamp; + + public String getBlockUid() { + return blockUid; } - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; + public void setBlockUid(String blockUid) { + this.blockUid = blockUid; } @Override public String toString() { StringBuilder sb = new StringBuilder() - .append(":").append(pubkey) + .append(":").append(publicKey) .append(":").append(signature) - .append(":").append(timestamp) - .append("").append(uid); + .append(":").append(blockUid) + .append("").append(userId); return sb.toString(); } @@ -297,24 +372,23 @@ public class BlockchainBlock implements Serializable { public static class Joiner extends Identity { private static final long serialVersionUID = 8448049949323699700L; - private String pubkey; - private String signature; + private String publicKey; - private String uid; + private String signature; - private long timestamp = -1; + private String userId; - private String number; + private String mBlockUid; - private String hash; + private String iBlockUid; - public String getPubkey() { - return pubkey; + public String getPublicKey() { + return publicKey; } - public void setPubkey(String pubkey) { - this.pubkey = pubkey; + public void setPublicKey(String pubkey) { + this.publicKey = pubkey; } public String getSignature() { @@ -325,49 +399,183 @@ public class BlockchainBlock implements Serializable { this.signature = signature; } - public String getUid() { - return uid; + public String getUserId() { + return userId; + } + + public void setUserId(String uid) { + this.userId = uid; + } + + public String getMBlockUid() { + return mBlockUid; } - public void setUid(String uid) { - this.uid = uid; + public void setMBlockUid(String mBlockUid) { + this.mBlockUid = mBlockUid; } - public long getTimestamp() { - return timestamp; + public String getIBlockUid() { + return iBlockUid; } - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; + public void setIBlockUid(String iBlockUid) { + this.iBlockUid = iBlockUid; } - public String getNumber() { - return number; + @Override + public String toString() { + + StringBuilder sb = new StringBuilder() + .append(":").append(publicKey) + .append(":").append(signature) + .append(":").append(mBlockUid) + .append(":").append(iBlockUid) + .append(":").append(userId); + + return sb.toString(); } + } + + + public static class Revoked implements Serializable { + private String signature; + private String userId; - public void setNumber(String number) { - this.number = number; + public String getSignature() { + return signature; + } + public void setSignature(String signature) { + this.signature = signature; } - public String getHash() { - return hash; + public String getUserId() { + return userId; } - public void setHash(String hash) { - this.hash = hash; + public void setUserId(String userId) { + this.userId = userId; } @Override public String toString() { StringBuilder sb = new StringBuilder() - .append(":").append(pubkey) .append(":").append(signature) - .append(":").append(number) - .append(":").append(hash) - .append(":").append(timestamp) - .append(":").append(uid); + .append(":").append(userId); + + return sb.toString(); + } + } + + public class Transaction implements Serializable { + private static final long serialVersionUID = 1L; + private String[] signatures; + + private String version; + + private String currency; + + private String[] issuers; + + private String[] inputs; + + private String[] unlocks; + + private String[] outputs; + + public String[] getSignatures() { + return signatures; + } + + public void setSignatures(String[] signatures) { + this.signatures = signatures; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public String[] getIssuers() { + return issuers; + } + + public void setIssuers(String[] issuers) { + this.issuers = issuers; + } + + public String[] getInputs() { + return inputs; + } + + public void setInputs(String[] inputs) { + this.inputs = inputs; + } + + public String[] getUnlocks() { + return unlocks; + } + + public void setUnlocks(String[] unlocks) { + this.unlocks = unlocks; + } + + public String[] getOutputs() { + return outputs; + } + + public void setOutputs(String[] outputs) { + this.outputs = outputs; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("\nsignatures:"); + if (signatures != null) { + for (String e : signatures) { + sb.append("\n\t").append(e); + } + } + sb.append("\nversion: ").append(version); + sb.append("\ncurrency: ").append(currency); + sb.append("\nissuers:"); + if (issuers != null) { + for (String e : issuers) { + sb.append("\n\t").append(e); + } + } + sb.append("\ninputs:"); + if (inputs != null) { + for (String e : inputs) { + sb.append("\n\t").append(e); + } + } + sb.append("\nunlocks:"); + if (unlocks != null) { + for (String e : unlocks) { + sb.append("\n\t").append(e); + } + } + sb.append("\noutputs:"); + if (outputs != null) { + for (String e : outputs) { + sb.append("\n\t").append(e); + } + } return sb.toString(); } } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainParameters.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainParameters.java index de3b0a8571dc9ab027989dfb1b5b98a9e2f68d87..7f30af3612cc730ef4dfaec90830366eed7aae39 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainParameters.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainParameters.java @@ -53,27 +53,47 @@ public class BlockchainParameters implements Serializable{ private Long ud0; /** - * Minimum delay between 2 identical certifications (same pubkeys) + * Minimum delay between 2 certifications of a same issuer, in seconds. Must be positive or zero. */ - private Integer sigDelay; + private Integer sigPeriod; /** - * Maximum age of a valid signature (in seconds) (e.g. 2629800) + * Maximum quantity of active certifications made by member. + */ + private Integer sigStock; + + /** + * Maximum delay a certification can wait before being expired for non-writing. + */ + private Integer sigWindow; + + /** + * Maximum age of a active signature (in seconds) (e.g. 2629800) */ private Integer sigValidity; /** - * Minimum quantity of signatures to be part of the WoT (e.g. 3) + * Minimum quantity of signatures to be part of the WoT(e.g. 3) */ private Integer sigQty; /** - * Minimum quantity of valid made certifications to be part of the WoT for distance rule + * Maximum delay an identity can wait before being expired for non-writing. + */ + private Integer idtyWindow; + + /** + * Maximum delay a membership can wait before being expired for non-writing. + */ + private Integer msWindow; + + /** + * Minimum percent of sentries to reach to match the distance rule */ - private Integer sigWoT; + private Double xpercent; /** - * Maximum age of a valid membership (in seconds) + * Maximum age of an active membership (in seconds) */ private Integer msValidity; @@ -139,14 +159,6 @@ public class BlockchainParameters implements Serializable{ this.ud0 = ud0; } - public Integer getSigDelay() { - return sigDelay; - } - - public void setSigDelay(Integer sigDelay) { - this.sigDelay = sigDelay; - } - public Integer getSigValidity() { return sigValidity; } @@ -163,13 +175,6 @@ public class BlockchainParameters implements Serializable{ this.sigQty = sigQty; } - public Integer getSigWoT() { - return sigWoT; - } - - public void setSigWoT(Integer sigWoT) { - this.sigWoT = sigWoT; - } public Integer getMsValidity() { return msValidity; @@ -227,6 +232,54 @@ public class BlockchainParameters implements Serializable{ this.percentRot = percentRot; } + public Integer getSigPeriod() { + return sigPeriod; + } + + public void setSigPeriod(Integer sigPeriod) { + this.sigPeriod = sigPeriod; + } + + public Integer getSigStock() { + return sigStock; + } + + public void setSigStock(Integer sigStock) { + this.sigStock = sigStock; + } + + public Integer getSigWindow() { + return sigWindow; + } + + public void setSigWindow(Integer sigWindow) { + this.sigWindow = sigWindow; + } + + public Integer getIdtyWindow() { + return idtyWindow; + } + + public void setIdtyWindow(Integer idtyWindow) { + this.idtyWindow = idtyWindow; + } + + public Integer getMsWindow() { + return msWindow; + } + + public void setMsWindow(Integer msWindow) { + this.msWindow = msWindow; + } + + public Double getXpercent() { + return xpercent; + } + + public void setXpercent(Double xpercent) { + this.xpercent = xpercent; + } + @Override public String toString() { return new StringBuilder() @@ -234,10 +287,14 @@ public class BlockchainParameters implements Serializable{ .append("\nc=").append(c) .append("\ndt=").append(dt) .append("\nud0=").append(ud0) - .append("\nsigDelay=").append(sigDelay) + .append("\nsigPeriod=").append(sigPeriod) + .append("\nsigStock=").append(sigStock) + .append("\nsigWindow=").append(sigWindow) .append("\nsigValidity=").append(sigValidity) .append("\nsigQty=").append(sigQty) - .append("\nsigWoT=").append(sigWoT) + .append("\nidtyWindow=").append(idtyWindow) + .append("\nmsWindow=").append(msWindow) + .append("\nxpercent=").append(xpercent) .append("\nmsValidity=").append(msValidity) .append("\nstepMax=").append(stepMax) .append("\nmedianTimeBlocks=").append(medianTimeBlocks) diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/Error.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/Error.java new file mode 100644 index 0000000000000000000000000000000000000000..37aaef759e42d077cb35415e5eba5b2a2a213827 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/Error.java @@ -0,0 +1,35 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +import java.io.Serializable; + +/** + * Created by blavenie on 31/03/16. + */ +public class Error implements Serializable { + + private static final long serialVersionUID = -5598140972293478469L; + + private int ucode; + private String message; + + public int getUcode() { + return ucode; + } + + public void setUcode(int ucode) { + this.ucode = ucode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String toString() { + return "ucode=" + ucode + + "\nmessage=" + message; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/ErrorCode.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/ErrorCode.java new file mode 100644 index 0000000000000000000000000000000000000000..a934c5b5320aaf35ebe4fcdeebae376bad28690a --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/ErrorCode.java @@ -0,0 +1,10 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +/** + * Created by blavenie on 31/03/16. + */ +public interface ErrorCode { + + int UID_ALREADY_USED = 2002; + int MEMBERSHRIP_ALREADY_SEND = 2007; +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeering.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeering.java index 30d5ce21b199c659ed76d2d4cca80f9c2202cae0..992b9a66b23ff42f46b8ed2c48e5b87c8f38e803 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeering.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeering.java @@ -30,7 +30,6 @@ import java.io.Serializable; public class NetworkPeering implements Serializable { private String version; private String currency; - private String status; private String block; private String signature; // not need : private String raw @@ -54,14 +53,6 @@ public class NetworkPeering implements Serializable { this.currency = currency; } - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - public String getBlock() { return block; } @@ -87,7 +78,8 @@ public class NetworkPeering implements Serializable { } public String toString() { - String s = "currency=" + currency + "\n" + + String s = "version=" + version + "\n" + + "currency=" + currency + "\n" + "pubkey=" + pubkey + "\n" + "signature=" + signature + "\n" + "block=" + block + "\n"; diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/Protocol.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/Protocol.java new file mode 100644 index 0000000000000000000000000000000000000000..8fe452de02905cd53580a4dfe72a13fe511f8586 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/Protocol.java @@ -0,0 +1,15 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +/** + * Created by blavenie on 31/03/16. + */ +public interface Protocol { + + String VERSION = "2"; + + String TYPE_IDENTITY = "Identity"; + + String TYPE_MEMBERSHIP = "Membership"; + + String TYPE_TRANSACTION = "Transaction"; +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotLookup.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotLookup.java index 8d1f97201842658fc23a54e3b3e5c400ff7d47f2..5b98e37b8ede556cebb54fac1923f54ac9e4c66b 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotLookup.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotLookup.java @@ -97,6 +97,8 @@ public class WotLookup { public String uid; public Meta meta; public String self; + public Boolean revoked; + public String revocation_sig; public OtherSignature[] others; public String getUid() { @@ -130,12 +132,36 @@ public class WotLookup { public void setOthers(OtherSignature[] others) { this.others = others; } + + public Boolean getRevoked() { + return revoked; + } + + public void setRevoked(Boolean revoked) { + this.revoked = revoked; + } + + public String getRevocationSig() { + return revocation_sig; + } + + public void setRevocationSig(String revocationSig) { + this.revocation_sig = revocationSig; + } } public class Meta implements Serializable { - public Long timestamp; + public String timestamp; public Long block_number; + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } } public class OtherSignature { diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/GsonUtils.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/GsonUtils.java index af9c432520c19973d51c72b1437cc09577f3ec3f..43a19179401a8ab324222802f583c413b79968b6 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/GsonUtils.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/GsonUtils.java @@ -44,11 +44,11 @@ public class GsonUtils { .setDateFormat(DATE_PATTERN) // Register Multimap adapter .registerTypeAdapter(Multimap.class, new MultimapTypeAdapter()) - // Register Blockchain.identity adapter + // Register Blockchain.* adapter .registerTypeAdapter(BlockchainBlock.Identity.class, new IdentityTypeAdapter()) - // Register Blockchain.joiner adapter .registerTypeAdapter(BlockchainBlock.Joiner.class, new JoinerTypeAdapter()) - // Register endpoint adpater + .registerTypeAdapter(BlockchainBlock.Revoked.class, new RevokedTypeAdapter()) + // Register endpoint adapter .registerTypeAdapter(NetworkPeering.Endpoint.class, new EndpointAdapter()) ; } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/IdentityTypeAdapter.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/IdentityTypeAdapter.java index 0f5c12c8a2a134655bea90642c40400749f0dce1..b69cee8b8dad923a4280a78168074ad05c9be306 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/IdentityTypeAdapter.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/IdentityTypeAdapter.java @@ -46,10 +46,10 @@ public class IdentityTypeAdapter implements JsonDeserializer<BlockchainBlock.Ide BlockchainBlock.Identity result = new BlockchainBlock.Identity(); int i = 0; - result.setPubkey(identityParts[i++]); + result.setPublicKey(identityParts[i++]); result.setSignature(identityParts[i++]); - result.setTimestamp(Integer.parseInt(identityParts[i++])); - result.setUid(identityParts[i++]); + result.setBlockUid(identityParts[i++]); + result.setUserId(identityParts[i++]); return result; } @@ -57,10 +57,10 @@ public class IdentityTypeAdapter implements JsonDeserializer<BlockchainBlock.Ide @Override public JsonElement serialize(BlockchainBlock.Identity identity, Type type, JsonSerializationContext context) { String result = new StringBuilder() - .append(identity.getPubkey()).append(":") + .append(identity.getPublicKey()).append(":") .append(identity.getSignature()).append(":") - .append(identity.getTimestamp()).append(":") - .append(identity.getUid()).toString(); + .append(identity.getBlockUid()).append(":") + .append(identity.getUserId()).toString(); return context.serialize(result.toString(), String.class); } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JoinerTypeAdapter.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JoinerTypeAdapter.java index f1a0582a089ed9b33746adf0cb650eacff473bc2..66c90b2b99e5126bd9f026c286c13170dd7ff7c5 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JoinerTypeAdapter.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JoinerTypeAdapter.java @@ -24,7 +24,6 @@ package io.ucoin.ucoinj.core.client.model.bma.gson; import com.google.gson.*; -import io.ucoin.ucoinj.core.client.model.Member; import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; import org.apache.commons.lang3.StringUtils; @@ -40,19 +39,18 @@ public class JoinerTypeAdapter implements JsonDeserializer<BlockchainBlock.Joine } String[] identityParts = identityStr.split(":"); - if (identityParts.length != 6) { - throw new JsonParseException(String.format("Bad format for BlockchainBlock.Identity. Should have 6 parts, but found %s.", identityParts.length)); + if (identityParts.length != 5) { + throw new JsonParseException(String.format("Bad format for BlockchainBlock.Identity. Should have 5 parts, but found %s.", identityParts.length)); } BlockchainBlock.Joiner result = new BlockchainBlock.Joiner(); int i = 0; - result.setPubkey(identityParts[i++]); + result.setPublicKey(identityParts[i++]); result.setSignature(identityParts[i++]); - result.setNumber(identityParts[i++]); - result.setHash(identityParts[i++]); - result.setTimestamp(Integer.parseInt(identityParts[i++])); - result.setUid(identityParts[i++]); + result.setMBlockUid(identityParts[i++]); + result.setIBlockUid(identityParts[i++]); + result.setUserId(identityParts[i++]); return result; } @@ -60,12 +58,11 @@ public class JoinerTypeAdapter implements JsonDeserializer<BlockchainBlock.Joine @Override public JsonElement serialize(BlockchainBlock.Joiner member, Type type, JsonSerializationContext context) { String result = new StringBuilder() - .append(member.getPubkey()).append(":") + .append(member.getPublicKey()).append(":") .append(member.getSignature()).append(":") - .append(member.getNumber()).append(":") - .append(member.getHash()).append(":") - .append(member.getTimestamp()).append(":") - .append(member.getUid()).toString(); + .append(member.getMBlockUid()).append(":") + .append(member.getIBlockUid()).append(":") + .append(member.getUserId()).toString(); return context.serialize(result.toString(), String.class); } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/RevokedTypeAdapter.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/RevokedTypeAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..1625b8110fa528992ccb8b89e405147c48f9c543 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/RevokedTypeAdapter.java @@ -0,0 +1,63 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.gson.*; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Type; + +public class RevokedTypeAdapter implements JsonDeserializer<BlockchainBlock.Revoked>, JsonSerializer<BlockchainBlock.Revoked>{ + + @Override + public BlockchainBlock.Revoked deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + String identityStr = json.getAsString(); + if (StringUtils.isBlank(identityStr)) { + return null; + } + + String[] identityParts = identityStr.split(":"); + if (identityParts.length != 4) { + throw new JsonParseException(String.format("Bad format for BlockchainBlock.Revoked. Should have 4 parts, but found %s.", identityParts.length)); + } + + BlockchainBlock.Revoked result = new BlockchainBlock.Revoked(); + int i = 0; + + result.setSignature(identityParts[i++]); + result.setUserId(identityParts[i++]); + + return result; + } + + @Override + public JsonElement serialize(BlockchainBlock.Revoked input, Type type, JsonSerializationContext context) { + String result = new StringBuilder() + .append(input.getSignature()).append(":") + .append(input.getUserId()).toString(); + + return context.serialize(result.toString(), String.class); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Identity.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Identity.java index e9c326c62bc3885a2d74306f0b5db637d631670a..9aca1eac866b0d5bb3c8f0ba7ea3772f00acb5f9 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Identity.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Identity.java @@ -29,21 +29,21 @@ public class Identity extends BasicIdentity { private static final long serialVersionUID = -7451079677730158794L; - private long timestamp = -1; + private String timestamp = null; private Boolean isMember = null; private Long currencyId; /** - * The timestamp value of the signature date + * The timestamp value of the signature date (a BLOCK_UID) * @return */ - public long getTimestamp() { + public String getTimestamp() { return timestamp; } - public void setTimestamp(long timestamp) { + public void setTimestamp(String timestamp) { this.timestamp = timestamp; } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Wallet.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Wallet.java index 089940923365ce6c6636f1a6bfae41b497264bd1..c84738c70bb87e86a3f2e6d14bf2df20295d768e 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Wallet.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Wallet.java @@ -117,7 +117,7 @@ public class Wallet extends KeyPair implements LocalEntity, Serializable { } public boolean isSelfSend() { - return identity.getTimestamp() != -1; + return identity.getTimestamp() != null; } public Long getCurrencyId() { @@ -174,11 +174,11 @@ public class Wallet extends KeyPair implements LocalEntity, Serializable { identity.setUid(uid); } - public long getCertTimestamp() { + public String getCertTimestamp() { return identity.getTimestamp(); } - public void setCertTimestamp(long timestamp) { + public void setCertTimestamp(String timestamp) { identity.setTimestamp(timestamp); } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpServiceImpl.java index 730d6efefb25a7cefa4ee0e64283d4cf907663b1..e0ac4968ad9d1a5a24203579baa1d7135e694706 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpServiceImpl.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpServiceImpl.java @@ -25,6 +25,7 @@ package io.ucoin.ucoinj.core.client.service; import com.google.gson.Gson; import io.ucoin.ucoinj.core.beans.InitializingBean; import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.bma.Error; import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; import io.ucoin.ucoinj.core.client.model.local.Peer; import io.ucoin.ucoinj.core.client.service.exception.HttpBadRequestException; @@ -191,7 +192,13 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean case HttpStatus.SC_FORBIDDEN: throw new TechnicalException("ucoinj.client.authentication"); case HttpStatus.SC_BAD_REQUEST: - throw new HttpBadRequestException("ucoinj.client.status" + response.getStatusLine().toString()); + try { + Error error = (Error)parseResponse(response, Error.class); + throw new HttpBadRequestException(error); + } + catch(IOException e) { + throw new HttpBadRequestException("ucoinj.client.status" + response.getStatusLine().toString()); + } default: throw new TechnicalException("ucoinj.client.status" + response.getStatusLine().toString()); } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BaseRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BaseRemoteServiceImpl.java index a98d7ec809e9007add2198d075b723ade01a5044..5b9e9fc2a1dd2dee22ec3d2b3c422b62d46a769c 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BaseRemoteServiceImpl.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BaseRemoteServiceImpl.java @@ -24,6 +24,7 @@ package io.ucoin.ucoinj.core.client.service.bma; import io.ucoin.ucoinj.core.beans.InitializingBean; import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.bma.Protocol; import io.ucoin.ucoinj.core.client.model.local.Peer; import io.ucoin.ucoinj.core.client.service.HttpService; import io.ucoin.ucoinj.core.client.service.local.PeerService; @@ -40,8 +41,6 @@ public abstract class BaseRemoteServiceImpl implements Service, InitializingBean protected HttpService httpService; protected PeerService peerService; - public static final String PROTOCOL_VERSION = "1"; - @Override public void afterPropertiesSet() { httpService = ServiceLocator.instance().getHttpService(); diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteService.java index 75d0c6a850d6f995873aaec1baa469167a7dad35..77da05d82a4ab1b4a9267d29feb98124a296e2be 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteService.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteService.java @@ -197,6 +197,8 @@ public interface BlockchainRemoteService extends Service { */ void requestMembership(Wallet wallet); + void requestMembership(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String membershipBlockUid, String selfBlockUid); + BlockchainMemberships getMembershipByPubkeyOrUid(long currencyId, String uidOrPubkey); BlockchainMemberships getMembershipByPubkeyOrUid(Peer peer, String uidOrPubkey); diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceImpl.java index a24867a817aacfa7454007647f350a8a8472038a..899c676fd0bebc3e4dbbc5b652fca0ff53f2d985 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceImpl.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceImpl.java @@ -26,6 +26,7 @@ import io.ucoin.ucoinj.core.client.config.Configuration; import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; import io.ucoin.ucoinj.core.client.model.bma.BlockchainMemberships; import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.bma.Protocol; import io.ucoin.ucoinj.core.client.model.bma.gson.JsonArrayParser; import io.ucoin.ucoinj.core.client.model.local.Currency; import io.ucoin.ucoinj.core.client.model.local.Identity; @@ -38,11 +39,11 @@ import io.ucoin.ucoinj.core.client.service.exception.UidAlreadyUsedException; import io.ucoin.ucoinj.core.client.service.exception.UidMatchAnotherPubkeyException; import io.ucoin.ucoinj.core.exception.TechnicalException; import io.ucoin.ucoinj.core.service.CryptoService; -import io.ucoin.ucoinj.core.util.CollectionUtils; import io.ucoin.ucoinj.core.util.ObjectUtils; import io.ucoin.ucoinj.core.util.StringUtils; import io.ucoin.ucoinj.core.util.cache.Cache; import io.ucoin.ucoinj.core.util.cache.SimpleCache; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; import io.ucoin.ucoinj.core.util.websocket.WebsocketClientEndpoint; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; @@ -364,13 +365,14 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement public void requestMembership(Wallet wallet) { ObjectUtils.checkNotNull(wallet); ObjectUtils.checkNotNull(wallet.getCurrencyId()); + ObjectUtils.checkNotNull(wallet.getCertTimestamp()); BlockchainBlock block = getCurrentBlock(wallet.getCurrencyId()); // Compute membership document String membership = getMembership(wallet, block, - true /*sideIn*/); + true /*side in*/); if (log.isDebugEnabled()) { log.debug(String.format( @@ -396,6 +398,28 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement executeRequest(httpPost, String.class); } + + public void requestMembership(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String membershipBlockUid, String selfBlockUid) { + // http post /blockchain/membership + HttpPost httpPost = new HttpPost(getPath(peer, URL_MEMBERSHIP)); + + // compute the self-certification + String membership = getSignedMembership(currency, pubKey, secKey, uid, membershipBlockUid, selfBlockUid, true/*side in*/); + + List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); + urlParameters.add(new BasicNameValuePair("membership", membership)); + + try { + httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); + } + catch(UnsupportedEncodingException e) { + throw new TechnicalException(e); + } + + // Execute the request + executeRequest(httpPost, String.class); + } + public BlockchainMemberships getMembershipByPubkeyOrUid(long currencyId, String uidOrPubkey) { String path = String.format(URL_MEMBERSHIP_SEARCH, uidOrPubkey); @@ -428,13 +452,12 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement ) { // Create the member ship document - String membership = getMembership(wallet.getUid(), + String membership = getUnsignedMembership( wallet.getCurrency(), wallet.getPubKeyHash(), - wallet.getCurrency(), - block.getNumber(), - block.getHash(), - sideIn, - wallet.getCertTimestamp() + wallet.getUid(), + block.getNumber() + '-' + block.getHash(), + wallet.getCertTimestamp(), + sideIn ); // Add signature @@ -585,7 +608,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement // Self certification not exists: make sure the cert time is cleaning else { - identity.setTimestamp(-1); + identity.setTimestamp(null); } } } @@ -593,7 +616,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement // UID and pubkey is a member: fine else if (identity.getPubkey().equals(result.getPubkey())) { identity.setMember(true); - identity.setTimestamp(result.getSigDate()); + //FIXME identity.setTimestamp(result.getSigDate()); } // Something wrong on pubkey : uid already used by anither pubkey ! @@ -642,25 +665,52 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement return result; } - private String getMembership(String uid, - String publicKey, - String currency, - long blockNumber, - String blockHash, - boolean sideIn, - long certificationTime + protected String getSignedMembership(String currency, + byte[] pubKey, + byte[] secKey, + String userId, + String membershipBlockUid, + String selfBlockUid, + boolean sideIn) { + // Compute the pub key hash + String pubKeyHash = CryptoUtils.encodeBase58(pubKey); + + // Create the member ship document + String membership = getUnsignedMembership(currency, + pubKeyHash, + userId, + membershipBlockUid, + selfBlockUid, + sideIn + ); + + // Add signature + CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); + String signature = cryptoService.sign(membership, secKey); + + return new StringBuilder().append(membership).append(signature) + .append('\n').toString(); + } + + protected String getUnsignedMembership(String currency, + String pubkey, + String userId, + String membershipBlockUid, + String selfBlockUid, + boolean sideIn ) { - StringBuilder result = new StringBuilder() - .append("Version: 1\n") - .append("Type: Membership\n") - .append("Currency: ").append(currency).append('\n') - .append("Issuer: ").append(publicKey).append('\n') - .append("Block: ").append(blockNumber).append('-').append(blockHash).append('\n') - .append("Membership: ").append(sideIn ? "IN" : "OUT").append('\n') - .append("UserID: ").append(uid).append('\n') - .append("CertTS: ").append(certificationTime).append('\n'); - - return result.toString(); + // see https://github.com/ucoin-io/ucoin/blob/master/doc/Protocol.md#membership + return new StringBuilder() + .append("Version: ").append(Protocol.VERSION) + .append("\nType: ").append(Protocol.TYPE_MEMBERSHIP) + .append("\nCurrency: ").append(currency) + .append("\nIssuer: ").append(pubkey) + .append("\nBlock: ").append(membershipBlockUid) + .append("\nMembership: ").append(sideIn ? "IN" : "OUT") + .append("\nUserID: ").append(userId) + .append("\nCertTS: ").append(selfBlockUid) + .append("\n") + .toString(); } private Integer getLastBlockNumberFromJson(final String json) { diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteService.java index 852226a67d8081e0f7c2a9f3eb90b16d6b72375c..4e0414ffb748e61b50bf35a7c9da15ed7892525f 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteService.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteService.java @@ -33,8 +33,8 @@ import io.ucoin.ucoinj.core.client.service.exception.InsufficientCreditException public interface TransactionRemoteService extends Service { - String transfert(Wallet wallet, String destPubKey, long amount, - String comment) throws InsufficientCreditException; + String transfer(Wallet wallet, String destPubKey, long amount, + String comment) throws InsufficientCreditException; TxSource getSources(long currencyId, String pubKey); diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java index 0354350abb2532bced9175b0afde0d09b7bc90bc..85a9f877bbafdfa56aa77d7f08a6bc76213f6598 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java @@ -24,6 +24,7 @@ package io.ucoin.ucoinj.core.client.service.bma; import io.ucoin.ucoinj.core.client.model.TxOutput; +import io.ucoin.ucoinj.core.client.model.bma.Protocol; import io.ucoin.ucoinj.core.client.model.bma.TxHistory; import io.ucoin.ucoinj.core.client.model.bma.TxSource; import io.ucoin.ucoinj.core.client.model.local.Peer; @@ -73,8 +74,8 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen cryptoService = ServiceLocator.instance().getCryptoService(); } - public String transfert(Wallet wallet, String destPubKey, long amount, - String comment) throws InsufficientCreditException { + public String transfer(Wallet wallet, String destPubKey, long amount, + String comment) throws InsufficientCreditException { // http post /tx/process HttpPost httpPost = new HttpPost( @@ -248,7 +249,8 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen String comments) { StringBuilder sb = new StringBuilder(); - sb.append("Version: 1\n").append("Type: Transaction\n") + sb.append("Version: ").append(Protocol.VERSION).append("\n") + .append("Type: ").append(Protocol.TYPE_TRANSACTION).append("\n") .append("Currency: ").append(currency).append('\n') .append("Issuers:\n") // add issuer pubkey @@ -264,6 +266,16 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen .append(input.getAmount()).append('\n'); } + // Unlocks + sb.append("Inputs:\n"); + for (TxSource.Source input : inputs) { + // INDEX:SOURCE:NUMBER:FINGERPRINT:AMOUNT + sb.append(0).append(':').append(input.getType()).append(':') + .append(input.getNumber()).append(':') + .append(input.getFingerprint()).append(':') + .append(input.getAmount()).append('\n'); + } + // Output sb.append("Outputs:\n"); for (TxOutput output : outputs) { @@ -286,7 +298,7 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen StringBuilder sb = new StringBuilder(); sb.append("TX:") // VERSION - .append(PROTOCOL_VERSION).append(':') + .append(Protocol.VERSION).append(':') // NB_ISSUERS .append("1:") // NB_INPUTS diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteService.java index 20c1dc98560a3d651a3258b5cf07478312a0e485..37f0b443ac9c55a6dfe41c7c6cc28af69c8489d4 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteService.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteService.java @@ -62,22 +62,22 @@ public interface WotRemoteService extends Service { WotCertification getCertifiersOf(long currencyId, String uid); - String getSelfCertification(byte[] secKey, String uid, long timestamp); + String getSignedIdentity(String currency, byte[] pubKey, byte[] secKey, String uid, String blockUid); - void sendSelf(long currencyId, byte[] pubKey, byte[] secKey, String uid, long timestamp); + void sendIdentity(long currencyId, byte[] pubKey, byte[] secKey, String uid, String blockUid); + + void sendIdentity(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String blockUid); String getCertification(byte[] pubKey, byte[] secKey, String userUid, - long userTimestamp, - String userSignature, - int blockNumber, - String blockHash); + String userTimestamp, + String userSignature); String sendCertification(Wallet wallet, Identity identity); String sendCertification(long currencyId, byte[] pubKey, byte[] secKey, - String uid, long timestamp, + String uid, String timestamp, String userUid, String userPubKeyHash, - long userTimestamp, String userSignature); + String userTimestamp, String userSignature); } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceImpl.java index 764b89eabe774b9ad6c4ffd59c8c442a7249960d..3ef399ca621e6c846f0f3461858b59e6df456544 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceImpl.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceImpl.java @@ -23,15 +23,13 @@ package io.ucoin.ucoinj.core.client.service.bma; */ import io.ucoin.ucoinj.core.client.model.ModelUtils; -import io.ucoin.ucoinj.core.client.model.bma.WotCertification; -import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; -import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; -import io.ucoin.ucoinj.core.client.model.bma.WotLookup; +import io.ucoin.ucoinj.core.client.model.bma.*; import io.ucoin.ucoinj.core.client.model.local.Certification; import io.ucoin.ucoinj.core.client.model.local.Identity; import io.ucoin.ucoinj.core.client.model.local.Peer; import io.ucoin.ucoinj.core.client.model.local.Wallet; import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.client.service.local.CurrencyService; import io.ucoin.ucoinj.core.exception.TechnicalException; import io.ucoin.ucoinj.core.service.CryptoService; import io.ucoin.ucoinj.core.util.CollectionUtils; @@ -71,6 +69,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe private CryptoService cryptoService; private BlockchainRemoteService bcService; + private CurrencyService currencyService; public WotRemoteServiceImpl() { super(); @@ -81,6 +80,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe super.afterPropertiesSet(); cryptoService = ServiceLocator.instance().getCryptoService(); bcService = ServiceLocator.instance().getBlockchainRemoteService(); + currencyService = ServiceLocator.instance().getCurrencyService(); } public List<Identity> findIdentities(Set<Long> currenciesIds, String uidOrPubKey) { @@ -282,20 +282,38 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } - public void sendSelf(long currencyId, byte[] pubKey, byte[] secKey, String uid, long timestamp) { + public void sendIdentity(long currencyId, byte[] pubKey, byte[] secKey, String userId, String blockUid) { // http post /wot/add HttpPost httpPost = new HttpPost(getPath(currencyId, URL_ADD)); - // Compute the pub key hash - String pubKeyHash = CryptoUtils.encodeBase58(pubKey); + String currency = currencyService.getCurrencyNameById(currencyId); + + // compute the self-certification + String identity = getSignedIdentity(currency, pubKey, secKey, userId, blockUid); + + List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); + urlParameters.add(new BasicNameValuePair("identity", identity)); + + try { + httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); + } + catch(UnsupportedEncodingException e) { + throw new TechnicalException(e); + } + + // Execute the request + executeRequest(httpPost, String.class); + } + + public void sendIdentity(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String blockUid) { + // http post /wot/add + HttpPost httpPost = new HttpPost(getPath(peer, URL_ADD)); // compute the self-certification - String selfCertification = getSelfCertification(secKey, uid, timestamp); + String identity = getSignedIdentity(currency, pubKey, secKey, uid, blockUid); List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); - urlParameters.add(new BasicNameValuePair("pubkey", pubKeyHash)); - urlParameters.add(new BasicNameValuePair("self", selfCertification)); - urlParameters.add(new BasicNameValuePair("other", "")); + urlParameters.add(new BasicNameValuePair("identity", identity)); try { httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); @@ -324,9 +342,9 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe public String sendCertification(long currencyId, byte[] pubKey, byte[] secKey, - String uid, long timestamp, + String uid, String timestamp, String userUid, String userPubKeyHash, - long userTimestamp, String userSignature) { + String userBlockUid, String userSignature) { // http post /wot/add HttpPost httpPost = new HttpPost(getPath(currencyId, URL_ADD)); @@ -341,18 +359,19 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe // Compute the pub key hash String pubKeyHash = CryptoUtils.encodeBase58(pubKey); - // compute the self-certification - String selfCertification = getSelfCertification(userUid, userTimestamp, userSignature); + // compute signed identity + String identity = getIdentity(currentBlock.getCurrency(), + pubKeyHash, userUid, userBlockUid, userSignature); // Compute the certification - String certification = getCertification(pubKey, secKey, - userUid, userTimestamp, userSignature, - blockNumber, blockHash); + String certification = null; /* FIXME getCertification(pubKey, secKey, + userUid, userBlockUid, userSignature, + blockNumber, blockHash);*/ String inlineCertification = toInlineCertification(pubKeyHash, userPubKeyHash, certification); List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); - urlParameters.add(new BasicNameValuePair("pubkey", userPubKeyHash)); - urlParameters.add(new BasicNameValuePair("self", selfCertification)); + urlParameters.add(new BasicNameValuePair("identity", identity)); + urlParameters.add(new BasicNameValuePair("self", identity)); urlParameters.add(new BasicNameValuePair("other", inlineCertification)); try { @@ -403,26 +422,23 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe target.setUid(source.getUid()); target.setSelf(source.getSelf()); - Long timestamp = source.getMeta() != null ? source.getMeta().timestamp : null; - target.setTimestamp(timestamp); + String timestamp = source.getMeta() != null ? source.getMeta().timestamp : null; + //FIXME target.setTimestamp(timestamp); } - public String getSelfCertification(byte[] secKey, String uid, long timestamp) { - // Create the self part to sign - StringBuilder buffer = new StringBuilder() - .append("UID:") - .append(uid) - .append("\nMETA:TS:") - .append(timestamp) - .append('\n'); + public String getSignedIdentity(String currency, byte[] pubKey, byte[] secKey, String uid, String blockUid) { + + // Compute the pub key hash + String pubKeyHash = CryptoUtils.encodeBase58(pubKey); + + // Create identity to sign + String unsignedIdentity = getUnsignedIdentity(currency, pubKeyHash, uid, blockUid); // Compute the signature - String signature = cryptoService.sign(buffer.toString(), secKey); + String signature = cryptoService.sign(unsignedIdentity, secKey); // Append the signature - return buffer.append(signature) - .append('\n') - .toString(); + return unsignedIdentity + signature + '\n'; } /* -- Internal methods -- */ @@ -449,7 +465,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe cert.setCertifiedBy(false); result.add(cert); - long certificationAge = medianTime - certifier.getTimestamp(); + /*FIXME long certificationAge = medianTime - certifier.getTimestamp(); if(certificationAge <= sigValidity) { if (certifier.getIsMember() != null && certifier.getIsMember().booleanValue() && certifier.getWritten()!=null && certifier.getWritten().getNumber()>=0) { @@ -459,7 +475,7 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } else { cert.setValid(false); - } + }*/ } } @@ -488,12 +504,15 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe cert.setCertifiedBy(true); result.add(cert); + // FIXME + /* long certificationAge = medianTime - certifiedBy.getTimestamp(); if (certificationAge <= sigValidity) { cert.setValid(true); } else { cert.setValid(false); } + */ } } @@ -596,13 +615,11 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } public String getCertification(byte[] pubKey, byte[] secKey, String userUid, - long userTimestamp, - String userSignature, - int blockNumber, - String blockHash) { + String userTimestamp, + String userSignature) { // Create the self part to sign String unsignedCertification = getCertificationUnsigned( - userUid, userTimestamp, userSignature, blockNumber, blockHash); + userUid, userTimestamp, userSignature); // Compute the signature String signature = cryptoService.sign(unsignedCertification, secKey); @@ -616,10 +633,8 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe } protected String getCertificationUnsigned(String userUid, - long userTimestamp, - String userSignature, - int blockNumber, - String blockHash) { + String userTimestamp, + String userSignature) { // Create the self part to sign return new StringBuilder() .append("UID:") @@ -628,29 +643,38 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe .append(userTimestamp) .append('\n') .append(userSignature) - .append("\nMETA:TS:") + /*.append("\nMETA:TS:") .append(blockNumber) .append('-') - .append(blockHash) + .append(blockHash)*/ .append('\n').toString(); } - protected String getSelfCertification(String uid, - long timestamp, - String signature) { - // Create the self part to sign + protected String getUnsignedIdentity(String currency, + String pubkey, + String userId, + String blockUid) { + // see https://github.com/ucoin-io/ucoin/blob/master/doc/Protocol.md#identity return new StringBuilder() - .append("UID:") - .append(uid) - .append("\nMETA:TS:") - .append(timestamp) - .append('\n') - .append(signature) - // FIXME : in ucoin, no '\n' here - is it a bug ? - //.append('\n') + .append("Version: ").append(Protocol.VERSION) + .append("\nType: ").append(Protocol.TYPE_IDENTITY) + .append("\nCurrency: ").append(currency) + .append("\nIssuer: ").append(pubkey) + .append("\nUniqueID: ").append(userId) + .append("\nTimestamp: ").append(blockUid) + .append("\n") .toString(); } + protected String getIdentity(String currency, + String pubkey, + String userId, + String blockUid, + String signature) { + return getUnsignedIdentity(currency, pubkey, userId, blockUid) + + "\n" + signature; + } + protected WotLookup.Uid getUid(WotLookup lookupResults, String filterUid) { if (lookupResults.getResults() == null || lookupResults.getResults().length == 0) { return null; @@ -762,9 +786,9 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe if (source.meta != null) { // timestamp - Long timestamp = source.meta != null ? source.meta.timestamp : null; + String timestamp = source.meta != null ? source.meta.timestamp : null; if (timestamp != null) { - target.setTimestamp(timestamp.longValue()); + //FIXME target.setTimestamp(timestamp.longValue()); } } @@ -858,4 +882,5 @@ public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRe previousCert.setTimestamp(cert.getTimestamp()); } } + } diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/HttpBadRequestException.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/HttpBadRequestException.java index b96c7255a14acb05c3282160b3bf93d4624bb563..32cf18ad670badb1516e40ba87059f4212c78235 100644 --- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/HttpBadRequestException.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/HttpBadRequestException.java @@ -22,6 +22,7 @@ package io.ucoin.ucoinj.core.client.service.exception; * #L% */ +import io.ucoin.ucoinj.core.client.model.bma.Error; import io.ucoin.ucoinj.core.exception.TechnicalException; /** @@ -43,7 +44,13 @@ public class HttpBadRequestException extends TechnicalException{ super(message); } + public HttpBadRequestException(Error error) { + super(error.getMessage()); + setCode(error.getUcode()); + } + public HttpBadRequestException(Throwable cause) { super(cause); } + } diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceTest.java index 9684b0844f290ff3ff2e05f31232ef8382aa61c2..966730bc4947213638e379b8ecf2a6e27f6ec542 100644 --- a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceTest.java +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceTest.java @@ -27,13 +27,15 @@ import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import io.ucoin.ucoinj.core.client.TestResource; import io.ucoin.ucoinj.core.client.config.Configuration; -import io.ucoin.ucoinj.core.client.model.BasicIdentity; import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; -import io.ucoin.ucoinj.core.client.model.Member; +import io.ucoin.ucoinj.core.client.model.bma.ErrorCode; import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.client.service.exception.HttpBadRequestException; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; import io.ucoin.ucoinj.core.util.websocket.WebsocketClientEndpoint; import org.junit.*; import org.slf4j.Logger; @@ -63,6 +65,8 @@ public class BlockchainRemoteServiceTest { Assert.assertNotNull(result); Assert.assertNotNull(result.getCurrency()); + + Assert.assertEquals(resource.getFixtures().getCurrency(), result.getCurrency()); } @Test @@ -74,11 +78,11 @@ public class BlockchainRemoteServiceTest { Assert.assertNotNull(result.getCurrency()); for (BlockchainBlock.Identity id: result.getIdentities()) { - Assert.assertNotNull(id.getUid()); + Assert.assertNotNull(id.getUserId()); } for (BlockchainBlock.Joiner id: result.getJoiners()) { - Assert.assertNotNull(id.getUid()); + Assert.assertNotNull(id.getUserId()); } } @@ -128,6 +132,30 @@ public class BlockchainRemoteServiceTest { } } + + @Test + public void requestMembership() throws Exception { + Peer peer = createTestPeer(); + Wallet wallet = createTestWallet(); + String uid = resource.getFixtures().getUid(); + String currency = resource.getFixtures().getCurrency(); + String selfIdentityBlockUid = resource.getFixtures().getSelfIdentityBlockUid(); + + // Get the block UID + BlockchainRemoteService blockchainRemoteService = ServiceLocator.instance().getBlockchainRemoteService(); + BlockchainBlock currentBlock = blockchainRemoteService.getCurrentBlock(peer); + Assume.assumeNotNull(currentBlock); + String blockUid = currentBlock.getNumber() + "-" + currentBlock.getHash(); + + try { + service.requestMembership(peer, currency, wallet.getPubKey(), wallet.getSecKey(), uid, blockUid, selfIdentityBlockUid); + } + catch(HttpBadRequestException e) { + Assert.assertEquals(ErrorCode.MEMBERSHRIP_ALREADY_SEND, e.getCode()); + + } + } + /* -- Internal methods -- */ protected Peer createTestPeer() { @@ -137,4 +165,14 @@ public class BlockchainRemoteServiceTest { return peer; } + + protected Wallet createTestWallet() { + Wallet wallet = new Wallet( + resource.getFixtures().getCurrency(), + resource.getFixtures().getUid(), + CryptoUtils.decodeBase58(resource.getFixtures().getUserPublicKey()), + CryptoUtils.decodeBase58(resource.getFixtures().getUserSecretKey())); + + return wallet; + } } diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceTest.java index 7c93d5196fd95f529a03f23979fb5c41310799d0..5b3dfdd8395b95ec579ba783c6cdb8d8dff397c8 100644 --- a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceTest.java +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceTest.java @@ -52,10 +52,9 @@ public class TransactionRemoteServiceTest { } @Test - public void transfert() throws Exception { + public void transfer() throws Exception { - - service.transfert( + service.transfer( createTestWallet(), resource.getFixtures().getOtherUserPublicKey(), 1, diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceTest.java index 4910902ddc245ba18bed8897f60781ae69c2d8d0..487e47b72c3b71ed82817d5527299108b258ee35 100644 --- a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceTest.java +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceTest.java @@ -25,20 +25,16 @@ package io.ucoin.ucoinj.core.client.service.bma; import io.ucoin.ucoinj.core.client.TestResource; import io.ucoin.ucoinj.core.client.config.Configuration; -import io.ucoin.ucoinj.core.client.model.BasicIdentity; -import io.ucoin.ucoinj.core.client.model.bma.WotCertification; -import io.ucoin.ucoinj.core.client.model.bma.WotLookup; +import io.ucoin.ucoinj.core.client.model.bma.*; import io.ucoin.ucoinj.core.client.model.local.Identity; import io.ucoin.ucoinj.core.client.model.local.Peer; import io.ucoin.ucoinj.core.client.model.local.Wallet; import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.client.service.exception.HttpBadRequestException; import io.ucoin.ucoinj.core.util.CollectionUtils; import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; import io.ucoin.ucoinj.core.util.crypto.SecretBox; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; +import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -134,51 +130,24 @@ public class WotRemoteServiceTest { } @Test - public void sendSelf() throws Exception { - - SecretBox secretBox = createSecretBox(); - - String uid = resource.getFixtures().getUid(); - long timestamp = resource.getFixtures().getSelfTimestamp(); - Wallet wallet = createTestWallet(); - - String selfCertification = service.getSelfCertification( - wallet.getSecKey(), - wallet.getUid(), - timestamp); - - String expectedCertification = String.format( - "UID:%s\nMETA:TS:%s\n%s\n", uid, timestamp, resource - .getFixtures().getSelfSignature()); - - Assert.assertEquals(expectedCertification, selfCertification); - } - - @Test - public void getCertification() throws Exception { - - Wallet wallet = createTestWallet(); - - String userUid = "kimamila"; - long userTimestamp = 1418377981; - String userSelf = "pVO6YMhZMl5pPxa33hpFCNljIZ0fO6HMPp9d+uW+DVT4DJXP+tQ5XzLfvOaT3uH+3Slx3BiuH/fADleSp873Cg=="; - int blockNumber = 3328; - String blockHash = "0837171AD6CE72B7DAD0409A230D43A9CCFFE0DC"; - - String selfCertification = service.getCertification(wallet.getPubKey(), - wallet.getSecKey(), userUid, - userTimestamp, userSelf, blockNumber, blockHash); - - String expectedCertification = String - .format("UID:%s\nMETA:TS:%s\n%s\nMETA:TS:%s-%s\n%s\n", - userUid, - userTimestamp, - userSelf, - blockNumber, - blockHash, - "wOAbhxPzlnwmKgMXirPjxNno5tsHN95KMSUrVrZSLPcXn69cFg6ZbiWpSKVSFcHVVuZ4rhRvi46RFvVT/yFuDA=="); - - Assert.assertEquals(expectedCertification, selfCertification); + public void sendIdentity() throws Exception { + Peer peer = createTestPeer(); + Wallet wallet = createTestWallet(); + String uid = resource.getFixtures().getUid(); + String currency = resource.getFixtures().getCurrency(); + + // Get the block UID + BlockchainRemoteService blockchainRemoteService = ServiceLocator.instance().getBlockchainRemoteService(); + BlockchainBlock currentBlock = blockchainRemoteService.getCurrentBlock(peer); + Assume.assumeNotNull(currentBlock); + String blockUid = currentBlock.getNumber() + "-" + currentBlock.getHash(); + + try { + service.sendIdentity(peer, currency, wallet.getPubKey(), wallet.getSecKey(), uid, blockUid); + } + catch(HttpBadRequestException e) { + Assert.assertEquals(ErrorCode.UID_ALREADY_USED, e.getCode()); + } } /* -- internal methods */ @@ -193,12 +162,11 @@ public class WotRemoteServiceTest { return wallet; } - protected SecretBox createSecretBox() { - String salt = resource.getFixtures().getUserSalt(); - String password = resource.getFixtures().getUserPassword(); - SecretBox secretBox = new SecretBox(salt, password); + protected Peer createTestPeer() { + Peer peer = new Peer( + Configuration.instance().getNodeHost(), + Configuration.instance().getNodePort()); - return secretBox; + return peer; } - } diff --git a/ucoinj-core-client/src/test/resources/ucoinj-core-client-test.properties b/ucoinj-core-client/src/test/resources/ucoinj-core-client-test.properties index 0774f09e68a257a381edb39debc29254a00018dd..935715198000eb25cd750d3e407c66c67c7a4e97 100644 --- a/ucoinj-core-client/src/test/resources/ucoinj-core-client-test.properties +++ b/ucoinj-core-client/src/test/resources/ucoinj-core-client-test.properties @@ -1,7 +1,12 @@ #ucoinj.node.host=metab.ucoin.io #ucoinj.node.host=metab.ucoin.fr -ucoinj.node.host=192.168.0.28 -ucoinj.node.port=9201 + +#ucoinj.node.host=192.168.0.28 +#ucoinj.node.port=9201 + +ucoinj.node.host=twiced.fr +ucoinj.node.port=9330 + ucoinj.node.elasticsearch.host=localhost ucoinj.node.elasticsearch.port=9200 diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/TechnicalException.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/TechnicalException.java index ef8d644ea8caf7472d2b2f8a0165810176182e95..ab430c542aabc4013c6521533316f8f9b33deb02 100644 --- a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/TechnicalException.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/TechnicalException.java @@ -33,6 +33,16 @@ public class TechnicalException extends RuntimeException{ private static final long serialVersionUID = -6715624222174163366L; + private int code; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + public TechnicalException() { super(); } diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestFixtures.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestFixtures.java index 7649583e4fb2be6b8ef6f1833326560de7a095d8..8ec6f536ef0aa4ffb6a44e9003e53360c7621216 100644 --- a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestFixtures.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestFixtures.java @@ -27,11 +27,11 @@ package io.ucoin.ucoinj.core.test; public class TestFixtures { public String getCurrency() { - return "meta_brouzouf"; + return "super_currency"; } public String getUid() { - return "cgeek"; + return "abc"; } public String getUserSalt() { @@ -70,15 +70,15 @@ public class TestFixtures { } /** - * A signature, that corespond to getSelfTimestamp(), getUid() + * A signature, that correspond to self identity * @return */ - public String getSelfSignature() { - return "TMgQysT7JwY8XwemskwWb8LBDJybLUsnxqaaUvSteIYpOxRiB92gkFQQcGpBwq4hAwhEiqBAiFkiXIozppDDDg=="; + public String getSelfIdentitySignature() { + return "sBawDbMdsUYFf1z4i/3sXC4kuVnLLy2aTpcY3BdfpzhX/DFOPxcCyq95D+lTed1Cuv7Ey+0KRSWMUcKnIZQ+BA=="; } - public long getSelfTimestamp() { - return 1420881879; + public String getSelfIdentityBlockUid() { + return "10169-00072A7870BDA66FA3BA8F102933C24EB591A15D789000AD8150F0FE476733D7"; } /** diff --git a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/RestModule.java b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/RestModule.java index 52a958d971812c2b7273be7566509017638ff262..1433bf1be26cb2d5c0ef6adb8281378b512fc02b 100644 --- a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/RestModule.java +++ b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/RestModule.java @@ -23,7 +23,8 @@ package io.ucoin.ucoinj.elasticsearch.action; */ import io.ucoin.ucoinj.elasticsearch.action.currency.RestCurrencyIndexAction; -import io.ucoin.ucoinj.elasticsearch.action.market.RestMarketRecordIndexAction; +import io.ucoin.ucoinj.elasticsearch.action.market.RestMarketDemandIndexAction; +import io.ucoin.ucoinj.elasticsearch.action.market.RestMarketOfferIndexAction; import io.ucoin.ucoinj.elasticsearch.action.registry.RestRegistryRecordIndexAction; import io.ucoin.ucoinj.elasticsearch.action.security.RestSecurityAuthAction; import io.ucoin.ucoinj.elasticsearch.action.security.RestSecurityGetChallengeAction; @@ -35,7 +36,8 @@ public class RestModule extends AbstractModule implements Module { @Override protected void configure() { bind(RestCurrencyIndexAction.class).asEagerSingleton(); - bind(RestMarketRecordIndexAction.class).asEagerSingleton(); + bind(RestMarketOfferIndexAction.class).asEagerSingleton(); + bind(RestMarketDemandIndexAction.class).asEagerSingleton(); bind(RestRegistryRecordIndexAction.class).asEagerSingleton(); diff --git a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketRecordIndexAction.java b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketDemandIndexAction.java similarity index 87% rename from ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketRecordIndexAction.java rename to ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketDemandIndexAction.java index 5fe953ac23be97069a1306578d5a269367b8e50c..e721244e30bb3f988d8f1152ed8f7cd6b220179a 100644 --- a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketRecordIndexAction.java +++ b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketDemandIndexAction.java @@ -35,21 +35,21 @@ import static org.elasticsearch.rest.RestRequest.Method.POST; import static org.elasticsearch.rest.RestStatus.BAD_REQUEST; import static org.elasticsearch.rest.RestStatus.OK; -public class RestMarketRecordIndexAction extends BaseRestHandler { +public class RestMarketDemandIndexAction extends BaseRestHandler { - private static final ESLogger log = ESLoggerFactory.getLogger(RestMarketRecordIndexAction.class.getName()); + private static final ESLogger log = ESLoggerFactory.getLogger(RestMarketDemandIndexAction.class.getName()); @Inject - public RestMarketRecordIndexAction(Settings settings, RestController controller, Client client) { + public RestMarketDemandIndexAction(Settings settings, RestController controller, Client client) { super(settings, controller, client); - controller.registerHandler(POST, "/market/record", this); + controller.registerHandler(POST, "/market/demand", this); } @Override protected void handleRequest(final RestRequest request, RestChannel restChannel, Client client) throws Exception { try { - String recordId = ServiceLocator.instance().getMarketRecordIndexerService().indexRecordFromJson(request.content().toUtf8()); + String recordId = ServiceLocator.instance().getMarketRecordIndexerService().indexDemandFromJson(request.content().toUtf8()); restChannel.sendResponse(new BytesRestResponse(OK, recordId)); } diff --git a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketOfferIndexAction.java b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketOfferIndexAction.java new file mode 100644 index 0000000000000000000000000000000000000000..bbfefcc94d9c8f7345a8d05f0af00f569fe141d7 --- /dev/null +++ b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketOfferIndexAction.java @@ -0,0 +1,65 @@ +package io.ucoin.ucoinj.elasticsearch.action.market; + +/* + * #%L + * ucoinj-elasticsearch-plugin + * %% + * Copyright (C) 2014 - 2016 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.core.exception.BusinessException; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import org.elasticsearch.client.Client; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.logging.ESLogger; +import org.elasticsearch.common.logging.ESLoggerFactory; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.rest.*; + +import static org.elasticsearch.rest.RestRequest.Method.POST; +import static org.elasticsearch.rest.RestStatus.BAD_REQUEST; +import static org.elasticsearch.rest.RestStatus.OK; + +public class RestMarketOfferIndexAction extends BaseRestHandler { + + private static final ESLogger log = ESLoggerFactory.getLogger(RestMarketOfferIndexAction.class.getName()); + + @Inject + public RestMarketOfferIndexAction(Settings settings, RestController controller, Client client) { + super(settings, controller, client); + controller.registerHandler(POST, "/market/offer", this); + } + + @Override + protected void handleRequest(final RestRequest request, RestChannel restChannel, Client client) throws Exception { + + try { + String recordId = ServiceLocator.instance().getMarketRecordIndexerService().indexOfferFromJson(request.content().toUtf8()); + + restChannel.sendResponse(new BytesRestResponse(OK, recordId)); + } + catch(BusinessException e) { + log.error(e.getMessage(), e); + restChannel.sendResponse(new BytesRestResponse(BAD_REQUEST, String.format("{error: {ucode: 'XXX', message:'%s'}}", e.getMessage()))); + } + catch(Exception e) { + log.error(e.getMessage(), e); + } + } + +} \ No newline at end of file diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/logging.yml b/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/logging.yml new file mode 100644 index 0000000000000000000000000000000000000000..4adf913a371cb30f2db3cdd5d73a6c0334fe0392 --- /dev/null +++ b/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/logging.yml @@ -0,0 +1,26 @@ +# default configuration for the audit trail logs +# +# Error Levels: +# +# ERROR authentication_failed, access_denied, tampered_request, connection_denied +# WARN authentication_failed, access_denied, tampered_request, connection_denied, anonymous_access +# INFO authentication_failed, access_denied, tampered_request, connection_denied, anonymous_access, access_granted +# DEBUG doesn't output additional entry types beyond INFO, but extends the information emmitted for each entry +# TRACE authentication_failed, access_denied, tampered_request, connection_denied, anonymous_access, access_granted, connection_granted, authentication_failed [<realm>]. In addition, internal system requests (self-management requests triggered by elasticsearch itself) will also be logged for "access_granted" entry type. +# + +logger: + shield.audit.logfile: INFO, access_log + +additivity: + shield.audit.logfile: false + +appender: + + access_log: + type: dailyRollingFile + file: ${path.logs}/${cluster.name}-access.log + datePattern: "'.'yyyy-MM-dd" + layout: + type: pattern + conversionPattern: "[%d{ISO8601}] %m%n" diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/role_mapping.yml b/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/role_mapping.yml new file mode 100644 index 0000000000000000000000000000000000000000..68c82f7e7c05b02e9aa539262ffa2df332cd078e --- /dev/null +++ b/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/role_mapping.yml @@ -0,0 +1,14 @@ +# Role mapping configuration file which has elasticsearch roles as keys +# that map to one or more user or group distinguished names + +#roleA: this is an elasticsearch role +# - groupA-DN this is a group distinguished name +# - groupB-DN +# - user1-DN this is the full user distinguished name + +#power_user: +# - "cn=admins,dc=example,dc=com" +#user: +# - "cn=users,dc=example,dc=com" +# - "cn=admins,dc=example,dc=com" +# - "cn=John Doe,cn=other users,dc=example,dc=com" diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/roles.yml b/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/roles.yml new file mode 100644 index 0000000000000000000000000000000000000000..633156f7611ee1257c930a1d86a10828cd8e2fb7 --- /dev/null +++ b/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/roles.yml @@ -0,0 +1,71 @@ +# All cluster rights +# All operations on all indices +admin: + cluster: all + indices: + '*': + privileges: all + +# monitoring cluster privileges +# All operations on all indices +power_user: + cluster: monitor + indices: + '*': + privileges: all + +# Read-only operations on indices +user: + indices: + '*': + privileges: read + +# Defines the required permissions for transport clients +transport_client: + cluster: + - cluster:monitor/nodes/liveness + #uncomment the following for sniffing + #- cluster:monitor/state + +# The required permissions for kibana 4 users. +kibana4: + cluster: + - cluster:monitor/nodes/info + - cluster:monitor/health + indices: + '*': + privileges: indices:admin/mappings/fields/get, indices:admin/validate/query, indices:data/read/search, indices:data/read/msearch, indices:data/read/field_stats, indices:admin/get + '.kibana': + privileges: indices:admin/exists, indices:admin/mapping/put, indices:admin/mappings/fields/get, indices:admin/refresh, indices:admin/validate/query, indices:data/read/get, indices:data/read/mget, indices:data/read/search, indices:data/write/delete, indices:data/write/index, indices:data/write/update + +# The required permissions for the kibana 4 server +kibana4_server: + cluster: + - cluster:monitor/nodes/info + - cluster:monitor/health + indices: + '.kibana': + privileges: indices:admin/create, indices:admin/exists, indices:admin/mapping/put, indices:admin/mappings/fields/get, indices:admin/refresh, indices:admin/validate/query, indices:data/read/get, indices:data/read/mget, indices:data/read/search, indices:data/write/delete, indices:data/write/index, indices:data/write/update + +# The required role for logstash users +logstash: + cluster: indices:admin/template/get, indices:admin/template/put + indices: + 'logstash-*': + privileges: indices:data/write/bulk, indices:data/write/delete, indices:data/write/update, indices:data/read/search, indices:data/read/scroll, create_index + +# Marvel user role. Assign to marvel users. +marvel_user: + indices: + '.marvel-es-*': + privileges: read + '.kibana': + privileges: indices:admin/exists, indices:admin/mappings/fields/get, indices:admin/validate/query, indices:data/read/get, indices:data/read/mget, indices:data/read/search + +# Marvel remote agent role. Assign to the agent user on the remote marvel cluster +# to which the marvel agent will export all its data +remote_marvel_agent: + cluster: indices:admin/template/put, indices:admin/template/get + indices: + '.marvel-es-*': + privileges: all \ No newline at end of file diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/users b/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/users new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/users_roles b/ucoinj-elasticsearch-plugin/src/test/es-home/config/shield/users_roles new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch-access.log b/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch-access.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch.log b/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch.log new file mode 100644 index 0000000000000000000000000000000000000000..41bdfb5d498a23795aec04efba624b738024f4cc --- /dev/null +++ b/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch.log @@ -0,0 +1,68 @@ +[2016-02-02 19:00:21,260][INFO ][node ] [Lucas Brand] version[2.2.0], pid[4389], build[8ff36d1/2016-01-27T13:32:39Z] +[2016-02-02 19:00:21,261][INFO ][node ] [Lucas Brand] initializing ... +[2016-02-02 19:00:21,353][INFO ][plugins ] [Lucas Brand] modules [], plugins [], sites [] +[2016-02-02 19:00:21,389][INFO ][env ] [Lucas Brand] using [1] data paths, mounts [[/home (/dev/sdb5)]], net usable_space [202.6gb], net total_space [436.4gb], spins? [possibly], types [ext4] +[2016-02-02 19:00:21,389][INFO ][env ] [Lucas Brand] heap size [3.4gb], compressed ordinary object pointers [true] +[2016-02-02 19:00:23,318][INFO ][node ] [Lucas Brand] initialized +[2016-02-02 19:00:23,318][INFO ][node ] [Lucas Brand] starting ... +[2016-02-02 19:00:23,381][INFO ][transport ] [Lucas Brand] publish_address {127.0.0.1:9300}, bound_addresses {127.0.0.1:9300}, {[::1]:9300} +[2016-02-02 19:00:23,390][INFO ][discovery ] [Lucas Brand] elasticsearch/0vD7T8u-Rmajbu8MH0yb_w +[2016-02-02 19:00:26,433][INFO ][cluster.service ] [Lucas Brand] new_master {Lucas Brand}{0vD7T8u-Rmajbu8MH0yb_w}{127.0.0.1}{127.0.0.1:9300}, reason: zen-disco-join(elected_as_master, [0] joins received) +[2016-02-02 19:00:26,443][INFO ][http ] [Lucas Brand] publish_address {127.0.0.1:9292}, bound_addresses {127.0.0.1:9292}, {[::1]:9292} +[2016-02-02 19:00:26,443][INFO ][node ] [Lucas Brand] started +[2016-02-02 19:00:26,535][INFO ][gateway ] [Lucas Brand] recovered [0] indices into cluster_state +[2016-02-02 19:01:28,760][INFO ][node ] [Lucas Brand] stopping ... +[2016-02-02 19:01:28,770][INFO ][node ] [Lucas Brand] stopped +[2016-02-02 19:01:28,770][INFO ][node ] [Lucas Brand] closing ... +[2016-02-02 19:01:28,773][INFO ][node ] [Lucas Brand] closed +[2016-02-02 19:01:32,954][INFO ][node ] [Hephaestus] version[2.2.0], pid[4590], build[8ff36d1/2016-01-27T13:32:39Z] +[2016-02-02 19:01:32,955][INFO ][node ] [Hephaestus] initializing ... +[2016-02-02 19:01:33,045][INFO ][plugins ] [Hephaestus] modules [], plugins [], sites [] +[2016-02-02 19:01:33,075][INFO ][env ] [Hephaestus] using [1] data paths, mounts [[/home (/dev/sdb5)]], net usable_space [202.6gb], net total_space [436.4gb], spins? [possibly], types [ext4] +[2016-02-02 19:01:33,075][INFO ][env ] [Hephaestus] heap size [3.4gb], compressed ordinary object pointers [true] +[2016-02-02 19:01:34,914][INFO ][node ] [Hephaestus] initialized +[2016-02-02 19:01:34,914][INFO ][node ] [Hephaestus] starting ... +[2016-02-02 19:01:34,973][INFO ][transport ] [Hephaestus] publish_address {127.0.0.1:9300}, bound_addresses {127.0.0.1:9300}, {[::1]:9300} +[2016-02-02 19:01:34,981][INFO ][discovery ] [Hephaestus] elasticsearch/KPUfVSTIRRicjnPSp6TjLQ +[2016-02-02 19:01:38,024][INFO ][cluster.service ] [Hephaestus] new_master {Hephaestus}{KPUfVSTIRRicjnPSp6TjLQ}{127.0.0.1}{127.0.0.1:9300}, reason: zen-disco-join(elected_as_master, [0] joins received) +[2016-02-02 19:01:38,037][INFO ][http ] [Hephaestus] publish_address {127.0.0.1:9292}, bound_addresses {127.0.0.1:9292}, {[::1]:9292} +[2016-02-02 19:01:38,038][INFO ][node ] [Hephaestus] started +[2016-02-02 19:01:38,105][INFO ][gateway ] [Hephaestus] recovered [0] indices into cluster_state +[2016-02-02 19:02:06,623][INFO ][node ] [Hephaestus] stopping ... +[2016-02-02 19:02:06,633][INFO ][node ] [Hephaestus] stopped +[2016-02-02 19:02:06,633][INFO ][node ] [Hephaestus] closing ... +[2016-02-02 19:02:06,637][INFO ][node ] [Hephaestus] closed +[2016-02-02 19:02:24,839][INFO ][node ] [Sergeant Fury] version[2.2.0], pid[4758], build[8ff36d1/2016-01-27T13:32:39Z] +[2016-02-02 19:02:24,840][INFO ][node ] [Sergeant Fury] initializing ... +[2016-02-02 19:02:24,922][INFO ][plugins ] [Sergeant Fury] modules [], plugins [], sites [] +[2016-02-02 19:02:24,946][INFO ][env ] [Sergeant Fury] using [1] data paths, mounts [[/home (/dev/sdb5)]], net usable_space [202.6gb], net total_space [436.4gb], spins? [possibly], types [ext4] +[2016-02-02 19:02:24,946][INFO ][env ] [Sergeant Fury] heap size [3.4gb], compressed ordinary object pointers [true] +[2016-02-02 19:02:26,789][INFO ][node ] [Sergeant Fury] initialized +[2016-02-02 19:02:26,789][INFO ][node ] [Sergeant Fury] starting ... +[2016-02-02 19:02:26,851][INFO ][transport ] [Sergeant Fury] publish_address {127.0.0.1:9300}, bound_addresses {127.0.0.1:9300}, {[::1]:9300} +[2016-02-02 19:02:26,860][INFO ][discovery ] [Sergeant Fury] elasticsearch/dG65jlrZSDCOeJg0Q074Cw +[2016-02-02 19:02:29,905][INFO ][cluster.service ] [Sergeant Fury] new_master {Sergeant Fury}{dG65jlrZSDCOeJg0Q074Cw}{127.0.0.1}{127.0.0.1:9300}, reason: zen-disco-join(elected_as_master, [0] joins received) +[2016-02-02 19:02:29,914][INFO ][http ] [Sergeant Fury] publish_address {127.0.0.1:9292}, bound_addresses {127.0.0.1:9292}, {[::1]:9292} +[2016-02-02 19:02:29,915][INFO ][node ] [Sergeant Fury] started +[2016-02-02 19:02:29,985][INFO ][gateway ] [Sergeant Fury] recovered [0] indices into cluster_state +[2016-02-02 19:02:43,546][INFO ][node ] [Sergeant Fury] stopping ... +[2016-02-02 19:02:43,555][INFO ][node ] [Sergeant Fury] stopped +[2016-02-02 19:02:43,555][INFO ][node ] [Sergeant Fury] closing ... +[2016-02-02 19:02:43,559][INFO ][node ] [Sergeant Fury] closed +[2016-02-02 19:02:49,922][INFO ][node ] [Lady Mandarin] version[2.2.0], pid[4918], build[8ff36d1/2016-01-27T13:32:39Z] +[2016-02-02 19:02:49,923][INFO ][node ] [Lady Mandarin] initializing ... +[2016-02-02 19:02:50,007][INFO ][plugins ] [Lady Mandarin] modules [], plugins [], sites [] +[2016-02-02 19:02:50,045][INFO ][env ] [Lady Mandarin] using [1] data paths, mounts [[/home (/dev/sdb5)]], net usable_space [202.6gb], net total_space [436.4gb], spins? [possibly], types [ext4] +[2016-02-02 19:02:50,045][INFO ][env ] [Lady Mandarin] heap size [3.4gb], compressed ordinary object pointers [true] +[2016-02-02 19:02:51,888][INFO ][node ] [Lady Mandarin] initialized +[2016-02-02 19:02:51,888][INFO ][node ] [Lady Mandarin] starting ... +[2016-02-02 19:02:51,950][INFO ][transport ] [Lady Mandarin] publish_address {127.0.0.1:9300}, bound_addresses {127.0.0.1:9300}, {[::1]:9300} +[2016-02-02 19:02:51,960][INFO ][discovery ] [Lady Mandarin] elasticsearch/hCDo3Pj5SnKGJzrKTawrSw +[2016-02-02 19:02:55,005][INFO ][cluster.service ] [Lady Mandarin] new_master {Lady Mandarin}{hCDo3Pj5SnKGJzrKTawrSw}{127.0.0.1}{127.0.0.1:9300}, reason: zen-disco-join(elected_as_master, [0] joins received) +[2016-02-02 19:02:55,015][INFO ][http ] [Lady Mandarin] publish_address {127.0.0.1:9292}, bound_addresses {127.0.0.1:9292}, {[::1]:9292} +[2016-02-02 19:02:55,015][INFO ][node ] [Lady Mandarin] started +[2016-02-02 19:02:55,084][INFO ][gateway ] [Lady Mandarin] recovered [0] indices into cluster_state +[2016-02-02 19:25:37,053][INFO ][node ] [Lady Mandarin] stopping ... +[2016-02-02 19:25:37,064][INFO ][node ] [Lady Mandarin] stopped +[2016-02-02 19:25:37,065][INFO ][node ] [Lady Mandarin] closing ... +[2016-02-02 19:25:37,068][INFO ][node ] [Lady Mandarin] closed diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch_deprecation.log b/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch_deprecation.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch_index_indexing_slowlog.log b/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch_index_indexing_slowlog.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch_index_search_slowlog.log b/ucoinj-elasticsearch-plugin/src/test/es-home/logs/elasticsearch_index_search_slowlog.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketRecordIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketRecordIndexerService.java index 6f4020b2590e5f866def77724b9ca76ea5cd00b3..d81187d8b6bbd707c798c9e1c8f5bbc0a5d68677 100644 --- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketRecordIndexerService.java +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketRecordIndexerService.java @@ -61,18 +61,16 @@ public class MarketRecordIndexerService extends BaseIndexerService { private static final String JSON_STRING_PROPERTY_REGEX = "[,]?[\"\\s\\n\\r]*%s[\"]?[\\s\\n\\r]*:[\\s\\n\\r]*\"[^\"]+\""; public static final String INDEX_NAME = "market"; - public static final String INDEX_TYPE = "record"; - private Gson gson; - - private Configuration config; + public static final String INDEX_TYPE_OFFER = "offer"; + public static final String INDEX_TYPE_DEMAND = "demand"; private WotRemoteService wotRemoteService; private CryptoService cryptoService; public MarketRecordIndexerService() { - gson = GsonUtils.newBuilder().create(); + } @Override @@ -80,15 +78,12 @@ public class MarketRecordIndexerService extends BaseIndexerService { super.afterPropertiesSet(); wotRemoteService = ServiceLocator.instance().getWotRemoteService(); cryptoService = ServiceLocator.instance().getCryptoService(); - config = Configuration.instance(); } @Override public void close() throws IOException { super.close(); wotRemoteService = null; - config = null; - gson = null; } /** @@ -123,71 +118,51 @@ public class MarketRecordIndexerService extends BaseIndexerService { * @throws JsonProcessingException */ public void createIndex() throws JsonProcessingException { - log.info(String.format("Creating index [%s/%s]", INDEX_NAME, INDEX_TYPE)); - CreateIndexRequestBuilder createIndexRequestBuilder = getClient().admin().indices().prepareCreate(INDEX_NAME); Settings indexSettings = Settings.settingsBuilder() - .put("number_of_shards", 1) - .put("number_of_replicas", 1) + .put("number_of_shards", 3) + .put("number_of_replicas", 2) .put("analyzer", createDefaultAnalyzer()) .build(); + + // Create offer index + log.info(String.format("Creating index [%s/%s]", INDEX_NAME, INDEX_TYPE_OFFER)); createIndexRequestBuilder.setSettings(indexSettings); - createIndexRequestBuilder.addMapping(INDEX_TYPE, createIndexMapping()); + createIndexRequestBuilder.addMapping(INDEX_TYPE_OFFER, createIndexMapping(INDEX_TYPE_OFFER)); + createIndexRequestBuilder.execute().actionGet(); + + // Create demand index + log.info(String.format("Creating index [%s/%s]", INDEX_NAME, INDEX_TYPE_DEMAND)); + createIndexRequestBuilder.setSettings(indexSettings); + createIndexRequestBuilder.addMapping(INDEX_TYPE_DEMAND, createIndexMapping(INDEX_TYPE_DEMAND)); createIndexRequestBuilder.execute().actionGet(); } /** - * + * Index a new offer * @param recordJson * @return the record id */ - public String indexRecordFromJson(String recordJson) { - - try { - ObjectMapper mapper = new ObjectMapper(); - JsonNode actualObj = mapper.readTree(recordJson); - Set<String> fieldNames = Sets.newHashSet(actualObj.fieldNames()); - if (!fieldNames.contains(Record.PROPERTY_ISSUER) - || !fieldNames.contains(Record.PROPERTY_SIGNATURE)) { - throw new InvalidFormatException("Invalid record JSON format. Required fields [issuer,signature]"); - } - String issuer = actualObj.get(Record.PROPERTY_ISSUER).asText(); - String signature = actualObj.get(Record.PROPERTY_SIGNATURE).asText(); - - String recordNoSign = recordJson.replaceAll(String.format(JSON_STRING_PROPERTY_REGEX, Record.PROPERTY_SIGNATURE), "") - .replaceAll(String.format(JSON_STRING_PROPERTY_REGEX, Record.PROPERTY_HASH), ""); - - if (!cryptoService.verify(recordNoSign, signature, issuer)) { - throw new InvalidSignatureException("Invalid signature for JSON string: " + recordNoSign); - } - - if (log.isDebugEnabled()) { - log.debug(String.format("Indexing a record from issuer [%s]", issuer.substring(0, 8))); - } - - } - catch(IOException | JsonSyntaxException e) { - throw new InvalidFormatException("Invalid record JSON: " + e.getMessage(), e); - } - - // Preparing indexBlocksFromNode - IndexRequestBuilder indexRequest = getClient().prepareIndex(INDEX_NAME, INDEX_TYPE) - .setSource(recordJson); + public String indexOfferFromJson(String recordJson) { - // Execute indexBlocksFromNode - IndexResponse response = indexRequest - .setRefresh(false) - .execute().actionGet(); + return indexRecordFromJson(recordJson, INDEX_TYPE_OFFER); + } - return response.getId(); + /** + * Index a new demand + * @param recordJson + * @return the record id + */ + public String indexDemandFromJson(String recordJson) { + return indexRecordFromJson(recordJson, INDEX_TYPE_DEMAND); } /* -- Internal methods -- */ - public XContentBuilder createIndexMapping() { + public XContentBuilder createIndexMapping(String indexType) { try { - XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_TYPE) + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(indexType) .startObject("properties") // title @@ -242,8 +217,53 @@ public class MarketRecordIndexerService extends BaseIndexerService { return mapping; } catch(IOException ioe) { - throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX_NAME, INDEX_TYPE, ioe.getMessage()), ioe); + throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX_NAME, indexType, ioe.getMessage()), ioe); + } + } + + public String indexRecordFromJson(String recordJson, String indexType) { + + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode actualObj = mapper.readTree(recordJson); + Set<String> fieldNames = Sets.newHashSet(actualObj.fieldNames()); + if (!fieldNames.contains(Record.PROPERTY_ISSUER) + || !fieldNames.contains(Record.PROPERTY_SIGNATURE)) { + throw new InvalidFormatException("Invalid record JSON format. Required fields [issuer,signature]"); + } + String issuer = actualObj.get(Record.PROPERTY_ISSUER).asText(); + + String signature = actualObj.get(Record.PROPERTY_SIGNATURE).asText(); + + String recordNoSign = recordJson.replaceAll(String.format(JSON_STRING_PROPERTY_REGEX, Record.PROPERTY_SIGNATURE), "") + .replaceAll(String.format(JSON_STRING_PROPERTY_REGEX, Record.PROPERTY_HASH), ""); + + if (!cryptoService.verify(recordNoSign, signature, issuer)) { + throw new InvalidSignatureException("Invalid signature for JSON string: " + recordNoSign); + } + + // TODO : check if issuer is a valid member + //wotRemoteService.getRequirments(); + + if (log.isDebugEnabled()) { + log.debug(String.format("Indexing a record from issuer [%s]", issuer.substring(0, 8))); + } + + } + catch(IOException | JsonSyntaxException e) { + throw new InvalidFormatException("Invalid record JSON: " + e.getMessage(), e); } + + // Preparing indexBlocksFromNode + IndexRequestBuilder indexRequest = getClient().prepareIndex(INDEX_NAME, indexType) + .setSource(recordJson); + + // Execute indexBlocksFromNode + IndexResponse response = indexRequest + .setRefresh(false) + .execute().actionGet(); + + return response.getId(); } } diff --git a/ucoinj-elasticsearch/src/test/resources/log4j.properties b/ucoinj-elasticsearch/src/test/resources/log4j.properties index ab3b55380dd939a15cb92f6173dd8f1ff84b5835..983dbe9f1a1d91d9794428b5209e0ead5e002478 100644 --- a/ucoinj-elasticsearch/src/test/resources/log4j.properties +++ b/ucoinj-elasticsearch/src/test/resources/log4j.properties @@ -9,6 +9,7 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - [%t] %m # uCoinj levels log4j.logger.io.ucoin=INFO +log4j.logger.io.ucoin.ucoinj.elasticsearch=DEBUG #log4j.logger.io.ucoin.ucoinj=DEBUG #log4j.logger.io.ucoin.ucoinj.core=WARN #log4j.logger.io.ucoin.ucoinj.elasticsearch=DEBUG