diff --git a/checkstyle-config.xml b/checkstyle-config.xml
index 75a9e22a..0bddcf20 100644
--- a/checkstyle-config.xml
+++ b/checkstyle-config.xml
@@ -105,7 +105,11 @@
-
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 4a4eef32..b61b79d1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
1.8.0
- 1.58
+ 1.59
4.5.4
true
8.1.7.v20160121
@@ -102,7 +102,7 @@
com.google.protobuf
protobuf-java
- 3.5.0
+ 3.5.1
diff --git a/src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java b/src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java
index 3c8b48ac..82d55d62 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java
@@ -19,7 +19,7 @@
import com.google.protobuf.InvalidProtocolBufferException;
import org.hyperledger.fabric.protos.common.Common.Block;
-import org.hyperledger.fabric.protos.orderer.Ab;
+import org.hyperledger.fabric.protos.peer.PeerEvents;
import org.hyperledger.fabric.protos.peer.PeerEvents.Event;
import org.hyperledger.fabric.sdk.exception.InvalidProtocolBufferRuntimeException;
@@ -29,7 +29,6 @@
* @see Block
*/
public class BlockEvent extends BlockInfo {
-
// private static final Log logger = LogFactory.getLog(BlockEvent.class);
private final EventHub eventHub;
@@ -50,9 +49,8 @@ public class BlockEvent extends BlockInfo {
this.event = event;
}
- BlockEvent(Peer peer, Ab.DeliverResponse resp) {
- super(resp.getBlock());
-
+ BlockEvent(Peer peer, PeerEvents.DeliverResponse resp) {
+ super(resp);
eventHub = null;
this.peer = peer;
this.event = null;
@@ -89,35 +87,26 @@ public Peer getPeer() {
// }
boolean isBlockEvent() {
+ if (peer != null) {
+ return true; //peer always returns Block type events;
+ }
- return event == null || event.getEventCase() == Event.EventCase.BLOCK;
+ return event != null && event.getEventCase() == PeerEvents.Event.EventCase.BLOCK;
}
TransactionEvent getTransactionEvent(int index) throws InvalidProtocolBufferException {
- return new TransactionEvent((TransactionEnvelopeInfo) getEnvelopeInfo(index), index);
+ return isFiltered() ? new TransactionEvent(getEnvelopeInfo(index).filteredTx) :
+ new TransactionEvent((TransactionEnvelopeInfo) getEnvelopeInfo(index));
}
- List getTransactionEventsList() {
-
- ArrayList ret = new ArrayList(getEnvelopeCount());
- for (TransactionEvent transactionEvent : getTransactionEvents()) {
- ret.add(transactionEvent);
+ public class TransactionEvent extends TransactionEnvelopeInfo {
+ TransactionEvent(TransactionEnvelopeInfo transactionEnvelopeInfo) {
+ super(transactionEnvelopeInfo.getTransactionDeserializer());
}
- return ret;
-
- }
-
- public Iterable getTransactionEvents() {
-
- return new TransactionEventIterable();
-
- }
-
- public class TransactionEvent extends TransactionEnvelopeInfo {
- TransactionEvent(TransactionEnvelopeInfo transactionEnvelopeInfo, int index) {
- super(transactionEnvelopeInfo.getTransactionDeserializer(), index);
+ TransactionEvent(PeerEvents.FilteredTransaction filteredTransaction) {
+ super(filteredTransaction);
}
/**
@@ -144,6 +133,23 @@ public Peer getPeer() {
}
}
+ List getTransactionEventsList() {
+
+ ArrayList ret = new ArrayList(getEnvelopeCount());
+ for (TransactionEvent transactionEvent : getTransactionEvents()) {
+ ret.add(transactionEvent);
+ }
+
+ return ret;
+
+ }
+
+ public Iterable getTransactionEvents() {
+
+ return new TransactionEventIterable();
+
+ }
+
class TransactionEventIterator implements Iterator {
final int max;
int ci = 0;
diff --git a/src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java b/src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java
index 026010e6..bc8c40f6 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java
@@ -20,64 +20,123 @@
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
+import org.hyperledger.fabric.protos.common.Common;
import org.hyperledger.fabric.protos.common.Common.Block;
import org.hyperledger.fabric.protos.ledger.rwset.Rwset.TxReadWriteSet;
import org.hyperledger.fabric.protos.peer.Chaincode.ChaincodeInput;
+import org.hyperledger.fabric.protos.peer.FabricTransaction;
+import org.hyperledger.fabric.protos.peer.PeerEvents;
+import org.hyperledger.fabric.protos.peer.PeerEvents.FilteredTransaction;
import org.hyperledger.fabric.sdk.exception.InvalidProtocolBufferRuntimeException;
import org.hyperledger.fabric.sdk.transaction.ProtoUtils;
+import static java.lang.String.format;
import static org.hyperledger.fabric.protos.peer.FabricProposalResponse.Endorsement;
/**
* BlockInfo contains the data from a {@link Block}
*/
public class BlockInfo {
- private final BlockDeserializer block;
+ private final BlockDeserializer block; //can be only one or the other.
+ private final PeerEvents.FilteredBlock filteredBlock;
BlockInfo(Block block) {
+
+ filteredBlock = null;
this.block = new BlockDeserializer(block);
}
+// BlockInfo(PeerEvents.Event event) {
+// if (event.getEventCase() == PeerEvents.Event.EventCase.FILTERED_BLOCK) {
+// block = null;
+// filteredBlock = event.getFilteredBlock();
+// } else {
+// this.block = new BlockDeserializer(event.getBlock());
+// filteredBlock = null;
+// }
+// }
+
+ BlockInfo(PeerEvents.DeliverResponse resp) {
+
+ final PeerEvents.DeliverResponse.TypeCase type = resp.getTypeCase();
+
+ if (type == PeerEvents.DeliverResponse.TypeCase.BLOCK) {
+ final Block respBlock = resp.getBlock();
+ filteredBlock = null;
+ if (respBlock == null) {
+ throw new AssertionError("DeliverResponse type block but block is null");
+ }
+ this.block = new BlockDeserializer(respBlock);
+ } else if (type == PeerEvents.DeliverResponse.TypeCase.FILTERED_BLOCK) {
+ filteredBlock = resp.getFilteredBlock();
+ block = null;
+ if (filteredBlock == null) {
+ throw new AssertionError("DeliverResponse type filter block but filter block is null");
+ }
+
+ } else {
+ throw new AssertionError(format("DeliverResponse type has unexpected type: %s, %d", type.name(), type.getNumber()));
+ }
+
+ }
+
+ public boolean isFiltered() {
+ if (filteredBlock == null && block == null) {
+ throw new AssertionError("Both block and filter is null.");
+ }
+ if (filteredBlock != null && block != null) {
+ throw new AssertionError("Both block and filter are set.");
+ }
+ return filteredBlock != null;
+ }
+
public String getChannelId() throws InvalidProtocolBufferException {
- return getEnvelopeInfo(0).getChannelId();
+ return isFiltered() ? filteredBlock.getChannelId() : getEnvelopeInfo(0).getChannelId();
}
/**
* @return the raw {@link Block}
*/
public Block getBlock() {
- return block.getBlock();
+ return isFiltered() ? null : block.getBlock();
+ }
+
+ /**
+ * @return the raw {@link org.hyperledger.fabric.protos.peer.PeerEvents.FilteredBlock}
+ */
+ public PeerEvents.FilteredBlock getFilteredBlock() {
+ return !isFiltered() ? null : filteredBlock;
}
/**
- * @return the {@link Block} previousHash value
+ * @return the {@link Block} previousHash value and null if filtered block.
*/
public byte[] getPreviousHash() {
- return block.getPreviousHash().toByteArray();
+ return isFiltered() ? null : block.getPreviousHash().toByteArray();
}
/**
- * @return the {@link Block} data hash value
+ * @return the {@link Block} data hash value and null if filtered block.
*/
public byte[] getDataHash() {
- return block.getDataHash().toByteArray();
+ return isFiltered() ? null : block.getDataHash().toByteArray();
}
/**
- * @return the {@link Block} transaction metadata value
+ * @return the {@link Block} transaction metadata value return null if filtered block.
*/
public byte[] getTransActionsMetaData() {
- return block.getTransActionsMetaData();
+ return isFiltered() ? null : block.getTransActionsMetaData();
}
/**
* @return the {@link Block} index number
*/
public long getBlockNumber() {
- return block.getNumber();
+ return isFiltered() ? filteredBlock.getNumber() : block.getNumber();
}
/**
@@ -87,59 +146,101 @@ public long getBlockNumber() {
*/
public int getEnvelopeCount() {
- return block.getData().getDataCount();
+ return isFiltered() ? filteredBlock.getFilteredTxCount() : block.getData().getDataCount();
}
public class EnvelopeInfo {
private final EnvelopeDeserializer envelopeDeserializer;
- HeaderDeserializer headerDeserializer;
+ private final HeaderDeserializer headerDeserializer;
+ protected final FilteredTransaction filteredTx;
+
+ boolean isFiltered() {
+ return filteredTx != null;
+
+ }
//private final EnvelopeDeserializer envelopeDeserializer;
- EnvelopeInfo(EnvelopeDeserializer envelopeDeserializer, int blockIndex) {
+ EnvelopeInfo(EnvelopeDeserializer envelopeDeserializer) {
this.envelopeDeserializer = envelopeDeserializer;
headerDeserializer = envelopeDeserializer.getPayload().getHeader();
- headerDeserializer.getChannelHeader().getType();
+ filteredTx = null;
+ }
+
+ public EnvelopeInfo(FilteredTransaction filteredTx) {
+ this.filteredTx = filteredTx;
+ envelopeDeserializer = null;
+ headerDeserializer = null;
+
}
public String getChannelId() {
- return headerDeserializer.getChannelHeader().getChannelId();
+ return BlockInfo.this.isFiltered() ? filteredBlock.getChannelId() : headerDeserializer.getChannelHeader().getChannelId();
}
public String getTransactionID() {
- return headerDeserializer.getChannelHeader().getTxId();
+ return BlockInfo.this.isFiltered() ? filteredTx.getTxid() : headerDeserializer.getChannelHeader().getTxId();
}
+ /**
+ * @return epoch and -1 if filtered block.
+ * @deprecated
+ */
+
public long getEpoch() {
- return headerDeserializer.getChannelHeader().getEpoch();
+ return BlockInfo.this.isFiltered() ? -1 : headerDeserializer.getChannelHeader().getEpoch();
}
+ /**
+ * Timestamp
+ *
+ * @return timestamp and null if filtered block.
+ */
+
public Date getTimestamp() {
- return ProtoUtils.getDateFromTimestamp(headerDeserializer.getChannelHeader().getTimestamp());
+ return BlockInfo.this.isFiltered() ? null :
+ ProtoUtils.getDateFromTimestamp(headerDeserializer.getChannelHeader().getTimestamp());
}
/**
* @return whether this Transaction is marked as TxValidationCode.VALID
*/
public boolean isValid() {
- return envelopeDeserializer.isValid();
+ return BlockInfo.this.isFiltered() ? filteredTx.getTxValidationCode().getNumber() == FabricTransaction.TxValidationCode.VALID_VALUE
+ : envelopeDeserializer.isValid();
}
/**
* @return the validation code of this Transaction (enumeration TxValidationCode in Transaction.proto)
*/
public byte getValidationCode() {
+ if (BlockInfo.this.isFiltered()) {
+
+ return (byte) filteredTx.getTxValidationCode().getNumber();
+
+ }
return envelopeDeserializer.validationCode();
}
public EnvelopeType getType() {
- switch (headerDeserializer.getChannelHeader().getType()) {
- case 3:
+ final int type;
+
+ if (BlockInfo.this.isFiltered()) {
+
+ type = filteredTx.getTypeValue();
+
+ } else {
+ type = headerDeserializer.getChannelHeader().getType();
+
+ }
+
+ switch (type) {
+ case Common.HeaderType.ENDORSER_TRANSACTION_VALUE:
return EnvelopeType.TRANSACTION_ENVELOPE;
default:
@@ -164,15 +265,30 @@ public EnvelopeInfo getEnvelopeInfo(int envelopeIndex) throws InvalidProtocolBuf
EnvelopeInfo ret;
- EnvelopeDeserializer ed = EnvelopeDeserializer.newInstance(block.getBlock().getData().getData(envelopeIndex), block.getTransActionsMetaData()[envelopeIndex]);
+ if (isFiltered()) {
+
+ switch (filteredBlock.getFilteredTx(envelopeIndex).getType().getNumber()) {
+ case Common.HeaderType.ENDORSER_TRANSACTION_VALUE:
+ ret = new TransactionEnvelopeInfo(this.filteredBlock.getFilteredTx(envelopeIndex));
+ break;
+ default: //just assume base properties.
+ ret = new EnvelopeInfo(this.filteredBlock.getFilteredTx(envelopeIndex));
+ break;
+ }
+
+ } else {
- switch (ed.getType()) {
- case 3:
- ret = new TransactionEnvelopeInfo((EndorserTransactionEnvDeserializer) ed, envelopeIndex);
- break;
- default: //just assume base properties.
- ret = new EnvelopeInfo(ed, envelopeIndex);
- break;
+ EnvelopeDeserializer ed = EnvelopeDeserializer.newInstance(block.getBlock().getData().getData(envelopeIndex), block.getTransActionsMetaData()[envelopeIndex]);
+
+ switch (ed.getType()) {
+ case Common.HeaderType.ENDORSER_TRANSACTION_VALUE:
+ ret = new TransactionEnvelopeInfo((EndorserTransactionEnvDeserializer) ed);
+ break;
+ default: //just assume base properties.
+ ret = new EnvelopeInfo(ed);
+ break;
+
+ }
}
return ret;
@@ -196,22 +312,25 @@ public Iterable getEnvelopeInfos() {
public class TransactionEnvelopeInfo extends EnvelopeInfo {
- EndorserTransactionEnvDeserializer getTransactionDeserializer() {
- return transactionDeserializer;
+ TransactionEnvelopeInfo(FilteredTransaction filteredTx) {
+ super(filteredTx);
+ this.transactionDeserializer = null;
}
- protected final EndorserTransactionEnvDeserializer transactionDeserializer;
-
- public TransactionEnvelopeInfo(EndorserTransactionEnvDeserializer transactionDeserializer, int blockIndex) {
- super(transactionDeserializer, blockIndex);
+ TransactionEnvelopeInfo(EndorserTransactionEnvDeserializer transactionDeserializer) {
+ super(transactionDeserializer);
this.transactionDeserializer = transactionDeserializer;
- this.headerDeserializer = transactionDeserializer.getPayload().getHeader();
+ }
+ EndorserTransactionEnvDeserializer getTransactionDeserializer() {
+ return transactionDeserializer;
}
+ protected final EndorserTransactionEnvDeserializer transactionDeserializer;
+
public int getTransactionActionInfoCount() {
- return transactionDeserializer.getPayload().getTransaction().getActionsCount();
+ return BlockInfo.this.isFiltered() ? filteredTx.getTransactionActions().getChaincodeActionsCount() : transactionDeserializer.getPayload().getTransaction().getActionsCount();
}
public Iterable getTransactionActionInfos() {
@@ -222,28 +341,45 @@ public Iterable getTransactionActionInfos() {
public class TransactionActionInfo {
private final TransactionActionDeserializer transactionAction;
+ private final PeerEvents.FilteredChaincodeAction filteredAction;
List endorserInfos = null;
+ private boolean isFiltered() {
+ return filteredAction != null;
+
+ }
+
TransactionActionInfo(TransactionActionDeserializer transactionAction) {
this.transactionAction = transactionAction;
+ filteredAction = null;
+ }
+
+ TransactionActionInfo(PeerEvents.FilteredChaincodeAction filteredAction) {
+ this.filteredAction = filteredAction;
+ transactionAction = null;
+
}
public byte[] getResponseMessageBytes() {
- return transactionAction.getPayload().getAction().getProposalResponsePayload().getExtension().getResponseMessageBytes();
+ return isFiltered() ? null : transactionAction.getPayload().getAction().getProposalResponsePayload().getExtension().getResponseMessageBytes();
}
public String getResponseMessage() {
- return transactionAction.getPayload().getAction().getProposalResponsePayload().getExtension().getResponseMessage();
+ return isFiltered() ? null :
+ transactionAction.getPayload().getAction().getProposalResponsePayload().getExtension().getResponseMessage();
}
public int getResponseStatus() {
- return transactionAction.getPayload().getAction().getProposalResponsePayload().getExtension().getResponseStatus();
+ return isFiltered() ? -1 : transactionAction.getPayload().getAction().getProposalResponsePayload().getExtension().getResponseStatus();
}
int getChaincodeInputArgsCount = -1;
public int getChaincodeInputArgsCount() {
+ if (isFiltered()) {
+ return 0;
+ }
if (getChaincodeInputArgsCount < 0) {
getChaincodeInputArgsCount = transactionAction.getPayload().getChaincodeProposalPayload().
getChaincodeInvocationSpec().getChaincodeInput().getChaincodeInput().getArgsCount();
@@ -252,6 +388,9 @@ public int getChaincodeInputArgsCount() {
}
public byte[] getChaincodeInputArgs(int index) {
+ if (isFiltered()) {
+ return null;
+ }
ChaincodeInput input = transactionAction.getPayload().getChaincodeProposalPayload().
getChaincodeInvocationSpec().getChaincodeInput().getChaincodeInput();
@@ -262,6 +401,9 @@ public byte[] getChaincodeInputArgs(int index) {
int getEndorsementsCount = -1;
public int getEndorsementsCount() {
+ if (isFiltered()) {
+ return 0;
+ }
if (getEndorsementsCount < 0) {
getEndorsementsCount = transactionAction.getPayload().getAction().getEndorsementsCount();
}
@@ -269,6 +411,9 @@ public int getEndorsementsCount() {
}
public EndorserInfo getEndorsementInfo(int index) {
+ if (isFiltered()) {
+ return null;
+ }
if (null == endorserInfos) {
endorserInfos = new ArrayList<>();
@@ -284,12 +429,18 @@ public EndorserInfo getEndorsementInfo(int index) {
}
public byte[] getProposalResponseMessageBytes() {
+ if (isFiltered()) {
+ return null;
+ }
return transactionAction.getPayload().getAction().getProposalResponsePayload().getExtension().getResponseMessageBytes();
}
public byte[] getProposalResponsePayload() {
+ if (isFiltered()) {
+ return null;
+ }
byte[] ret = null;
ByteString retByteString = transactionAction.getPayload().getAction().getProposalResponsePayload().
@@ -303,6 +454,9 @@ public byte[] getProposalResponsePayload() {
}
public int getProposalResponseStatus() {
+ if (isFiltered()) {
+ return -1;
+ }
return transactionAction.getPayload().getAction().getProposalResponsePayload().
getExtension().getResponseStatus();
@@ -318,13 +472,19 @@ public int getProposalResponseStatus() {
public TxReadWriteSetInfo getTxReadWriteSet() {
- TxReadWriteSet txReadWriteSet = transactionAction.getPayload().getAction().getProposalResponsePayload()
- .getExtension().getResults();
- if (txReadWriteSet == null) {
+ if (BlockInfo.this.isFiltered()) {
return null;
- }
- return new TxReadWriteSetInfo(txReadWriteSet);
+ } else {
+
+ TxReadWriteSet txReadWriteSet = transactionAction.getPayload().getAction().getProposalResponsePayload()
+ .getExtension().getResults();
+ if (txReadWriteSet == null) {
+ return null;
+ }
+
+ return new TxReadWriteSetInfo(txReadWriteSet);
+ }
}
@@ -335,6 +495,10 @@ public TxReadWriteSetInfo getTxReadWriteSet() {
*/
public ChaincodeEvent getEvent() {
+ if (isFiltered()) {
+ final PeerEvents.FilteredChaincodeAction chaincodeActions = filteredAction;
+ return new ChaincodeEvent(chaincodeActions.getCcEvent().toByteString());
+ }
return transactionAction.getPayload().getAction().getProposalResponsePayload()
.getExtension().getEvent();
@@ -344,7 +508,8 @@ public ChaincodeEvent getEvent() {
}
public TransactionActionInfo getTransactionActionInfo(int index) {
- return new TransactionActionInfo(transactionDeserializer.getPayload().getTransaction().getTransactionAction(index));
+ return BlockInfo.this.isFiltered() ? new TransactionActionInfo(filteredTx.getTransactionActions().getChaincodeActionsList().get(index))
+ : new TransactionActionInfo(transactionDeserializer.getPayload().getTransaction().getTransactionAction(index));
}
public class TransactionActionInfoIterator implements Iterator {
@@ -365,8 +530,13 @@ public boolean hasNext() {
@Override
public TransactionActionInfo next() {
- return getTransactionActionInfo(ci++);
+ if (ci >= max) {
+ throw new ArrayIndexOutOfBoundsException(format("Current index: %d. Max index: %d", ci, max));
+ }
+ // return BlockInfo.this.isFiltered() ? new TransactionActionInfo(filteredTx.getFilteredAction(ci++))
+ return BlockInfo.this.isFiltered() ? new TransactionActionInfo(filteredTx.getTransactionActions().getChaincodeActions(ci++))
+ : getTransactionActionInfo(ci++);
}
}
@@ -377,7 +547,6 @@ public Iterator iterator() {
return new TransactionActionInfoIterator();
}
}
-
}
class EnvelopeInfoIterator implements Iterator {
@@ -385,7 +554,7 @@ class EnvelopeInfoIterator implements Iterator {
final int max;
EnvelopeInfoIterator() {
- max = block.getData().getDataCount();
+ max = isFiltered() ? filteredBlock.getFilteredTxCount() : block.getData().getDataCount();
}
@@ -398,6 +567,10 @@ public boolean hasNext() {
@Override
public EnvelopeInfo next() {
+ if (ci >= max) {
+ throw new ArrayIndexOutOfBoundsException(format("Current index: %d. Max index: %d", ci, max));
+ }
+
try {
return getEnvelopeInfo(ci++);
} catch (InvalidProtocolBufferException e) {
diff --git a/src/main/java/org/hyperledger/fabric/sdk/Channel.java b/src/main/java/org/hyperledger/fabric/sdk/Channel.java
index ac734ccb..fc9f7196 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/Channel.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/Channel.java
@@ -561,7 +561,7 @@ public String getName() {
*/
public Channel addPeer(Peer peer) throws InvalidArgumentException {
- return addPeer(peer, PeerOptions.create());
+ return addPeer(peer, PeerOptions.createPeerOptions());
}
@@ -615,7 +615,7 @@ public Channel addPeer(Peer peer, PeerOptions peerOptions) throws InvalidArgumen
*/
public Channel joinPeer(Peer peer) throws ProposalException {
- return joinPeer(peer, PeerOptions.create());
+ return joinPeer(peer, PeerOptions.createPeerOptions());
}
private Collection getEventingPeers() {
@@ -644,8 +644,7 @@ private Collection getLedgerQueryPeers() {
}
/**
- *
- * @param peer the peer to join the channel.
+ * @param peer the peer to join the channel.
* @param peerOptions see {@link PeerOptions}
* @return
* @throws ProposalException
@@ -852,7 +851,7 @@ public Collection getPeers(EnumSet roles) {
/**
* Set peerOptions in the channel that has not be initialized yet.
*
- * @param peer the peer to set options on.
+ * @param peer the peer to set options on.
* @param peerOptions see {@link PeerOptions}
* @return old options.
*/
@@ -1040,6 +1039,7 @@ boolean isSystemChannel() {
/**
* Is the channel shutdown.
+ *
* @return return true if the channel is shutdown.
*/
public boolean isShutdown() {
@@ -1048,6 +1048,7 @@ public boolean isShutdown() {
/**
* Get signed byes of the update channel.
+ *
* @param updateChannelConfiguration
* @param signer
* @return
@@ -2404,8 +2405,8 @@ public CompletableFuture sendTransaction(Collection peerRoles;
- // protected String blockType = "Filter"; // not yet used.
protected Boolean newest = true;
protected Long startEvents;
protected Long stopEvents = Long.MAX_VALUE;
+ protected boolean registerEventsForFilteredBlocks = false;
+
+ /**
+ * Is the peer eventing service registered for filtered blocks
+ *
+ * @return true if filtered blocks will be returned by the peer eventing service.
+ */
+ public boolean isRegisterEventsForFilteredBlocks() {
+ return registerEventsForFilteredBlocks;
+ }
+
+ /**
+ * Register the peer eventing services to return filtered blocks.
+ *
+ * @return the PeerOptions instance.
+ */
+
+ public PeerOptions registerEventsForFilteredBlocks() {
+ registerEventsForFilteredBlocks = true;
+ return this;
+ }
/**
- * Get newest block on startup.
+ * Register the peer eventing services to return full event blocks.
+ *
+ * @return the PeerOptions instance.
+ */
+
+ public PeerOptions registerEventsForBlocks() {
+ registerEventsForFilteredBlocks = false;
+ return this;
+ }
+
+ /**
+ * Get newest block on startup of peer eventing service.
+ *
* @return
*/
- Boolean getNewest() {
+ public Boolean getNewest() {
return newest;
}
/**
- * The block number to start getting.
+ * The block number to start getting events from on start up of the peer eventing service..
*
* @return the start number
*/
@@ -3169,7 +3202,7 @@ public Long getStartEvents() {
}
/**
- * The stopping block number.
+ * The stopping block number when the peer eventing service will stop sending blocks.
*
* @return the stop block number.
*/
@@ -3184,10 +3217,11 @@ protected PeerOptions() {
/**
* Create an instance of PeerOptions.
+ *
* @return the PeerOptions instance.
*/
- public static PeerOptions create() {
+ public static PeerOptions createPeerOptions() {
return new PeerOptions();
}
@@ -3206,6 +3240,7 @@ public EnumSet getPeerRoles() {
/**
* Set the roles this peer will have on the chain it will added or joined.
+ *
* @param peerRoles {@link PeerRole}
* @return This PeerOptions.
*/
@@ -3217,6 +3252,7 @@ public PeerOptions setPeerRoles(EnumSet peerRoles) {
/**
* Add to the roles this peer will have on the chain it will added or joined.
+ *
* @param peerRole see {@link PeerRole}
* @return This PeerOptions.
*/
@@ -3233,6 +3269,7 @@ public PeerOptions addPeerRole(PeerRole peerRole) {
/**
* Set the block number the eventing peer will start relieving events.
+ *
* @param start The staring block number.
* @return This PeerOptions.
*/
@@ -3246,6 +3283,7 @@ public PeerOptions startEvents(long start) {
/**
* This is the default. It will start retrieving events with the newest. Note this is not the
* next block that is added to the chain but the current block on the chain.
+ *
* @return This PeerOptions.
*/
@@ -3258,6 +3296,7 @@ public PeerOptions startEventsNewest() {
/**
* The block number to stop sending events.
+ *
* @param stop the number to stop sending events.
* @return This PeerOptions.
*/
@@ -3268,6 +3307,7 @@ public PeerOptions stopEvents(long stop) {
/**
* Clone.
+ *
* @return return a duplicate of this instance.
*/
diff --git a/src/main/java/org/hyperledger/fabric/sdk/NetworkConfig.java b/src/main/java/org/hyperledger/fabric/sdk/NetworkConfig.java
index ca074e77..f9993d3b 100755
--- a/src/main/java/org/hyperledger/fabric/sdk/NetworkConfig.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/NetworkConfig.java
@@ -567,7 +567,7 @@ private Channel reconstructChannel(HFClient client, String channelName, JsonObje
}
// Set the various roles
- PeerOptions peerOptions = PeerOptions.create();
+ PeerOptions peerOptions = PeerOptions.createPeerOptions();
setPeerRole(channelName, peerOptions, jsonPeer, PeerRole.ENDORSING_PEER);
setPeerRole(channelName, peerOptions, jsonPeer, PeerRole.CHAINCODE_QUERY);
setPeerRole(channelName, peerOptions, jsonPeer, PeerRole.LEDGER_QUERY);
diff --git a/src/main/java/org/hyperledger/fabric/sdk/Orderer.java b/src/main/java/org/hyperledger/fabric/sdk/Orderer.java
index 1212bc41..3619baf1 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/Orderer.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/Orderer.java
@@ -36,7 +36,32 @@ public class Orderer implements Serializable {
private static final Log logger = LogFactory.getLog(Orderer.class);
private static final long serialVersionUID = 4281642068914263247L;
private final Properties properties;
+ private final String name;
+ private final String url;
private transient boolean shutdown = false;
+ private Channel channel;
+ private transient volatile OrdererClient ordererClient = null;
+
+ Orderer(String name, String url, Properties properties) throws InvalidArgumentException {
+
+ if (StringUtil.isNullOrEmpty(name)) {
+ throw new InvalidArgumentException("Invalid name for orderer");
+ }
+ Exception e = checkGrpcUrl(url);
+ if (e != null) {
+ throw new InvalidArgumentException(e);
+ }
+
+ this.name = name;
+ this.url = url;
+ this.properties = properties == null ? null : (Properties) properties.clone(); //keep our own copy.
+
+ }
+
+ static Orderer createNewInstance(String name, String url, Properties properties) throws InvalidArgumentException {
+ return new Orderer(name, url, properties);
+
+ }
/**
* Get Orderer properties.
@@ -58,25 +83,6 @@ public String getName() {
return name;
}
- private final String name;
- private final String url;
-
- Orderer(String name, String url, Properties properties) throws InvalidArgumentException {
-
- if (StringUtil.isNullOrEmpty(name)) {
- throw new InvalidArgumentException("Invalid name for orderer");
- }
- Exception e = checkGrpcUrl(url);
- if (e != null) {
- throw new InvalidArgumentException(e);
- }
-
- this.name = name;
- this.url = url;
- this.properties = properties == null ? null : (Properties) properties.clone(); //keep our own copy.
-
- }
-
/**
* getUrl - the Grpc url of the Orderer
*
@@ -86,28 +92,12 @@ public String getUrl() {
return url;
}
- void setChannel(Channel channel) throws InvalidArgumentException {
- if (channel == null) {
- throw new InvalidArgumentException("setChannel Channel can not be null");
- }
-
- if (null != this.channel && this.channel != channel) {
- throw new InvalidArgumentException(format("Can not add orderer %s to channel %s because it already belongs to channel %s.",
- name, channel.getName(), this.channel.getName()));
- }
-
- this.channel = channel;
-
- }
-
void unsetChannel() {
channel = null;
}
- private Channel channel;
-
/**
* Get the channel of which this orderer is a member.
*
@@ -117,6 +107,20 @@ Channel getChannel() {
return channel;
}
+ void setChannel(Channel channel) throws InvalidArgumentException {
+ if (channel == null) {
+ throw new InvalidArgumentException("setChannel Channel can not be null");
+ }
+
+ if (null != this.channel && this.channel != channel) {
+ throw new InvalidArgumentException(format("Can not add orderer %s to channel %s because it already belongs to channel %s.",
+ name, channel.getName(), this.channel.getName()));
+ }
+
+ this.channel = channel;
+
+ }
+
/**
* Send transaction to Order
*
@@ -148,13 +152,6 @@ Ab.BroadcastResponse sendTransaction(Common.Envelope transaction) throws Excepti
}
- static Orderer createNewInstance(String name, String url, Properties properties) throws InvalidArgumentException {
- return new Orderer(name, url, properties);
-
- }
-
- private transient volatile OrdererClient ordererClient = null;
-
DeliverResponse[] sendDeliver(Common.Envelope transaction) throws TransactionException {
if (shutdown) {
@@ -184,21 +181,20 @@ synchronized void shutdown(boolean force) {
if (shutdown) {
return;
}
+ shutdown = true;
+ channel = null;
+
if (ordererClient != null) {
OrdererClient torderClientDeliver = ordererClient;
ordererClient = null;
torderClientDeliver.shutdown(force);
-
}
- shutdown = true;
- channel = null;
-
}
@Override
protected void finalize() throws Throwable {
- super.finalize();
shutdown(true);
+ super.finalize();
}
} // end Orderer
diff --git a/src/main/java/org/hyperledger/fabric/sdk/Peer.java b/src/main/java/org/hyperledger/fabric/sdk/Peer.java
index 697de2f3..4726be8f 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/Peer.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/Peer.java
@@ -153,7 +153,7 @@ void setChannel(Channel channel) throws InvalidArgumentException {
*/
public String getUrl() {
- return this.url;
+ return url;
}
/**
diff --git a/src/main/java/org/hyperledger/fabric/sdk/PeerEventServiceClient.java b/src/main/java/org/hyperledger/fabric/sdk/PeerEventServiceClient.java
index dc8295c2..6884aeb2 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/PeerEventServiceClient.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/PeerEventServiceClient.java
@@ -30,9 +30,9 @@
import org.apache.commons.logging.LogFactory;
import org.hyperledger.fabric.protos.common.Common.Envelope;
import org.hyperledger.fabric.protos.orderer.Ab;
-import org.hyperledger.fabric.protos.orderer.Ab.DeliverResponse;
import org.hyperledger.fabric.protos.orderer.Ab.SeekInfo;
-import org.hyperledger.fabric.protos.orderer.AtomicBroadcastGrpc;
+import org.hyperledger.fabric.protos.peer.DeliverGrpc;
+import org.hyperledger.fabric.protos.peer.PeerEvents.DeliverResponse;
import org.hyperledger.fabric.sdk.Channel.PeerOptions;
import org.hyperledger.fabric.sdk.exception.CryptoException;
import org.hyperledger.fabric.sdk.exception.TransactionException;
@@ -40,9 +40,12 @@
import org.hyperledger.fabric.sdk.transaction.TransactionContext;
import static java.lang.String.format;
-import static org.hyperledger.fabric.protos.orderer.Ab.DeliverResponse.TypeCase.STATUS;
+import static org.hyperledger.fabric.protos.peer.PeerEvents.DeliverResponse.TypeCase.BLOCK;
+import static org.hyperledger.fabric.protos.peer.PeerEvents.DeliverResponse.TypeCase.FILTERED_BLOCK;
+import static org.hyperledger.fabric.protos.peer.PeerEvents.DeliverResponse.TypeCase.STATUS;
import static org.hyperledger.fabric.sdk.transaction.ProtoUtils.createSeekInfoEnvelope;
+
/**
* Sample client code that makes gRPC calls to the server.
*/
@@ -56,8 +59,11 @@ class PeerEventServiceClient {
private final String url;
private final long ordererWaitTimeMilliSecs;
private final PeerOptions peerOptions;
- private Channel.ChannelEventQue channelEventQue;
+ private final boolean filterBlock;
Properties properties = new Properties();
+ StreamObserver nso = null;
+ StreamObserver so = null;
+ private Channel.ChannelEventQue channelEventQue;
private boolean shutdown = false;
private ManagedChannel managedChannel = null;
private transient TransactionContext transactionContext;
@@ -69,6 +75,7 @@ class PeerEventServiceClient {
PeerEventServiceClient(Peer peer, ManagedChannelBuilder> channelBuilder, Properties properties, PeerOptions peerOptions) {
this.channelBuilder = channelBuilder;
+ this.filterBlock = peerOptions.isRegisterEventsForFilteredBlocks();
this.peer = peer;
name = peer.getName();
url = peer.getUrl();
@@ -140,9 +147,6 @@ synchronized void shutdown(boolean force) {
}
- StreamObserver nso = null;
- StreamObserver so = null;
-
@Override
public void finalize() {
shutdown(true);
@@ -165,7 +169,7 @@ DeliverResponse[] connectEnvelope(Envelope envelope) throws TransactionException
try {
- AtomicBroadcastGrpc.AtomicBroadcastStub broadcast = AtomicBroadcastGrpc.newStub(lmanagedChannel);
+ DeliverGrpc.DeliverStub broadcast = DeliverGrpc.newStub(lmanagedChannel);
// final DeliverResponse[] ret = new DeliverResponse[1];
final List retList = new ArrayList<>();
@@ -192,7 +196,9 @@ public void onNext(DeliverResponse resp) {
return;
}
- if (resp.getTypeCase() == STATUS) {
+ final DeliverResponse.TypeCase typeCase = resp.getTypeCase();
+
+ if (typeCase == STATUS) {
done = true;
logger.debug(format("DeliverResponse channel %s peer %s setting done.",
channelName, peer.getName()));
@@ -200,12 +206,16 @@ public void onNext(DeliverResponse resp) {
finishLatch.countDown();
- } else {
+ } else if (typeCase == FILTERED_BLOCK || typeCase == BLOCK) {
logger.trace(format("Channel %s peer %s got event block hex hashcode: %016x, block number: %d",
channelName, peer.getName(), resp.getBlock().hashCode(), resp.getBlock().getHeader().getNumber()));
retList.add(resp);
finishLatch.countDown();
channelEventQue.addBEvent(new BlockEvent(peer, resp));
+ } else {
+ logger.error(format("Channel %s peer %s got event block with unknown type: %s, %d",
+ channelName, peer.getName(), typeCase.name(), typeCase.getNumber())
+ );
}
}
@@ -217,7 +227,7 @@ public void onError(Throwable t) {
return; // make sure we do this once.
}
if (!shutdown) {
- logger.error(format("Received error on channel %s, orderer %s, url %s, %s",
+ logger.error(format("Received error on channel %s, peer %s, url %s, %s",
channelName, name, url, t.getMessage()), t);
done = true;
@@ -243,7 +253,8 @@ public void onCompleted() {
}
};
- nso = broadcast.deliver(so);
+ nso = filterBlock ? broadcast.deliverFiltered(so) : broadcast.deliver(so);
+
nso.onNext(envelope);
//nso.onCompleted();
@@ -251,7 +262,7 @@ public void onCompleted() {
// if (!finishLatch.await(ordererWaitTimeMilliSecs, TimeUnit.MILLISECONDS)) {
if (!finishLatch.await(9999999, TimeUnit.MILLISECONDS)) {
TransactionException ex = new TransactionException(format(
- "Channel %s connect time exceeded for orderer %s, timed out at %d ms.", channelName, name, ordererWaitTimeMilliSecs));
+ "Channel %s connect time exceeded for peer eventing service %s, timed out at %d ms.", channelName, name, ordererWaitTimeMilliSecs));
logger.error(ex.getMessage(), ex);
throw ex;
}
@@ -264,7 +275,7 @@ public void onCompleted() {
if (!throwableList.isEmpty()) {
Throwable throwable = throwableList.get(0);
TransactionException e = new TransactionException(format(
- "Channel %s connect failed on orderer %s. Reason: %s", channelName, name, throwable.getMessage()), throwable);
+ "Channel %s connect failed on peer eventing service %s. Reason: %s", channelName, name, throwable.getMessage()), throwable);
logger.error(e.getMessage(), e);
throw e;
}
diff --git a/src/main/java/org/hyperledger/fabric/sdk/helper/Config.java b/src/main/java/org/hyperledger/fabric/sdk/helper/Config.java
index 1c27b1ef..f7d1e728 100644
--- a/src/main/java/org/hyperledger/fabric/sdk/helper/Config.java
+++ b/src/main/java/org/hyperledger/fabric/sdk/helper/Config.java
@@ -62,7 +62,6 @@ public class Config {
public static final String SECURITY_CURVE_MAPPING = "org.hyperledger.fabric.sdk.security_curve_mapping";
public static final String HASH_ALGORITHM = "org.hyperledger.fabric.sdk.hash_algorithm";
public static final String ASYMMETRIC_KEY_TYPE = "org.hyperledger.fabric.sdk.crypto.asymmetric_key_type";
-
public static final String CERTIFICATE_FORMAT = "org.hyperledger.fabric.sdk.crypto.certificate_format";
public static final String SIGNATURE_ALGORITHM = "org.hyperledger.fabric.sdk.crypto.default_signature_algorithm";
/**
diff --git a/src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java b/src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java
index 6d2b1a9d..82012f78 100644
--- a/src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java
+++ b/src/main/java/org/hyperledger/fabric_ca/sdk/HFCAClient.java
@@ -102,6 +102,10 @@
*/
public class HFCAClient {
+ /**
+ * Default profile name.
+ */
+ public static final String DEFAULT_PROFILE_NAME = "";
private static final Log logger = LogFactory.getLog(HFCAClient.class);
private static final String HFCA_CONTEXT_ROOT = "/api/v1/";
private static final String HFCA_ENROLL = HFCA_CONTEXT_ROOT + "enroll";
diff --git a/src/main/proto/peer/events.proto b/src/main/proto/peer/events.proto
index 51baea38..6179b50a 100644
--- a/src/main/proto/peer/events.proto
+++ b/src/main/proto/peer/events.proto
@@ -27,15 +27,14 @@ option go_package = "github.com/hyperledger/fabric/protos/peer";
package protos;
-
//----Event objects----
enum EventType {
- REGISTER = 0;
- BLOCK = 1;
- CHAINCODE = 2;
- REJECTION = 3;
- FILTEREDBLOCK = 4;
+ REGISTER = 0;
+ BLOCK = 1;
+ CHAINCODE = 2;
+ REJECTION = 3;
+ FILTEREDBLOCK = 4;
}
//ChaincodeReg is used for registering chaincode Interests
@@ -81,7 +80,6 @@ message Unregister {
message FilteredBlock {
string channel_id = 1;
uint64 number = 2; // The position in the blockchain
- common.HeaderType type = 3;
repeated FilteredTransaction filtered_tx = 4;
}
@@ -89,13 +87,22 @@ message FilteredBlock {
//within a block.
message FilteredTransaction {
string txid = 1;
- TxValidationCode tx_validation_code = 2;
- repeated FilteredAction filtered_action = 3;
+ common.HeaderType type = 2;
+ TxValidationCode tx_validation_code = 3;
+ oneof Data {
+ FilteredTransactionActions transaction_actions = 4;
+ }
+}
+
+// FilteredTransactionActions is a wrapper for array of TransactionAction
+// message from regular block
+message FilteredTransactionActions {
+ repeated FilteredChaincodeAction chaincode_actions = 1;
}
-//FilteredAction is a minimal set of information about an action within a
+//FilteredChaincodeAction is a minimal set of information about an action within a
//transaction.
-message FilteredAction {
+message FilteredChaincodeAction {
ChaincodeEvent ccEvent = 1;
}
@@ -129,10 +136,35 @@ message Event {
bytes creator = 6;
// Timestamp of the client - used to mitigate replay attacks
google.protobuf.Timestamp timestamp = 8;
+
+ // If mutual TLS is employed, this represents
+ // the hash of the client's TLS certificate
+ bytes tls_cert_hash = 9;
}
// Interface exported by the events server
service Events {
// event chatting using Event
- rpc Chat(stream SignedEvent) returns (stream Event) {}
+ rpc Chat (stream SignedEvent) returns (stream Event) {
+ }
}
+
+// DeliverResponse
+message DeliverResponse {
+ oneof Type {
+ common.Status status = 1;
+ common.Block block = 2;
+ FilteredBlock filtered_block = 3;
+ }
+}
+
+service Deliver {
+ // deliver first requires an Envelope of type ab.DELIVER_SEEK_INFO with Payload data as a marshaled orderer.SeekInfo message,
+ // then a stream of block replies is received.
+ rpc Deliver (stream common.Envelope) returns (stream DeliverResponse) {
+ }
+ // deliver first requires an Envelope of type ab.DELIVER_SEEK_INFO with Payload data as a marshaled orderer.SeekInfo message,
+ // then a stream of **filtered** block replies is received.
+ rpc DeliverFiltered (stream common.Envelope) returns (stream DeliverResponse) {
+ }
+}
\ No newline at end of file
diff --git a/src/main/proto/peer/query.proto b/src/main/proto/peer/query.proto
index 8dc3ec4d..d934104f 100644
--- a/src/main/proto/peer/query.proto
+++ b/src/main/proto/peer/query.proto
@@ -26,35 +26,41 @@ package protos;
// instantiated on a channel), and GetInstalledChaincodes (returns all chaincodes
// installed on a peer)
message ChaincodeQueryResponse {
- repeated ChaincodeInfo chaincodes = 1;
+ repeated ChaincodeInfo chaincodes = 1;
}
// ChaincodeInfo contains general information about an installed/instantiated
// chaincode
message ChaincodeInfo {
- string name = 1;
- string version = 2;
- // the path as specified by the install/instantiate transaction
- string path = 3;
- // the chaincode function upon instantiation and its arguments. This will be
- // blank if the query is returning information about installed chaincodes.
- string input = 4;
- // the name of the ESCC for this chaincode. This will be
- // blank if the query is returning information about installed chaincodes.
- string escc = 5;
- // the name of the VSCC for this chaincode. This will be
- // blank if the query is returning information about installed chaincodes.
- string vscc = 6;
+ string name = 1;
+ string version = 2;
+ // the path as specified by the install/instantiate transaction
+ string path = 3;
+ // the chaincode function upon instantiation and its arguments. This will be
+ // blank if the query is returning information about installed chaincodes.
+ string input = 4;
+ // the name of the ESCC for this chaincode. This will be
+ // blank if the query is returning information about installed chaincodes.
+ string escc = 5;
+ // the name of the VSCC for this chaincode. This will be
+ // blank if the query is returning information about installed chaincodes.
+ string vscc = 6;
+ // the chaincode unique id.
+ // computed as: H(
+ // H(name || version) ||
+ // H(CodePackage)
+ // )
+ bytes id = 7;
}
// ChannelQueryResponse returns information about each channel that pertains
// to a query in lscc.go, such as GetChannels (returns all channels for a
// given peer)
message ChannelQueryResponse {
- repeated ChannelInfo channels = 1;
+ repeated ChannelInfo channels = 1;
}
// ChannelInfo contains general information about channels
message ChannelInfo {
- string channel_id = 1;
+ string channel_id = 1;
}
diff --git a/src/test/fixture/sdkintegration/peer-base/peer-base.yaml b/src/test/fixture/sdkintegration/peer-base/peer-base.yaml
index 0830baf8..7f29ca9d 100644
--- a/src/test/fixture/sdkintegration/peer-base/peer-base.yaml
+++ b/src/test/fixture/sdkintegration/peer-base/peer-base.yaml
@@ -13,6 +13,7 @@ services:
- CORE_PEER_ENDORSER_ENABLED=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
+ - CORE_PEER_CHANNELSERVICE_ENABLED=true
# The following setting skips the gossip handshake since we are
# are not doing mutual TLS
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/msp
diff --git a/src/test/java/org/hyperledger/fabric/sdk/ChannelTest.java b/src/test/java/org/hyperledger/fabric/sdk/ChannelTest.java
index 3d24641c..0251e22f 100644
--- a/src/test/java/org/hyperledger/fabric/sdk/ChannelTest.java
+++ b/src/test/java/org/hyperledger/fabric/sdk/ChannelTest.java
@@ -41,6 +41,7 @@
import org.junit.rules.ExpectedException;
import sun.misc.Unsafe;
+import static org.hyperledger.fabric.sdk.Channel.PeerOptions.createPeerOptions;
import static org.hyperledger.fabric.sdk.testutils.TestUtils.setField;
//CHECKSTYLE.ON: IllegalImport
@@ -246,7 +247,7 @@ protected void loadCACertificates() {
final Channel testChannel = new MockChannel(CHANNEL_NAME, hfclient);
final Peer peer = hfclient.newPeer("peer_", "grpc://localhost:7051");
- testChannel.addPeer(peer, Channel.PeerOptions.create().setPeerRoles(Peer.PeerRole.NO_EVENT_SOURCE));
+ testChannel.addPeer(peer, createPeerOptions().setPeerRoles(Peer.PeerRole.NO_EVENT_SOURCE));
Assert.assertFalse(testChannel.isInitialized());
testChannel.initialize();
Assert.assertTrue(testChannel.isInitialized());
diff --git a/src/test/java/org/hyperledger/fabric/sdk/PeerTest.java b/src/test/java/org/hyperledger/fabric/sdk/PeerTest.java
index a16bc286..02658ca7 100644
--- a/src/test/java/org/hyperledger/fabric/sdk/PeerTest.java
+++ b/src/test/java/org/hyperledger/fabric/sdk/PeerTest.java
@@ -55,37 +55,37 @@ public void testGetName() {
}
- @Test(expected = InvalidArgumentException.class)
+ @Test (expected = InvalidArgumentException.class)
public void testSetNullName() throws InvalidArgumentException {
peer = hfclient.newPeer(null, "grpc://localhost:4");
Assert.fail("expected set null name to throw exception.");
}
- @Test(expected = InvalidArgumentException.class)
+ @Test (expected = InvalidArgumentException.class)
public void testSetEmptyName() throws InvalidArgumentException {
peer = hfclient.newPeer("", "grpc://localhost:4");
Assert.fail("expected set empty name to throw exception.");
}
- @Test(expected = PeerException.class)
+ @Test (expected = PeerException.class)
public void testSendNullProposal() throws PeerException, InvalidArgumentException {
peer.sendProposal(null);
Assert.fail("Expected null proposal to throw exception.");
}
- @Test(expected = PeerException.class)
+ @Test (expected = PeerException.class)
public void testSendNullChannel() throws InvalidArgumentException, PeerException {
Peer badpeer = hfclient.newPeer("badpeer", "grpc://localhost:7051");
badpeer.sendProposal(FabricProposal.SignedProposal.newBuilder().build());
Assert.fail("Expected peer with no channel throw exception");
}
- @Test(expected = PeerException.class)
+ @Test (expected = PeerException.class)
public void testSendAsyncNullProposal() throws PeerException, InvalidArgumentException {
peer.sendProposalAsync(null);
}
- @Test(expected = InvalidArgumentException.class)
+ @Test (expected = InvalidArgumentException.class)
public void testBadURL() throws InvalidArgumentException {
hfclient.newPeer(PEER_NAME, " ");
Assert.fail("Expected peer with no channel throw exception");
diff --git a/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java b/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java
index 4bdbc65f..0be2d72f 100644
--- a/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java
+++ b/src/test/java/org/hyperledger/fabric/sdk/testutils/TestConfig.java
@@ -87,7 +87,7 @@ private TestConfig() {
// Default values
- defaultProperty(INVOKEWAITTIME, "100000");
+ defaultProperty(INVOKEWAITTIME, "120");
defaultProperty(DEPLOYWAITTIME, "120000");
defaultProperty(PROPOSALWAITTIME, "120000");
diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java
index dfbcbf41..8d5e65da 100644
--- a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java
+++ b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java
@@ -15,7 +15,6 @@
package org.hyperledger.fabric.sdkintegration;
import java.io.File;
-import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
@@ -29,16 +28,16 @@
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;
import org.hyperledger.fabric.protos.common.Configtx;
import org.hyperledger.fabric.protos.peer.Query.ChaincodeInfo;
import org.hyperledger.fabric.sdk.BlockEvent;
+import org.hyperledger.fabric.sdk.BlockInfo;
import org.hyperledger.fabric.sdk.BlockchainInfo;
import org.hyperledger.fabric.sdk.ChaincodeEndorsementPolicy;
+import org.hyperledger.fabric.sdk.ChaincodeEvent;
import org.hyperledger.fabric.sdk.ChaincodeID;
import org.hyperledger.fabric.sdk.ChaincodeResponse.Status;
import org.hyperledger.fabric.sdk.Channel;
@@ -57,7 +56,6 @@
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
import org.hyperledger.fabric.sdk.exception.ProposalException;
import org.hyperledger.fabric.sdk.exception.TransactionEventException;
-import org.hyperledger.fabric.sdk.exception.TransactionException;
import org.hyperledger.fabric.sdk.security.CryptoSuite;
import org.hyperledger.fabric.sdk.testutils.TestConfig;
import org.hyperledger.fabric.sdk.testutils.TestUtils;
@@ -67,6 +65,8 @@
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.hyperledger.fabric.sdk.BlockInfo.EnvelopeType.TRANSACTION_ENVELOPE;
+import static org.hyperledger.fabric.sdk.Channel.PeerOptions.createPeerOptions;
import static org.hyperledger.fabric.sdk.testutils.TestUtils.resetConfig;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -236,17 +236,25 @@ public void setup() {
// Now test replay feature of V1.1 peer eventing services.
byte[] replayChannelBytes = barChannel.serializeChannel();
barChannel.shutdown(true);
+
Channel replayChannel = client.deSerializeChannel(replayChannelBytes);
- testPeerServiceEventingReplay(client, replayChannel, 0L, -1L);
+ out("doing testPeerServiceEventingReplay,0,-1,false");
+ testPeerServiceEventingReplay(client, replayChannel, 0L, -1L, false);
+
+ replayChannel = client.deSerializeChannel(replayChannelBytes);
+ out("doing testPeerServiceEventingReplay,0,-1,true"); // block 0 is import to test
+ testPeerServiceEventingReplay(client, replayChannel, 0L, -1L, true);
//Now do it again starting at block 1
replayChannel = client.deSerializeChannel(replayChannelBytes);
- testPeerServiceEventingReplay(client, replayChannel, 1L, -1L);
+ out("doing testPeerServiceEventingReplay,1,-1,false");
+ testPeerServiceEventingReplay(client, replayChannel, 1L, -1L, false);
//Now do it again starting at block 2 to 3
replayChannel = client.deSerializeChannel(replayChannelBytes);
- testPeerServiceEventingReplay(client, replayChannel, 2L, 3L);
+ out("doing testPeerServiceEventingReplay,2,3,false");
+ testPeerServiceEventingReplay(client, replayChannel, 2L, 3L, false);
}
@@ -575,12 +583,21 @@ private Channel reconstructChannel(String name, HFClient client, SampleOrg sampl
testConfig.getOrdererProperties(ordererName)));
}
+ boolean everyOther = false;
+
for (String peerName : sampleOrg.getPeerNames()) {
String peerLocation = sampleOrg.getPeerLocation(peerName);
Properties peerProperties = testConfig.getPeerProperties(peerName);
Peer peer = client.newPeer(peerName, peerLocation, peerProperties);
+ final PeerOptions peerEventingOptions = // we have two peers on one use block on other use filtered
+ everyOther ?
+ createPeerOptions().registerEventsForBlocks() :
+ createPeerOptions().registerEventsForFilteredBlocks();
+
newChannel.addPeer(peer, IS_FABRIC_V10 ?
- PeerOptions.create().setPeerRoles(PeerRole.NO_EVENT_SOURCE) : PeerOptions.create());
+ createPeerOptions().setPeerRoles(PeerRole.NO_EVENT_SOURCE) : peerEventingOptions);
+
+ everyOther = !everyOther;
}
//For testing mix it up. For v1.1 use just peer eventing service for foo channel.
@@ -684,23 +701,23 @@ private Channel reconstructChannel(String name, HFClient client, SampleOrg sampl
return newChannel;
}
+
/**
- * This code test the replay feature of the new peer event services.
- * Instead of the default of starting the eventing peer to retrieve the newest block it sets it
- * retrieve starting from the start parameter.
*
+ *This code test the replay feature of the new peer event services.
+ * Instead of the default of starting the eventing peer to retrieve the newest block it sets it
+ * retrieve starting from the start parameter. Also checks with block and filterblock replays.
+ * Depends on end2end and end2endAndBackagain of have fully run to have the blocks need to work with.
* @param client
* @param replayTestChannel
- * @throws IOException
+ * @param start
+ * @param stop
+ * @param useFilteredBlocks
* @throws InvalidArgumentException
- * @throws TransactionException
- * @throws InterruptedException
- * @throws ExecutionException
- * @throws TimeoutException
- * @throws ProposalException
*/
- void testPeerServiceEventingReplay(HFClient client, Channel replayTestChannel, final long start, final long stop) throws InvalidArgumentException, TransactionException, InterruptedException, ExecutionException, TimeoutException, ProposalException {
+ private void testPeerServiceEventingReplay(HFClient client, Channel replayTestChannel, final long start, final long stop,
+ final boolean useFilteredBlocks) throws InvalidArgumentException {
if (testConfig.isRunningAgainstFabric10()) {
return; // not supported for v1.0
@@ -724,16 +741,20 @@ void testPeerServiceEventingReplay(HFClient client, Channel replayTestChannel, f
assertNotNull(client.getChannel(replayTestChannel.getName())); // should be known by client.
+ final PeerOptions eventingPeerOptions = createPeerOptions().setPeerRoles(EnumSet.of(PeerRole.EVENT_SOURCE));
+ if (useFilteredBlocks) {
+ eventingPeerOptions.registerEventsForFilteredBlocks();
+ }
+
if (-1L == stop) { //the height of the blockchain
- replayTestChannel.addPeer(eventingPeer, PeerOptions.create().setPeerRoles(EnumSet.of(PeerRole.EVENT_SOURCE))
- .startEvents(start)); // Eventing peer start getting blocks from block 0
+ replayTestChannel.addPeer(eventingPeer, eventingPeerOptions.startEvents(start)); // Eventing peer start getting blocks from block 0
} else {
- replayTestChannel.addPeer(eventingPeer, PeerOptions.create().setPeerRoles(EnumSet.of(PeerRole.EVENT_SOURCE))
+ replayTestChannel.addPeer(eventingPeer, eventingPeerOptions
.startEvents(start).stopEvents(stop)); // Eventing peer start getting blocks from block 0
-
}
- replayTestChannel.addPeer(ledgerPeer, PeerOptions.create().setPeerRoles(EnumSet.of(PeerRole.LEDGER_QUERY)));
+ //add a ledger peer
+ replayTestChannel.addPeer(ledgerPeer, createPeerOptions().setPeerRoles(EnumSet.of(PeerRole.LEDGER_QUERY)));
CompletableFuture done = new CompletableFuture<>(); // future to set when done.
// some variable used by the block listener being set up.
@@ -749,9 +770,13 @@ void testPeerServiceEventingReplay(HFClient client, Channel replayTestChannel, f
final long blockNumber = blockEvent.getBlockNumber();
BlockEvent seen = blockEvents.put(blockNumber, blockEvent);
assertNull(format("Block number %d seen twice", blockNumber), seen);
+
+ assertTrue(format("Wrong type of block seen block number %d. expected filtered block %b but got %b",
+ blockNumber, useFilteredBlocks, blockEvent.isFiltered()),
+ useFilteredBlocks ? blockEvent.isFiltered() : !blockEvent.isFiltered());
final long count = bcount.getAndIncrement(); //count starts with 0 not 1 !
- out("Block count: %d, block number: %d received from peer: %s", count, blockNumber, blockEvent.getPeer().getName());
+ //out("Block count: %d, block number: %d received from peer: %s", count, blockNumber, blockEvent.getPeer().getName());
if (count == 0 && stop == -1L) {
final BlockchainInfo blockchainInfo = finalChannel.queryBlockchainInfo();
@@ -774,22 +799,85 @@ void testPeerServiceEventingReplay(HFClient client, Channel replayTestChannel, f
}
});
- replayTestChannel.initialize(); // start it all up.
- done.get(30, TimeUnit.SECONDS); // give a timeout here.
- Thread.sleep(1000); // sleep a little to see if more blocks trickle in .. they should not
- replayTestChannel.unregisterBlockListener(blockListenerHandle);
- final long expectNumber = stopValue.longValue() - start + 1L; // Start 2 and stop is 3 expect 2
+ try {
+ replayTestChannel.initialize(); // start it all up.
+ done.get(30, TimeUnit.SECONDS); // give a timeout here.
+ Thread.sleep(1000); // sleep a little to see if more blocks trickle in .. they should not
+ replayTestChannel.unregisterBlockListener(blockListenerHandle);
- assertEquals(format("Didn't get number we expected %d but got %d block events. Start: %d, end: %d, height: %d",
- expectNumber, blockEvents.size(), start, stop, stopValue.longValue()), expectNumber, blockEvents.size());
+ final long expectNumber = stopValue.longValue() - start + 1L; // Start 2 and stop is 3 expect 2
- for (long i = stopValue.longValue(); i >= start; i--) { //make sure all are there.
- final BlockEvent blockEvent = blockEvents.get(i);
- assertNotNull(format("Missing block event for block number %d. Start= %d", i, start), blockEvent);
- }
+ assertEquals(format("Didn't get number we expected %d but got %d block events. Start: %d, end: %d, height: %d",
+ expectNumber, blockEvents.size(), start, stop, stopValue.longValue()), expectNumber, blockEvents.size());
+
+ for (long i = stopValue.longValue(); i >= start; i--) { //make sure all are there.
+ final BlockEvent blockEvent = blockEvents.get(i);
+ assertNotNull(format("Missing block event for block number %d. Start= %d", i, start), blockEvent);
+ }
+
+ //light weight test just see if we get reasonable values for traversing the block. Test just whats common between
+ // Block and FilteredBlock.
+
+ int transactionEventCounts = 0;
+ int chaincodeEventsCounts = 0;
+
+ for (long i = stopValue.longValue(); i >= start; i--) {
+
+ final BlockEvent blockEvent = blockEvents.get(i);
+// out("blockwalker %b, start: %d, stop: %d, i: %d, block %d", useFilteredBlocks, start, stopValue.longValue(), i, blockEvent.getBlockNumber());
+ assertEquals(useFilteredBlocks, blockEvent.isFiltered()); // check again
+
+ if (useFilteredBlocks) {
+ assertNull(blockEvent.getBlock()); // should not have raw block event.
+ assertNotNull(blockEvent.getFilteredBlock()); // should have raw filtered block.
+ } else {
+ assertNotNull(blockEvent.getBlock()); // should not have raw block event.
+ assertNull(blockEvent.getFilteredBlock()); // should have raw filtered block.
+ }
+
+ assertEquals(replayTestChannel.getName(), blockEvent.getChannelId());
+
+ for (BlockInfo.EnvelopeInfo envelopeInfo : blockEvent.getEnvelopeInfos()) {
+ if (envelopeInfo.getType() == TRANSACTION_ENVELOPE) {
+
+ BlockInfo.TransactionEnvelopeInfo transactionEnvelopeInfo = (BlockInfo.TransactionEnvelopeInfo) envelopeInfo;
+ assertTrue(envelopeInfo.isValid()); // only have valid blocks.
+ assertEquals(envelopeInfo.getValidationCode(), 0);
+
+ ++transactionEventCounts;
+ for (BlockInfo.TransactionEnvelopeInfo.TransactionActionInfo ta : transactionEnvelopeInfo.getTransactionActionInfos()) {
+ // out("\nTA:", ta + "\n\n");
+ ChaincodeEvent event = ta.getEvent();
+ if (event != null) {
+ assertNotNull(event.getChaincodeId());
+ assertNotNull(event.getEventName());
+ chaincodeEventsCounts++;
+ }
+
+ }
+
+ } else {
+ assertEquals("Only non transaction block should be block 0.", blockEvent.getBlockNumber(), 0);
- replayTestChannel.shutdown(true); //all done.
+ }
+
+ }
+
+ }
+
+ assertTrue(transactionEventCounts > 0);
+
+ if (expectNumber > 4) { // this should be enough blocks with CC events.
+
+ assertTrue(chaincodeEventsCounts > 0);
+ }
+
+ replayTestChannel.shutdown(true); //all done.
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
}
private void queryChaincodeForExpectedValue(HFClient client, Channel channel, final String expect, ChaincodeID chaincodeID) {
diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java
index ca637d18..118b3e2b 100644
--- a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java
+++ b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java
@@ -39,7 +39,6 @@
import org.hyperledger.fabric.sdk.ChaincodeEvent;
import org.hyperledger.fabric.sdk.ChaincodeID;
import org.hyperledger.fabric.sdk.Channel;
-import org.hyperledger.fabric.sdk.Channel.PeerOptions;
import org.hyperledger.fabric.sdk.ChannelConfiguration;
import org.hyperledger.fabric.sdk.EventHub;
import org.hyperledger.fabric.sdk.HFClient;
@@ -70,6 +69,7 @@
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hyperledger.fabric.sdk.BlockInfo.EnvelopeType.TRANSACTION_ENVELOPE;
+import static org.hyperledger.fabric.sdk.Channel.PeerOptions.createPeerOptions;
import static org.hyperledger.fabric.sdk.testutils.TestUtils.resetConfig;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -726,9 +726,10 @@ private Channel constructChannel(String name, HFClient client, SampleOrg sampleO
Peer peer = client.newPeer(peerName, peerLocation, peerProperties);
if (doPeerEventing && everyother) {
- newChannel.joinPeer(peer); //Default is all roles.
+ newChannel.joinPeer(peer, createPeerOptions()); //Default is all roles.
} else {
- newChannel.joinPeer(peer, PeerOptions.create().setPeerRoles(PeerRole.NO_EVENT_SOURCE));
+ // Set peer to not be all roles but eventing.
+ newChannel.joinPeer(peer, createPeerOptions().setPeerRoles(PeerRole.NO_EVENT_SOURCE));
}
out("Peer %s joined channel %s", peerName, name);
everyother = !everyother;
diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/UpdateChannelIT.java b/src/test/java/org/hyperledger/fabric/sdkintegration/UpdateChannelIT.java
index 8bbb453d..e3505097 100644
--- a/src/test/java/org/hyperledger/fabric/sdkintegration/UpdateChannelIT.java
+++ b/src/test/java/org/hyperledger/fabric/sdkintegration/UpdateChannelIT.java
@@ -35,7 +35,6 @@
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.hyperledger.fabric.sdk.Channel;
-import org.hyperledger.fabric.sdk.Channel.PeerOptions;
import org.hyperledger.fabric.sdk.EventHub;
import org.hyperledger.fabric.sdk.HFClient;
import org.hyperledger.fabric.sdk.Peer;
@@ -47,6 +46,7 @@
import org.junit.Test;
import static java.lang.String.format;
+import static org.hyperledger.fabric.sdk.Channel.PeerOptions.createPeerOptions;
import static org.hyperledger.fabric.sdk.testutils.TestUtils.resetConfig;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -242,7 +242,7 @@ private Channel reconstructChannel(String name, HFClient client, SampleOrg sampl
throw new AssertionError(format("Peer %s does not appear to belong to channel %s", peerName, name));
}
- newChannel.addPeer(peer, PeerOptions.create().setPeerRoles(EnumSet.of(Peer.PeerRole.CHAINCODE_QUERY,
+ newChannel.addPeer(peer, createPeerOptions().setPeerRoles(EnumSet.of(Peer.PeerRole.CHAINCODE_QUERY,
Peer.PeerRole.ENDORSING_PEER, Peer.PeerRole.LEDGER_QUERY)));
}
diff --git a/src/test/java/org/hyperledger/fabric_ca/sdkintegration/HFCAClientIT.java b/src/test/java/org/hyperledger/fabric_ca/sdkintegration/HFCAClientIT.java
index 42bce0fb..f5097920 100644
--- a/src/test/java/org/hyperledger/fabric_ca/sdkintegration/HFCAClientIT.java
+++ b/src/test/java/org/hyperledger/fabric_ca/sdkintegration/HFCAClientIT.java
@@ -55,6 +55,7 @@
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hyperledger.fabric.sdk.testutils.TestUtils.resetConfig;
+import static org.hyperledger.fabric_ca.sdk.HFCAClient.DEFAULT_PROFILE_NAME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -278,7 +279,7 @@ public void testReenrollAndRevoke() throws Exception {
sleepALittle();
// get another enrollment
- EnrollmentRequest req = new EnrollmentRequest("profile 1", "label 1", null);
+ EnrollmentRequest req = new EnrollmentRequest(DEFAULT_PROFILE_NAME, "label 1", null);
req.addHost("example1.ibm.com");
req.addHost("example2.ibm.com");
Enrollment tmpEnroll = client.reenroll(user, req);
@@ -322,7 +323,7 @@ public void testUserRevoke() throws Exception {
}
if (!user.isEnrolled()) {
- EnrollmentRequest req = new EnrollmentRequest("profile 2", "label 2", null);
+ EnrollmentRequest req = new EnrollmentRequest(DEFAULT_PROFILE_NAME, "label 2", null);
req.addHost("example3.ibm.com");
user.setEnrollment(client.enroll(user.getName(), user.getEnrollmentSecret(), req));
@@ -384,7 +385,7 @@ public void testUserRevokeNullReason() throws Exception {
sleepALittle();
if (!user.isEnrolled()) {
- EnrollmentRequest req = new EnrollmentRequest("profile 2", "label 2", null);
+ EnrollmentRequest req = new EnrollmentRequest(DEFAULT_PROFILE_NAME, "label 2", null);
req.addHost("example3.ibm.com");
user.setEnrollment(client.enroll(user.getName(), user.getEnrollmentSecret(), req));
@@ -450,7 +451,7 @@ public void testUserRevokeGenCRL() throws Exception {
sleepALittle();
if (!user.isEnrolled()) {
- EnrollmentRequest req = new EnrollmentRequest("profile 2", "label 2", null);
+ EnrollmentRequest req = new EnrollmentRequest(DEFAULT_PROFILE_NAME, "label 2", null);
req.addHost("example3.ibm.com");
user.setEnrollment(client.enroll(user.getName(), user.getEnrollmentSecret(), req));
@@ -512,7 +513,7 @@ public void testEnrollNoKeyPair() throws Exception {
SampleUser user = getEnrolledUser(TEST_ADMIN_ORG);
- EnrollmentRequest req = new EnrollmentRequest("profile 1", "label 1", null);
+ EnrollmentRequest req = new EnrollmentRequest(DEFAULT_PROFILE_NAME, "label 1", null);
req.setCsr("test");
client.enroll(user.getName(), user.getEnrollmentSecret(), req);
}