diff --git a/checkstyle-config.xml b/checkstyle-config.xml index cb6875c5..87f23653 100644 --- a/checkstyle-config.xml +++ b/checkstyle-config.xml @@ -52,7 +52,9 @@ + value="^log(ger)?|config|[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/> + diff --git a/src/main/java/org/hyperledger/fabric/sdk/Channel.java b/src/main/java/org/hyperledger/fabric/sdk/Channel.java index b976c7c0..4a02d9ab 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/Channel.java +++ b/src/main/java/org/hyperledger/fabric/sdk/Channel.java @@ -118,9 +118,9 @@ */ public class Channel { private static final Log logger = LogFactory.getLog(Channel.class); - private final static boolean isDebugLevel = logger.isDebugEnabled(); + private static final boolean isDebugLevel = logger.isDebugEnabled(); private static final Config config = Config.getConfig(); - static final String SYSTEM_CHANNEL_NAME = ""; + private static final String SYSTEM_CHANNEL_NAME = ""; // Name of the channel is only meaningful to the client private String name; @@ -165,7 +165,7 @@ ExecutorService getChannelExecutorService() { return executorService; } - Channel(String name, HFClient hfClient, Orderer orderer, ChannelConfiguration channelConfiguration, byte[][] signers) throws InvalidArgumentException, TransactionException { + private Channel(String name, HFClient hfClient, Orderer orderer, ChannelConfiguration channelConfiguration, byte[][] signers) throws InvalidArgumentException, TransactionException { this(name, hfClient, false); logger.debug(format("Creating new channel %s on the Fabric", name)); @@ -229,6 +229,8 @@ ExecutorService getChannelExecutorService() { .setSignature(payloadSignature) .setPayload(payloadByteString).build(); + orderer.setChannel(this); + BroadcastResponse trxResult = orderer.sendTransaction(payloadEnv); if (200 != trxResult.getStatusValue()) { throw new TransactionException(format("New channel %s error. StatusValue %d. Status %s", name, @@ -290,7 +292,7 @@ private Channel(String name, HFClient client, final boolean systemChannel) throw this.systemChannel = systemChannel; if (systemChannel) { - name = SYSTEM_CHANNEL_NAME;///It's special ! + name = SYSTEM_CHANNEL_NAME; ///It's special ! initialized = true; } else { if (Utils.isNullOrEmpty(name)) { @@ -399,10 +401,10 @@ public Channel joinPeer(Peer peer) throws ProposalException { .build(); logger.debug("Getting signed proposal."); - SignedProposal signedProposal = getSignedProposal(joinProposal); + SignedProposal signedProposal = getSignedProposal(transactionContext, joinProposal); logger.debug("Got signed proposal."); - Collection resp = sendProposalToPeers(new ArrayList<>(Arrays.asList(peer)), + Collection resp = sendProposalToPeers(new ArrayList<>(Collections.singletonList(peer)), signedProposal, transactionContext); ProposalResponse pro = resp.iterator().next(); @@ -489,6 +491,7 @@ public Channel addEventHub(EventHub eventHub) throws InvalidArgumentException { /** * Get the peers for this channel. + * * @return the peers. */ public Collection getPeers() { @@ -497,6 +500,7 @@ public Collection getPeers() { /** * Get the deploy wait time in seconds. + * * @return number of seconds. */ public int getDeployWaitTime() { @@ -567,7 +571,7 @@ public Channel initialize() throws InvalidArgumentException, TransactionExceptio } try { - parseConfigBlock();// Parse config block for this channel to get it's information. + parseConfigBlock(); // Parse config block for this channel to get it's information. loadCACertificates(); // put all MSP certs into cryptoSuite @@ -689,13 +693,12 @@ private Block getGenesisBlock(Orderer order) throws TransactionException { .setData(seekInfo.toByteString()) .build(); - byte[] deliverPayload_bytes = deliverPayload.toByteArray(); + byte[] deliverPayloadBytes = deliverPayload.toByteArray(); - byte[] deliver_signature = cryptoSuite.sign(getEnrollment().getKey(), deliverPayload_bytes); Envelope deliverEnvelope = Envelope.newBuilder() - .setSignature(ByteString.copyFrom(deliver_signature)) - .setPayload(ByteString.copyFrom(deliverPayload_bytes)) + .setSignature(ByteString.copyFrom(cryptoSuite.sign(getEnrollment().getKey(), deliverPayloadBytes))) + .setPayload(ByteString.copyFrom(deliverPayloadBytes)) .build(); DeliverResponse[] deliver = order.sendDeliver(deliverEnvelope); @@ -735,7 +738,7 @@ private Block getGenesisBlock(Orderer order) throws TransactionException { throw new TransactionException(format("Getting genesis block time exceeded %s seconds for channel %s", Long.toString(TimeUnit.MILLISECONDS.toSeconds(duration)), name)); } try { - Thread.sleep(200);//try again + Thread.sleep(200); //try again } catch (InterruptedException e) { TransactionException te = new TransactionException("getGenesisBlock thread Sleep", e); logger.warn(te.getMessage(), te); @@ -763,7 +766,7 @@ private Block getGenesisBlock(Orderer order) throws TransactionException { return genesisBlock; } - Map msps = new HashMap<>(); + private Map msps = new HashMap<>(); boolean isSystemChannel() { return systemChannel; @@ -1082,7 +1085,7 @@ private Block getBlockByNumber(final long number) throws TransactionException { } - private Block getLatestBlock(Orderer orderer) throws CryptoException, TransactionException { + private Block getLatestBlock(Orderer orderer) throws CryptoException, TransactionException, InvalidArgumentException { logger.debug(format("getConfigurationBlock for channel %s", name)); @@ -1211,12 +1214,12 @@ public Collection sendInstantiationProposal(InstantiateProposa * * @param instantiateProposalRequest * @param peers + * @return responses from peers. * @throws InvalidArgumentException * @throws ProposalException - * @return responses from peers. */ public Collection sendInstantiationProposal(InstantiateProposalRequest instantiateProposalRequest, - Collection peers) throws InvalidArgumentException, ProposalException { + Collection peers) throws InvalidArgumentException, ProposalException { if (shutdown) { throw new InvalidArgumentException(format("Channel %s has been shutdown.", name)); @@ -1224,6 +1227,9 @@ public Collection sendInstantiationProposal(InstantiateProposa if (null == instantiateProposalRequest) { throw new InvalidArgumentException("sendDeploymentProposal deploymentProposalRequest is null"); } + + instantiateProposalRequest.setSubmitted(); + if (null == peers) { throw new InvalidArgumentException("sendDeploymentProposal peers is null"); } @@ -1235,7 +1241,7 @@ public Collection sendInstantiationProposal(InstantiateProposa } try { - TransactionContext transactionContext = getTransactionContext(); + TransactionContext transactionContext = getTransactionContext(instantiateProposalRequest.getUserContext()); transactionContext.setProposalWaitTime(instantiateProposalRequest.getProposalWaitTime()); InstantiateProposalBuilder instantiateProposalbuilder = InstantiateProposalBuilder.newBuilder(); instantiateProposalbuilder.context(transactionContext); @@ -1248,7 +1254,7 @@ public Collection sendInstantiationProposal(InstantiateProposa instantiateProposalbuilder.setTransientMap(instantiateProposalRequest.getTransientMap()); FabricProposal.Proposal instantiateProposal = instantiateProposalbuilder.build(); - SignedProposal signedProposal = getSignedProposal(instantiateProposal); + SignedProposal signedProposal = getSignedProposal(transactionContext, instantiateProposal); return sendProposalToPeers(peers, signedProposal, transactionContext); } catch (Exception e) { @@ -1256,11 +1262,19 @@ public Collection sendInstantiationProposal(InstantiateProposa } } - private TransactionContext getTransactionContext() { + private TransactionContext getTransactionContext() throws InvalidArgumentException { return getTransactionContext(client.getUserContext()); } - private TransactionContext getTransactionContext(User userContext) { + private TransactionContext getTransactionContext(User userContext) throws InvalidArgumentException { + userContext = userContext != null ? userContext : client.getUserContext(); + if (userContext == null) { + throw new InvalidArgumentException("User context may not be null."); + } + if (cryptoSuite == null) { + throw new InvalidArgumentException("CryptoSuite may not be null."); + } + // return new TransactionContext(this, userContext != null ? client.getUserContext() : userContext, cryptoSuite); return new TransactionContext(this, userContext, cryptoSuite); } @@ -1294,7 +1308,7 @@ Collection sendInstallProposal(InstallProposalRequest installP } try { - TransactionContext transactionContext = getTransactionContext(); + TransactionContext transactionContext = getTransactionContext(installProposalRequest.getUserContext()); transactionContext.verify(false); // Install will have no signing cause it's not really targeted to a channel. transactionContext.setProposalWaitTime(installProposalRequest.getProposalWaitTime()); InstallProposalBuilder installProposalbuilder = InstallProposalBuilder.newBuilder(); @@ -1307,7 +1321,7 @@ Collection sendInstallProposal(InstallProposalRequest installP installProposalbuilder.setChaincodeInputStream(installProposalRequest.getChaincodeInputStream()); FabricProposal.Proposal deploymentProposal = installProposalbuilder.build(); - SignedProposal signedProposal = getSignedProposal(deploymentProposal); + SignedProposal signedProposal = getSignedProposal(transactionContext, deploymentProposal); return sendProposalToPeers(peers, signedProposal, transactionContext); } catch (Exception e) { @@ -1361,7 +1375,7 @@ public Collection sendUpgradeProposal(UpgradeProposalRequest u } try { - TransactionContext transactionContext = getTransactionContext(); + TransactionContext transactionContext = getTransactionContext(upgradeProposalRequest.getUserContext()); //transactionContext.verify(false); // Install will have no signing cause it's not really targeted to a channel. transactionContext.setProposalWaitTime(upgradeProposalRequest.getProposalWaitTime()); UpgradeProposalBuilder upgradeProposalBuilder = UpgradeProposalBuilder.newBuilder(); @@ -1372,7 +1386,7 @@ public Collection sendUpgradeProposal(UpgradeProposalRequest u upgradeProposalBuilder.chaincodeVersion(upgradeProposalRequest.getChaincodeVersion()); upgradeProposalBuilder.chaincodEndorsementPolicy(upgradeProposalRequest.getChaincodeEndorsementPolicy()); - SignedProposal signedProposal = getSignedProposal(upgradeProposalBuilder.build()); + SignedProposal signedProposal = getSignedProposal(transactionContext, upgradeProposalBuilder.build()); return sendProposalToPeers(peers, signedProposal, transactionContext); } catch (Exception e) { @@ -1380,24 +1394,13 @@ public Collection sendUpgradeProposal(UpgradeProposalRequest u } } - private SignedProposal getSignedProposal(FabricProposal.Proposal proposal) throws CryptoException { - byte[] ecdsaSignature = cryptoSuite.sign(getEnrollment().getKey(), proposal.toByteArray()); - SignedProposal.Builder signedProposal = SignedProposal.newBuilder(); - - signedProposal.setProposalBytes(proposal.toByteString()); - - signedProposal.setSignature(ByteString.copyFrom(ecdsaSignature)); - return signedProposal.build(); - } - - private SignedProposal signTransActionEnvelope(FabricProposal.Proposal deploymentProposal) throws CryptoException { - byte[] ecdsaSignature = cryptoSuite.sign(getEnrollment().getKey(), deploymentProposal.toByteArray()); - SignedProposal.Builder signedProposal = SignedProposal.newBuilder(); + private SignedProposal getSignedProposal(TransactionContext transactionContext, FabricProposal.Proposal proposal) throws CryptoException { - signedProposal.setProposalBytes(deploymentProposal.toByteString()); + return SignedProposal.newBuilder() + .setProposalBytes(proposal.toByteString()) + .setSignature(transactionContext.signByteString(proposal.toByteArray())) + .build(); - signedProposal.setSignature(ByteString.copyFrom(ecdsaSignature)); - return signedProposal.build(); } /** @@ -1425,11 +1428,12 @@ public BlockInfo queryBlockByHash(byte[] blockHash) throws InvalidArgumentExcept /** * Query a peer in this channel for a Block by the block hash. - * @param peer the Peer to query. + * + * @param peer the Peer to query. * @param blockHash the hash of the Block in the chain. * @return the {@link BlockInfo} with the given block Hash * @throws InvalidArgumentException if the channel is shutdown or any of the arguments are not valid. - * @throws ProposalException if an error occurred processing the query. + * @throws ProposalException if an error occurred processing the query. */ public BlockInfo queryBlockByHash(Peer peer, byte[] blockHash) throws InvalidArgumentException, ProposalException { @@ -1450,7 +1454,7 @@ public BlockInfo queryBlockByHash(Peer peer, byte[] blockHash) throws InvalidArg BlockInfo responseBlock; try { logger.debug("queryBlockByHash with hash : " + Hex.encodeHexString(blockHash) + "\n to peer " + peer.getName() + " on channel " + name); - QuerySCCRequest querySCCRequest = new QuerySCCRequest(); + QuerySCCRequest querySCCRequest = new QuerySCCRequest(client.getUserContext()); querySCCRequest.setFcn(QuerySCCRequest.GETBLOCKBYHASH); querySCCRequest.setArgs(new String[] {name}); querySCCRequest.setArgBytes(new byte[][] {blockHash}); @@ -1520,7 +1524,7 @@ public BlockInfo queryBlockByNumber(Peer peer, long blockNumber) throws InvalidA BlockInfo responseBlock; try { logger.debug("queryBlockByNumber with blockNumber " + blockNumber + " to peer " + peer.getName() + " on channel " + name); - QuerySCCRequest querySCCRequest = new QuerySCCRequest(); + QuerySCCRequest querySCCRequest = new QuerySCCRequest(client.getUserContext()); querySCCRequest.setFcn(QuerySCCRequest.GETBLOCKBYNUMBER); querySCCRequest.setArgs(new String[] {name, Long.toUnsignedString(blockNumber)}); @@ -1599,7 +1603,7 @@ public BlockInfo queryBlockByTransactionID(Peer peer, String txID) throws Invali BlockInfo responseBlock; try { logger.debug("queryBlockByTransactionID with txID " + txID + " \n to peer" + peer.getName() + " on channel " + name); - QuerySCCRequest querySCCRequest = new QuerySCCRequest(); + QuerySCCRequest querySCCRequest = new QuerySCCRequest(client.getUserContext()); querySCCRequest.setFcn(QuerySCCRequest.GETBLOCKBYTXID); querySCCRequest.setArgs(new String[] {name, txID}); @@ -1670,7 +1674,7 @@ public BlockchainInfo queryBlockchainInfo(Peer peer) throws ProposalException, I BlockchainInfo response; try { logger.debug("queryBlockchainInfo to peer " + peer.getName() + " on channel " + name); - QuerySCCRequest querySCCRequest = new QuerySCCRequest(); + QuerySCCRequest querySCCRequest = new QuerySCCRequest(client.getUserContext()); querySCCRequest.setFcn(QuerySCCRequest.GETCHAININFO); querySCCRequest.setArgs(new String[] {name}); @@ -1748,7 +1752,7 @@ public TransactionInfo queryTransactionByID(Peer peer, String txID) throws Propo TransactionInfo transactionInfo; try { logger.debug("queryTransactionByID with txID " + txID + "\n from peer " + peer.getName() + " on channel " + name); - QuerySCCRequest querySCCRequest = new QuerySCCRequest(); + QuerySCCRequest querySCCRequest = new QuerySCCRequest(client.getUserContext()); querySCCRequest.setFcn(QuerySCCRequest.GETTRANSACTIONBYID); querySCCRequest.setArgs(new String[] {name, txID}); @@ -1792,7 +1796,7 @@ Set queryChannels(Peer peer) throws InvalidArgumentException, ProposalEx FabricProposal.Proposal q = QueryPeerChannelsBuilder.newBuilder().context(context).build(); - SignedProposal qProposal = getSignedProposal(q); + SignedProposal qProposal = getSignedProposal(context, q); Collection proposalResponses = sendProposalToPeers(Collections.singletonList(peer), qProposal, context); if (null == proposalResponses) { @@ -1814,7 +1818,7 @@ Set queryChannels(Peer peer) throws InvalidArgumentException, ProposalEx final Response fabricResponseResponse = fabricResponse.getResponse(); - if (null == fabricResponseResponse) {//not likely but check it. + if (null == fabricResponseResponse) { //not likely but check it. throw new ProposalException(format("Peer %s channel query return with empty fabricResponseResponse", peer.getName())); } @@ -1859,7 +1863,7 @@ List queryInstalledChaincodes(Peer peer) throws InvalidArgumentEx FabricProposal.Proposal q = QueryInstalledChaincodesBuilder.newBuilder().context(context).build(); - SignedProposal qProposal = getSignedProposal(q); + SignedProposal qProposal = getSignedProposal(context, q); Collection proposalResponses = sendProposalToPeers(Collections.singletonList(peer), qProposal, context); if (null == proposalResponses) { @@ -1881,7 +1885,7 @@ List queryInstalledChaincodes(Peer peer) throws InvalidArgumentEx final Response fabricResponseResponse = fabricResponse.getResponse(); - if (null == fabricResponseResponse) {//not likely but check it. + if (null == fabricResponseResponse) { //not likely but check it. throw new ProposalException(format("Peer %s channel query return with empty fabricResponseResponse", peer.getName())); } @@ -1929,7 +1933,7 @@ public List queryInstantiatedChaincodes(Peer peer) throws Invalid FabricProposal.Proposal q = QueryInstantiatedChaincodesBuilder.newBuilder().context(context).build(); - SignedProposal qProposal = getSignedProposal(q); + SignedProposal qProposal = getSignedProposal(context, q); Collection proposalResponses = sendProposalToPeers(Collections.singletonList(peer), qProposal, context); if (null == proposalResponses) { @@ -1951,7 +1955,7 @@ public List queryInstantiatedChaincodes(Peer peer) throws Invalid final Response fabricResponseResponse = fabricResponse.getResponse(); - if (null == fabricResponseResponse) {//not likely but check it. + if (null == fabricResponseResponse) { //not likely but check it. throw new ProposalException(format("Peer %s channel query return with empty fabricResponseResponse", peer.getName())); } @@ -2037,6 +2041,9 @@ private Collection sendProposal(TransactionRequest proposalReq if (null == proposalRequest) { throw new InvalidArgumentException("sendProposal queryProposalRequest is null"); } + + proposalRequest.setSubmitted(); + if (null == peers) { throw new InvalidArgumentException("sendProposal peers is null"); } @@ -2052,7 +2059,7 @@ private Collection sendProposal(TransactionRequest proposalReq } try { - TransactionContext transactionContext = getTransactionContext(); + TransactionContext transactionContext = getTransactionContext(proposalRequest.getUserContext()); transactionContext.verify(proposalRequest.doVerify()); transactionContext.setProposalWaitTime(proposalRequest.getProposalWaitTime()); @@ -2061,7 +2068,7 @@ private Collection sendProposal(TransactionRequest proposalReq proposalBuilder.context(transactionContext); proposalBuilder.request(proposalRequest); - SignedProposal invokeProposal = getSignedProposal(proposalBuilder.build()); + SignedProposal invokeProposal = getSignedProposal(transactionContext, proposalBuilder.build()); return sendProposalToPeers(peers, invokeProposal, transactionContext); } catch (ProposalException e) { throw e; @@ -2118,7 +2125,7 @@ private Pair(Peer peer, Future future) Throwable cause = e.getCause(); if (cause instanceof Error) { String emsg = "Sending proposal to " + peerFuturePair.peer.getName() + " failed because of " + cause.getMessage(); - logger.error(emsg, new Exception(cause));//wrapped in exception to get full stack trace. + logger.error(emsg, new Exception(cause)); //wrapped in exception to get full stack trace. throw (Error) cause; } else { if (cause instanceof StatusRuntimeException) { @@ -2128,7 +2135,7 @@ private Pair(Peer peer, Future future) message = format("Sending proposal to " + peerFuturePair.peer.getName() + " failed because of %s", cause.getMessage()); } status = 500; - logger.error(message, new Exception(cause));//wrapped in exception to get full stack trace. + logger.error(message, new Exception(cause)); //wrapped in exception to get full stack trace. } } @@ -2152,10 +2159,23 @@ private Pair(Peer peer, Future future) // transactions order /** - * Send transaction to one of the orderers on the channel. + * Send transaction to one of the orderers on the channel using a specific user context. * - * @param proposalResponses - * @return a Future allowing access to the result of the transaction invocation. + * @param proposalResponses The proposal responses to be sent to the orderer. + * @param userContext The usercontext used for signing transaction. + * @return a future allowing access to the result of the transaction invocation once complete. + */ + public CompletableFuture sendTransaction(Collection proposalResponses, User userContext) { + + return sendTransaction(proposalResponses, orderers, userContext); + + } + + /** + * Send transaction to one of the orderers on the channel using the usercontext set on the client. + * + * @param proposalResponses . + * @return a future allowing access to the result of the transaction invocation once complete. */ public CompletableFuture sendTransaction(Collection proposalResponses) { @@ -2164,14 +2184,27 @@ public CompletableFuture sendTransaction(Collection sendTransaction(Collection proposalResponses, Collection orderers) { + + return sendTransaction(proposalResponses, orderers, client.getUserContext()); + } + + /** + * Send transaction to one of a specified set of orderers with the specified user context. * * @param proposalResponses * @param orderers * @return Future allowing access to the result of the transaction invocation. */ - public CompletableFuture sendTransaction(Collection proposalResponses, Collection orderers) { + public CompletableFuture sendTransaction(Collection proposalResponses, Collection orderers, User userContext) { try { if (shutdown) { @@ -2189,6 +2222,11 @@ public CompletableFuture sendTransaction(Collection sendTransaction(Collection sret = registerTxListener(proposalTransactionID); logger.debug(format("Channel %s sending transaction to orderer(s) with TxID %s ", name, proposalTransactionID)); @@ -2243,8 +2281,12 @@ public CompletableFuture sendTransaction(Collection sendTransaction(Collection registerTxListener(String txid) { + private CompletableFuture registerTxListener(String txid) { CompletableFuture future = new CompletableFuture<>(); diff --git a/src/main/java/org/hyperledger/fabric/sdk/HFClient.java b/src/main/java/org/hyperledger/fabric/sdk/HFClient.java index 1f5d0b57..1c8a5539 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/HFClient.java +++ b/src/main/java/org/hyperledger/fabric/sdk/HFClient.java @@ -80,6 +80,10 @@ public CryptoSuite getCryptoSuite() { } public void setCryptoSuite(CryptoSuite cryptoSuite) throws CryptoException, InvalidArgumentException { + if (this.cryptoSuite != null) { + throw new InvalidArgumentException("CryptoSuite may only be set once."); + + } this.cryptoSuite = cryptoSuite; this.cryptoSuite.init(); } @@ -111,11 +115,11 @@ public Channel newChannel(String name) throws InvalidArgumentException { /** * Create a new channel * - * @param name The channel's name - * @param orderer Orderer to create the channel with. + * @param name The channel's name + * @param orderer Orderer to create the channel with. * @param channelConfiguration Channel configuration data. * @param channelConfigurationSignatures byte arrays containing ConfigSignature's proto serialized. - * See {@link Channel#getChannelConfigurationSignature} on how to create + * See {@link Channel#getChannelConfigurationSignature} on how to create * @return a new channel. * @throws TransactionException * @throws InvalidArgumentException @@ -195,7 +199,7 @@ public Channel getChannel(String name) { * @return InstallProposalRequest */ public InstallProposalRequest newInstallProposalRequest() { - return new InstallProposalRequest(); + return new InstallProposalRequest(userContext); } /** @@ -205,11 +209,11 @@ public InstallProposalRequest newInstallProposalRequest() { */ public InstantiateProposalRequest newInstantiationProposalRequest() { - return new InstantiateProposalRequest(); + return new InstantiateProposalRequest(userContext); } public UpgradeProposalRequest newUpgradeProposalRequest() { - return new UpgradeProposalRequest(); + return new UpgradeProposalRequest(userContext); } /** @@ -219,7 +223,7 @@ public UpgradeProposalRequest newUpgradeProposalRequest() { */ public TransactionProposalRequest newTransactionProposalRequest() { - return TransactionProposalRequest.newInstance(); + return TransactionProposalRequest.newInstance(userContext); } /** @@ -229,7 +233,7 @@ public TransactionProposalRequest newTransactionProposalRequest() { */ public QueryByChaincodeRequest newQueryProposalRequest() { - return QueryByChaincodeRequest.newInstance(); + return QueryByChaincodeRequest.newInstance(userContext); } /** @@ -468,6 +472,7 @@ public byte[] getChannelConfigurationSignature(ChannelConfiguration channelConfi public Collection sendInstallProposal(InstallProposalRequest installProposalRequest, Collection peers) throws ProposalException, InvalidArgumentException { + installProposalRequest.setSubmitted(); Channel systemChannel = Channel.newSystemChannel(this); return systemChannel.sendInstallProposal(installProposalRequest, peers); diff --git a/src/main/java/org/hyperledger/fabric/sdk/InstallProposalRequest.java b/src/main/java/org/hyperledger/fabric/sdk/InstallProposalRequest.java index 1f75ac66..c80f4389 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/InstallProposalRequest.java +++ b/src/main/java/org/hyperledger/fabric/sdk/InstallProposalRequest.java @@ -4,7 +4,7 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,6 +27,10 @@ public class InstallProposalRequest extends TransactionRequest { private File chaincodeSourceLocation = null; private InputStream chaincodeInputStream = null; + InstallProposalRequest(User userContext) { + super(userContext); + } + public InputStream getChaincodeInputStream() { return chaincodeInputStream; } diff --git a/src/main/java/org/hyperledger/fabric/sdk/InstantiateProposalRequest.java b/src/main/java/org/hyperledger/fabric/sdk/InstantiateProposalRequest.java index bcd2dc63..46fad6d4 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/InstantiateProposalRequest.java +++ b/src/main/java/org/hyperledger/fabric/sdk/InstantiateProposalRequest.java @@ -23,6 +23,10 @@ */ public class InstantiateProposalRequest extends TransactionRequest { + InstantiateProposalRequest(User userContext) { + super(userContext); + } + /** * Transient data added to the proposal that is not added to the ledger. * diff --git a/src/main/java/org/hyperledger/fabric/sdk/Orderer.java b/src/main/java/org/hyperledger/fabric/sdk/Orderer.java index 24b5526f..3e5b5b56 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/Orderer.java +++ b/src/main/java/org/hyperledger/fabric/sdk/Orderer.java @@ -89,7 +89,7 @@ void setChannel(Channel channel) throws InvalidArgumentException { throw new InvalidArgumentException("setChannel Channel can not be null"); } - if (null != this.channel) { + 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())); } @@ -125,7 +125,7 @@ Ab.BroadcastResponse sendTransaction(Common.Envelope transaction) throws Excepti OrdererClient localOrdererClient = ordererClient; if (localOrdererClient == null || !localOrdererClient.isChannelActive()) { - localOrdererClient = ordererClient = new OrdererClient(new Endpoint(url, properties).getChannelBuilder()); + localOrdererClient = ordererClient = new OrdererClient(this, new Endpoint(url, properties).getChannelBuilder()); } try { @@ -160,7 +160,7 @@ DeliverResponse[] sendDeliver(Common.Envelope transaction) throws TransactionExc logger.debug(format("Order.sendDeliver name: %s, url: %s", name, url)); if (localOrdererClient == null || !localOrdererClient.isChannelActive()) { - ordererClient =localOrdererClient = new OrdererClient(new Endpoint(url, properties).getChannelBuilder()); + ordererClient = localOrdererClient = new OrdererClient(this, new Endpoint(url, properties).getChannelBuilder()); } try { diff --git a/src/main/java/org/hyperledger/fabric/sdk/OrdererClient.java b/src/main/java/org/hyperledger/fabric/sdk/OrdererClient.java index aa4714e8..a7d5a530 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/OrdererClient.java +++ b/src/main/java/org/hyperledger/fabric/sdk/OrdererClient.java @@ -30,21 +30,28 @@ import org.hyperledger.fabric.protos.orderer.AtomicBroadcastGrpc; import org.hyperledger.fabric.sdk.exception.TransactionException; +import static java.lang.String.format; import static org.hyperledger.fabric.protos.orderer.Ab.DeliverResponse.TypeCase.STATUS; /** * Sample client code that makes gRPC calls to the server. */ class OrdererClient { + private final String channelName; boolean shutdown = false; private static final Log logger = LogFactory.getLog(OrdererClient.class); private ManagedChannel managedChannel; + private final String name; + private final String url; /** * Construct client for accessing Orderer server using the existing managedChannel. */ - OrdererClient(ManagedChannelBuilder channelBuilder) { + OrdererClient(Orderer orderer, ManagedChannelBuilder channelBuilder) { managedChannel = channelBuilder.build(); + name = orderer.getName(); + url = orderer.getUrl(); + channelName = orderer.getChannel().getName(); } synchronized void shutdown(boolean force) { @@ -105,6 +112,10 @@ public void onNext(Ab.BroadcastResponse resp) { @Override public void onError(Throwable t) { + if (!shutdown) { + logger.error(format("Received error on channel %s, orderer %s, url %s, %s", + channelName, name, url, t.getMessage()), t); + } throwable[0] = t; finishLatch.countDown(); } @@ -122,7 +133,7 @@ public void onCompleted() { //nso.onCompleted(); try { - if(!finishLatch.await(2, TimeUnit.MINUTES)){ + if (!finishLatch.await(2, TimeUnit.MINUTES)) { TransactionException ste = new TransactionException("Send transactions failed. Reason: timeout"); logger.error("sendTransaction error " + ste.getMessage(), ste); throw ste; @@ -187,7 +198,8 @@ public void onNext(DeliverResponse resp) { @Override public void onError(Throwable t) { if (!shutdown) { - logger.error("broadcast error " + t); + logger.error(format("Received error on channel %s, orderer %s, url %s, %s", + channelName, name, url, t.getMessage()), t); } throwableList.add(t); finishLatch.countDown(); @@ -205,10 +217,10 @@ public void onCompleted() { //nso.onCompleted(); try { - if(!finishLatch.await(2, TimeUnit.MINUTES)){ + if (!finishLatch.await(2, TimeUnit.MINUTES)) { TransactionException ex = new TransactionException("sendDeliver time exceeded for orderer"); - logger.error(ex.getMessage(),ex); - throw ex; + logger.error(ex.getMessage(), ex); + throw ex; } logger.trace("Done waiting for reply!"); @@ -226,8 +238,8 @@ public void onCompleted() { return retList.toArray(new DeliverResponse[retList.size()]); } - boolean isChannelActive(){ + boolean isChannelActive() { ManagedChannel lchannel = managedChannel; - return lchannel != null && !lchannel.isShutdown() && ! lchannel.isTerminated(); + return lchannel != null && !lchannel.isShutdown() && !lchannel.isTerminated(); } } diff --git a/src/main/java/org/hyperledger/fabric/sdk/QueryByChaincodeRequest.java b/src/main/java/org/hyperledger/fabric/sdk/QueryByChaincodeRequest.java index 12eaa9bf..868a2214 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/QueryByChaincodeRequest.java +++ b/src/main/java/org/hyperledger/fabric/sdk/QueryByChaincodeRequest.java @@ -18,11 +18,12 @@ import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; public class QueryByChaincodeRequest extends TransactionRequest { - private QueryByChaincodeRequest() { + private QueryByChaincodeRequest(User userContext) { + super(userContext); } - public static QueryByChaincodeRequest newInstance() { - return new QueryByChaincodeRequest(); + public static QueryByChaincodeRequest newInstance(User userContext) { + return new QueryByChaincodeRequest(userContext); } /** diff --git a/src/main/java/org/hyperledger/fabric/sdk/QuerySCCRequest.java b/src/main/java/org/hyperledger/fabric/sdk/QuerySCCRequest.java index 505942f7..f6c0a1fd 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/QuerySCCRequest.java +++ b/src/main/java/org/hyperledger/fabric/sdk/QuerySCCRequest.java @@ -27,6 +27,10 @@ public class QuerySCCRequest extends TransactionRequest { public static final String GETTRANSACTIONBYID = "GetTransactionByID"; public static final String GETBLOCKBYTXID = "GetBlockByTxID"; + public QuerySCCRequest(User userContext) { + super(userContext); + } + @Override public ChaincodeID getChaincodeID() { return new ChaincodeID( diff --git a/src/main/java/org/hyperledger/fabric/sdk/TransactionProposalRequest.java b/src/main/java/org/hyperledger/fabric/sdk/TransactionProposalRequest.java index b7e28823..db78ad31 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/TransactionProposalRequest.java +++ b/src/main/java/org/hyperledger/fabric/sdk/TransactionProposalRequest.java @@ -18,12 +18,13 @@ import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; public class TransactionProposalRequest extends TransactionRequest { - private TransactionProposalRequest() { + TransactionProposalRequest(User userContext) { + super(userContext); } - public static TransactionProposalRequest newInstance() { - return new TransactionProposalRequest(); + public static TransactionProposalRequest newInstance(User userContext) { + return new TransactionProposalRequest(userContext); } diff --git a/src/main/java/org/hyperledger/fabric/sdk/TransactionRequest.java b/src/main/java/org/hyperledger/fabric/sdk/TransactionRequest.java index 06072f9d..292a8e7d 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/TransactionRequest.java +++ b/src/main/java/org/hyperledger/fabric/sdk/TransactionRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 DTCC, Fujitsu Australia Software Technology - All Rights Reserved. + * Copyright 2016, 2017 DTCC, Fujitsu Australia Software Technology, IBM - All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,16 @@ import java.util.Arrays; import java.util.Map; +import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; import org.hyperledger.fabric.sdk.helper.Config; /** * A base transaction request common for InstallProposalRequest,trRequest, and QueryRequest. */ public class TransactionRequest { + private User userContext; + + boolean submitted = false; private final Config config = Config.getConfig(); @@ -53,6 +57,26 @@ public class TransactionRequest { protected Map transientMap; + /** + * The user context to use on this request. + * + * + * @return User context that is used for signing + */ + User getUserContext() { + return userContext; + } + + /** + * Set the user context for this request. This context will override the user context set + * on {@link HFClient#setUserContext(User)} + * + * @param userContext The user context for this request used for signing. + */ + public void setUserContext(User userContext) { + this.userContext = userContext; + } + /** * Transient data added to the proposal that is not added to the ledger. * @@ -71,7 +95,7 @@ public Map getTransientMap() { * This implementation returns {@code false}. * * @return {@code true} if an empty channel ID should be used; otherwise - * {@code false}. + * {@code false}. */ public boolean noChannelID() { return false; @@ -237,4 +261,26 @@ public void setProposalWaitTime(long proposalWaitTime) { this.proposalWaitTime = proposalWaitTime; } + /** + * If this request has been submitted already. + * + * @return true if the already submitted. + */ + + public boolean isSubmitted() { + return submitted; + } + + void setSubmitted() throws InvalidArgumentException { + if (submitted) { + // Has already been submitted. + throw new InvalidArgumentException("Request has been already submitted and can not be reused."); + } + this.submitted = true; + } + + protected TransactionRequest(User userContext) { + this.userContext = userContext; + } + } diff --git a/src/main/java/org/hyperledger/fabric/sdk/UpgradeProposalRequest.java b/src/main/java/org/hyperledger/fabric/sdk/UpgradeProposalRequest.java index 40c3341c..7215a963 100644 --- a/src/main/java/org/hyperledger/fabric/sdk/UpgradeProposalRequest.java +++ b/src/main/java/org/hyperledger/fabric/sdk/UpgradeProposalRequest.java @@ -23,6 +23,10 @@ */ public class UpgradeProposalRequest extends TransactionRequest { + UpgradeProposalRequest(User userContext) { + super(userContext); + } + /** * Transient data added to the proposal that is not added to the ledger. * diff --git a/src/main/proto/orderer/configuration.proto b/src/main/proto/orderer/configuration.proto index f627a0fb..9925ca63 100644 --- a/src/main/proto/orderer/configuration.proto +++ b/src/main/proto/orderer/configuration.proto @@ -35,13 +35,13 @@ message ConsensusType { message BatchSize { // Simply specified as number of messages for now, in the future // we may want to allow this to be specified by size in bytes - uint32 maxMessageCount = 1; + uint32 max_message_count = 1; // The byte count of the serialized messages in a batch cannot // exceed this value. - uint32 absoluteMaxBytes = 2; + uint32 absolute_max_bytes = 2; // The byte count of the serialized messages in a batch should not // exceed this value. - uint32 preferredMaxBytes = 3; + uint32 preferred_max_bytes = 3; } message BatchTimeout { diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java index 4de9ea5d..5326e003 100644 --- a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java +++ b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endAndBackAgainIT.java @@ -41,6 +41,7 @@ import org.hyperledger.fabric.sdk.TestConfigHelper; import org.hyperledger.fabric.sdk.TransactionProposalRequest; import org.hyperledger.fabric.sdk.UpgradeProposalRequest; +import org.hyperledger.fabric.sdk.User; import org.hyperledger.fabric.sdk.exception.InvalidArgumentException; import org.hyperledger.fabric.sdk.exception.ProposalException; import org.hyperledger.fabric.sdk.exception.TransactionEventException; @@ -183,6 +184,9 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int final String channelName = channel.getName(); try { +// final boolean changeContext = false; // BAR_CHANNEL_NAME.equals(channel.getName()) ? true : false; + final boolean changeContext = BAR_CHANNEL_NAME.equals(channel.getName()) ? true : false; + out("Running Channel %s with a delta %d", channelName, delta); channel.setTransactionWaitTime(testConfig.getTransactionWaitTime()); channel.setDeployWaitTime(testConfig.getDeployWaitTime()); @@ -192,9 +196,15 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int // queryChaincodeForExpectedValue(client, channel, "" + (300 + delta), chaincodeID); + //Set user context on client but use explicit user contest on each call. + if (changeContext) { + client.setUserContext(sampleOrg.getUser(TESTUSER_1_NAME)); + + } + // exercise v1 of chaincode - moveAmount(client, channel, chaincodeID, "25").thenApply(transactionEvent -> { + moveAmount(client, channel, chaincodeID, "25", changeContext ? sampleOrg.getPeerAdmin() : null).thenApply(transactionEvent -> { try { waitOnFabric(); @@ -213,7 +223,11 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int installProposalRequest.setChaincodeVersion(CHAIN_CODE_VERSION_11); installProposalRequest.setProposalWaitTime(testConfig.getProposalWaitTime()); - out("Sending install proposal"); + if (changeContext) { + installProposalRequest.setUserContext(sampleOrg.getPeerAdmin()); + } + + out("Sending install proposal for channel: %s", channel.getName()); //////////////////////////// // only a client from the same org as the peer can issue an install request @@ -236,13 +250,6 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int } } - // Check that all the proposals are consistent with each other. We should have only one set - // where all the proposals above are consistent. - Collection> proposalConsistencySets = SDKUtils.getProposalConsistencySets(responses); - if (proposalConsistencySets.size() != 1) { - fail(format("Expected only one set of consistent install proposal responses but got %d", proposalConsistencySets.size())); - } - out("Received %d install proposal responses. Successful+verified: %d . Failed: %d", numInstallProposal, successful.size(), failed.size()); if (failed.size() > 0) { @@ -250,9 +257,20 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int fail("Not enough endorsers for install :" + successful.size() + ". " + first.getMessage()); } + // Check that all the proposals are consistent with each other. We should have only one set + // where all the proposals above are consistent. + Collection> proposalConsistencySets = SDKUtils.getProposalConsistencySets(responses); + if (proposalConsistencySets.size() != 1) { + fail(format("Expected only one set of consistent install proposal responses but got %d", proposalConsistencySets.size())); + } + ////////////////// // Upgrade chaincode to ***double*** our move results. + if (changeContext) { + installProposalRequest.setUserContext(sampleOrg.getPeerAdmin()); + } + UpgradeProposalRequest upgradeProposalRequest = client.newUpgradeProposalRequest(); upgradeProposalRequest.setChaincodeID(chaincodeID_11); upgradeProposalRequest.setProposalWaitTime(testConfig.getProposalWaitTime()); @@ -266,6 +284,10 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int upgradeProposalRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy); + if (changeContext) { + upgradeProposalRequest.setUserContext(sampleOrg.getPeerAdmin()); + } + out("Sending upgrade proposal"); Collection responses2; @@ -283,6 +305,14 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int } } + out("Received %d upgrade proposal responses. Successful+verified: %d . Failed: %d", channel.getPeers().size(), successful.size(), failed.size()); + + if (failed.size() > 0) { + ProposalResponse first = failed.iterator().next(); + throw new AssertionError("Not enough endorsers for upgrade :" + + successful.size() + ". " + first.getMessage()); + } + // Check that all the proposals are consistent with each other. We should have only one set // where the proposals above are consistent. proposalConsistencySets = SDKUtils.getProposalConsistencySets(responses2); @@ -290,15 +320,14 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int fail(format("Expected only one set of consistent upgrade proposal responses but got %d", proposalConsistencySets.size())); } - out("Received %d upgrade proposal responses. Successful+verified: %d . Failed: %d", channel.getPeers().size(), successful.size(), failed.size()); + if (changeContext) { + return channel.sendTransaction(successful, sampleOrg.getPeerAdmin()).get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS); - if (failed.size() > 0) { - ProposalResponse first = failed.iterator().next(); - throw new AssertionError("Not enough endorsers for upgrade :" - + successful.size() + ". " + first.getMessage()); - } + } else { + + return channel.sendTransaction(successful).get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS); - return channel.sendTransaction(successful).get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS); + } } catch (CompletionException e) { throw e; @@ -313,6 +342,8 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int out("Chaincode has been upgraded to version %s", CHAIN_CODE_VERSION_11); //Check to see if peers have new chaincode and old chaincode is gone. + + client.setUserContext(sampleOrg.getPeerAdmin()); for (Peer peer : channel.getPeers()) { if (!checkInstalledChaincode(client, peer, CHAIN_CODE_NAME, CHAIN_CODE_PATH, CHAIN_CODE_VERSION_11)) { @@ -337,12 +368,19 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int client.setUserContext(sampleOrg.getUser(TESTUSER_1_NAME)); +// +// if( !changeContext ){ +// +// client.setUserContext(sampleOrg.getUser(TESTUSER_1_NAME)); +// } + ///Check if we still get the same value on the ledger out("delta is %s", delta); queryChaincodeForExpectedValue(client, channel, "" + (325 + delta), chaincodeID); //Now lets run the new chaincode which should *double* the results we asked to move. - return moveAmount(client, channel, chaincodeID_11, "50").get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS); // really move 100 + return moveAmount(client, channel, chaincodeID_11, "50", + changeContext ? sampleOrg.getPeerAdmin() : null).get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS); // really move 100 } catch (CompletionException e) { throw e; } catch (Exception e) { @@ -363,9 +401,13 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int if (e instanceof TransactionEventException) { BlockEvent.TransactionEvent te = ((TransactionEventException) e).getTransactionEvent(); if (te != null) { + + e.printStackTrace(System.err); fail(format("Transaction with txid %s failed. %s", te.getTransactionID(), e.getMessage())); } } + + e.printStackTrace(System.err); fail(format("Test failed with %s exception %s", e.getClass().getName(), e.getMessage())); return null; @@ -377,7 +419,7 @@ void runChannel(HFClient client, Channel channel, SampleOrg sampleOrg, final int } - CompletableFuture moveAmount(HFClient client, Channel channel, ChaincodeID chaincodeID, String moveAmount) { + CompletableFuture moveAmount(HFClient client, Channel channel, ChaincodeID chaincodeID, String moveAmount, User user) { try { Collection successful = new LinkedList<>(); @@ -390,6 +432,9 @@ CompletableFuture moveAmount(HFClient client, Chann transactionProposalRequest.setFcn("invoke"); transactionProposalRequest.setArgs(new String[] {"move", "a", "b", moveAmount}); transactionProposalRequest.setProposalWaitTime(testConfig.getProposalWaitTime()); + if (user != null) { // specific user use that + transactionProposalRequest.setUserContext(user); + } out("sending transaction proposal to all peers with arguments: move(a,b,%s)", moveAmount); Collection invokePropResp = channel.sendTransactionProposal(transactionProposalRequest, channel.getPeers()); @@ -423,6 +468,9 @@ CompletableFuture moveAmount(HFClient client, Chann //////////////////////////// // Send transaction to orderer out("Sending chaincode transaction(move a,b,%s) to orderer.", moveAmount); + if (user != null) { + return channel.sendTransaction(successful, user); + } return channel.sendTransaction(successful); } catch (Exception e) { @@ -532,6 +580,8 @@ private void waitOnFabric(int additional) { } private static boolean checkInstalledChaincode(HFClient client, Peer peer, String cc_name, String cc_path, String cc_version) throws InvalidArgumentException, ProposalException { + + out("Checking installed chaincode: %s, at version: %s, on peer: %s", cc_name, cc_version, peer.getName()); List ccinfoList = client.queryInstalledChaincodes(peer); boolean found = false; @@ -549,6 +599,7 @@ private static boolean checkInstalledChaincode(HFClient client, Peer peer, Strin } private static boolean checkInstantiatedChaincode(Channel channel, Peer peer, String cc_name, String cc_path, String cc_version) throws InvalidArgumentException, ProposalException { + out("Checking instantiated chaincode: %s, at version: %s, on peer: %s", cc_name, cc_version, peer.getName()); List ccinfoList = channel.queryInstantiatedChaincodes(peer); boolean found = false; diff --git a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java index 438680d2..6caf91b6 100644 --- a/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java +++ b/src/test/java/org/hyperledger/fabric/sdkintegration/End2endIT.java @@ -178,6 +178,8 @@ public void setup() { final String sampleOrgName = sampleOrg.getName(); final String sampleOrgDomainName = sampleOrg.getDomainName(); + // src/test/fixture/sdkintegration/e2e-2Orgs/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/ + SampleUser peerOrgAdmin = sampleStore.getMember(sampleOrgName + "Admin", sampleOrgName, sampleOrg.getMSPID(), findFile_sk(Paths.get(testConfig.getTestChannlePath(), "crypto-config/peerOrganizations/", sampleOrgDomainName, format("/users/Admin@%s/msp/keystore", sampleOrgDomainName)).toFile()), @@ -201,6 +203,7 @@ sampleOrgDomainName, format("/users/Admin@%s/msp/keystore", sampleOrgDomainName) runChannel(client, barChannel, true, sampleOrg, 100); //run a newly constructed bar channel with different b value! //let bar channel just shutdown so we have both scenarios. + out("\nTraverse the blocks for chain %s ", barChannel.getName()); blockWalker(barChannel); out("That's all folks!"); @@ -549,8 +552,9 @@ private Channel constructChannel(String name, HFClient client, SampleOrg sampleO Properties ordererProperties = testConfig.getOrdererProperties(orderName); //example of setting keepAlive to avoid timeouts on inactive http2 connections. - //calls: NettyChannelBuilder.enableKeepAlive(true, 1, TimeUnit.SECONDS, 1, TimeUnit.SECONDS); - ordererProperties.put("grpc.NettyChannelBuilderOption.enableKeepAlive", new Object[] {true, 1L, TimeUnit.SECONDS, 1L, TimeUnit.SECONDS}); + // Under 5 minutes would require changes to server side to accept faster ping rates. + ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES}); + ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS}); orderers.add(client.newOrderer(orderName, sampleOrg.getOrdererLocation(orderName), ordererProperties)); @@ -592,8 +596,14 @@ private Channel constructChannel(String name, HFClient client, SampleOrg sampleO } for (String eventHubName : sampleOrg.getEventHubNames()) { + + final Properties eventHubProperties = testConfig.getEventHubProperties(eventHubName); + + eventHubProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES}); + eventHubProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS}); + EventHub eventHub = client.newEventHub(eventHubName, sampleOrg.getEventHubLocation(eventHubName), - testConfig.getEventHubProperties(eventHubName)); + eventHubProperties); newChannel.addEventHub(eventHub); }