use of org.hyperledger.fabric.sdk.BlockEvent.TransactionEvent in project fabric-sdk-java by hyperledger.
the class Channel method registerChaincodeListenerProcessor.
// //////////////////////////////////////////////////////////////////////
// ////////////// Chaincode Events.. //////////////////////////////////
private String registerChaincodeListenerProcessor() throws InvalidArgumentException {
logger.debug(format("Channel %s registerChaincodeListenerProcessor starting", name));
return registerBlockListener(blockEvent -> {
if (chainCodeListeners.isEmpty()) {
return;
}
LinkedList<ChaincodeEvent> chaincodeEvents = new LinkedList<>();
for (TransactionEvent transactionEvent : blockEvent.getTransactionEvents()) {
logger.debug(format("Channel %s got event for transaction %s ", name, transactionEvent.getTransactionID()));
for (BlockInfo.TransactionEnvelopeInfo.TransactionActionInfo info : transactionEvent.getTransactionActionInfos()) {
ChaincodeEvent event = info.getEvent();
if (null != event) {
chaincodeEvents.add(event);
}
}
}
if (!chaincodeEvents.isEmpty()) {
class MatchPair {
final ChaincodeEventListenerEntry eventListener;
final ChaincodeEvent event;
MatchPair(ChaincodeEventListenerEntry eventListener, ChaincodeEvent event) {
this.eventListener = eventListener;
this.event = event;
}
}
// Find matches.
List<MatchPair> matches = new LinkedList<MatchPair>();
synchronized (chainCodeListeners) {
for (ChaincodeEventListenerEntry chaincodeEventListenerEntry : chainCodeListeners.values()) {
for (ChaincodeEvent chaincodeEvent : chaincodeEvents) {
if (chaincodeEventListenerEntry.isMatch(chaincodeEvent)) {
matches.add(new MatchPair(chaincodeEventListenerEntry, chaincodeEvent));
}
}
}
}
// fire events
for (MatchPair match : matches) {
ChaincodeEventListenerEntry chaincodeEventListenerEntry = match.eventListener;
ChaincodeEvent ce = match.event;
chaincodeEventListenerEntry.fire(blockEvent, ce);
}
}
});
}
use of org.hyperledger.fabric.sdk.BlockEvent.TransactionEvent in project fabric-sdk-java by hyperledger.
the class Channel method registerTransactionListenerProcessor.
/**
* Own block listener to manage transactions.
*
* @return
*/
private String registerTransactionListenerProcessor() throws InvalidArgumentException {
logger.debug(format("Channel %s registerTransactionListenerProcessor starting", name));
return registerBlockListener(blockEvent -> {
if (txListeners.isEmpty()) {
return;
}
for (TransactionEvent transactionEvent : blockEvent.getTransactionEvents()) {
logger.debug(format("Channel %s got event for transaction %s ", name, transactionEvent.getTransactionID()));
List<TL> txL = new ArrayList<>(txListeners.size() + 2);
synchronized (txListeners) {
LinkedList<TL> list = txListeners.get(transactionEvent.getTransactionID());
if (null != list) {
txL.addAll(list);
}
}
for (TL l : txL) {
try {
// if (getEventHubs().containsAll(l.eventReceived(transactionEvent.getEventHub()))) {
if (l.eventReceived(transactionEvent)) {
l.fire(transactionEvent);
}
} catch (Throwable e) {
// Don't let one register stop rest.
logger.error(e);
}
}
}
});
}
use of org.hyperledger.fabric.sdk.BlockEvent.TransactionEvent in project fabric-sdk-java by hyperledger.
the class NetworkConfigIT method deployChaincode.
private static ChaincodeID deployChaincode(HFClient client, Channel channel, String ccName, String ccPath, String ccVersion) throws Exception {
out("deployChaincode - enter");
ChaincodeID chaincodeID = null;
try {
final String channelName = channel.getName();
out("deployChaincode - channelName = " + channelName);
Collection<Orderer> orderers = channel.getOrderers();
Collection<ProposalResponse> responses;
Collection<ProposalResponse> successful = new LinkedList<>();
Collection<ProposalResponse> failed = new LinkedList<>();
chaincodeID = ChaincodeID.newBuilder().setName(ccName).setVersion(ccVersion).setPath(ccPath).build();
// //////////////////////////
// Install Proposal Request
//
out("Creating install proposal");
InstallProposalRequest installProposalRequest = client.newInstallProposalRequest();
installProposalRequest.setChaincodeID(chaincodeID);
// //For GO language and serving just a single user, chaincodeSource is mostly likely the users GOPATH
installProposalRequest.setChaincodeSourceLocation(new File(TEST_FIXTURES_PATH + "/sdkintegration/gocc/sample1"));
installProposalRequest.setChaincodeVersion(ccVersion);
out("Sending install proposal");
// //////////////////////////
// only a client from the same org as the peer can issue an install request
int numInstallProposal = 0;
Collection<Peer> peersFromOrg = channel.getPeers();
numInstallProposal = numInstallProposal + peersFromOrg.size();
responses = client.sendInstallProposal(installProposalRequest, peersFromOrg);
for (ProposalResponse response : responses) {
if (response.getStatus() == ProposalResponse.Status.SUCCESS) {
out("Successful install proposal response Txid: %s from peer %s", response.getTransactionID(), response.getPeer().getName());
successful.add(response);
} else {
failed.add(response);
}
}
out("Received %d install proposal responses. Successful+verified: %d . Failed: %d", numInstallProposal, successful.size(), failed.size());
if (failed.size() > 0) {
ProposalResponse first = failed.iterator().next();
fail("Not enough endorsers for install :" + successful.size() + ". " + first.getMessage());
}
// /////////////
// // Instantiate chaincode.
//
// From the docs:
// The instantiate transaction invokes the lifecycle System Chaincode (LSCC) to create and initialize a chaincode on a channel
// After being successfully instantiated, the chaincode enters the active state on the channel and is ready to process any transaction proposals of type ENDORSER_TRANSACTION
InstantiateProposalRequest instantiateProposalRequest = client.newInstantiationProposalRequest();
instantiateProposalRequest.setProposalWaitTime(testConfig.getProposalWaitTime());
instantiateProposalRequest.setChaincodeID(chaincodeID);
instantiateProposalRequest.setFcn("init");
instantiateProposalRequest.setArgs("a", "500", "b", "999");
Map<String, byte[]> tm = new HashMap<>();
tm.put("HyperLedgerFabric", "InstantiateProposalRequest:JavaSDK".getBytes(UTF_8));
tm.put("method", "InstantiateProposalRequest".getBytes(UTF_8));
instantiateProposalRequest.setTransientMap(tm);
/*
policy OR(Org1MSP.member, Org2MSP.member) meaning 1 signature from someone in either Org1 or Org2
See README.md Chaincode endorsement policies section for more details.
*/
ChaincodeEndorsementPolicy chaincodeEndorsementPolicy = new ChaincodeEndorsementPolicy();
chaincodeEndorsementPolicy.fromYamlFile(new File(TEST_FIXTURES_PATH + "/sdkintegration/chaincodeendorsementpolicy.yaml"));
instantiateProposalRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
out("Sending instantiateProposalRequest to all peers...");
successful.clear();
failed.clear();
responses = channel.sendInstantiationProposal(instantiateProposalRequest);
for (ProposalResponse response : responses) {
if (response.isVerified() && response.getStatus() == ProposalResponse.Status.SUCCESS) {
successful.add(response);
out("Succesful instantiate proposal response Txid: %s from peer %s", response.getTransactionID(), response.getPeer().getName());
} else {
failed.add(response);
}
}
out("Received %d instantiate proposal responses. Successful+verified: %d . Failed: %d", responses.size(), successful.size(), failed.size());
if (failed.size() > 0) {
ProposalResponse first = failed.iterator().next();
fail("Not enough endorsers for instantiate :" + successful.size() + "endorser failed with " + first.getMessage() + ". Was verified:" + first.isVerified());
}
// /////////////
// / Send instantiate transaction to orderer
out("Sending instantiateTransaction to orderer...");
CompletableFuture<TransactionEvent> future = channel.sendTransaction(successful, orderers);
out("calling get...");
TransactionEvent event = future.get(30, TimeUnit.SECONDS);
out("get done...");
// must be valid to be here.
assertTrue(event.isValid());
out("Finished instantiate transaction with transaction id %s", event.getTransactionID());
} catch (Exception e) {
e.printStackTrace();
out("Caught an exception running channel %s", channel.getName());
fail("Test failed with error : " + e.getMessage());
}
return chaincodeID;
}
use of org.hyperledger.fabric.sdk.BlockEvent.TransactionEvent in project fabric-sdk-java by hyperledger.
the class NetworkConfigIT method testUpdate1.
@Test
public void testUpdate1() throws Exception {
// Setup client and channel instances
HFClient client = getTheClient();
Channel channel = constructChannel(client, FOO_CHANNEL_NAME);
final ChaincodeID chaincodeID = ChaincodeID.newBuilder().setName(CHAIN_CODE_NAME).setVersion(CHAIN_CODE_VERSION).setPath(CHAIN_CODE_PATH).build();
final String channelName = channel.getName();
out("Running testUpdate1 - Channel %s", channelName);
int moveAmount = 5;
String originalVal = queryChaincodeForCurrentValue(client, channel, chaincodeID);
String newVal = "" + (Integer.parseInt(originalVal) + moveAmount);
out("Original value = %s", originalVal);
// Move some assets
moveAmount(client, channel, chaincodeID, "a", "b", "" + moveAmount, null).thenApply(transactionEvent -> {
// Check that they were moved
queryChaincodeForExpectedValue(client, channel, newVal, chaincodeID);
return null;
}).thenApply(transactionEvent -> {
// Move them back
try {
return moveAmount(client, channel, chaincodeID, "b", "a", "" + moveAmount, null).get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS);
} catch (Exception e) {
throw new RuntimeException(e);
}
}).thenApply(transactionEvent -> {
// Check that they were moved back
queryChaincodeForExpectedValue(client, channel, originalVal, chaincodeID);
return null;
}).exceptionally(e -> {
if (e instanceof CompletionException && e.getCause() != null) {
e = e.getCause();
}
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;
}).get(testConfig.getTransactionWaitTime(), TimeUnit.SECONDS);
// Force channel to shutdown clean up resources.
channel.shutdown(true);
out("testUpdate1 - done");
}
use of org.hyperledger.fabric.sdk.BlockEvent.TransactionEvent in project fabric-sdk-java by hyperledger.
the class Channel method sendTransaction.
/**
* Send transaction to one of a specified set of orderers with the specified user context.
* IF there are no event hubs or eventing peers this future returns immediately completed
* indicating that orderer has accepted the transaction only.
*
* @param proposalResponses
* @param transactionOptions
* @return Future allowing access to the result of the transaction invocation.
*/
public CompletableFuture<TransactionEvent> sendTransaction(Collection<ProposalResponse> proposalResponses, TransactionOptions transactionOptions) {
try {
if (null == transactionOptions) {
throw new InvalidArgumentException("Parameter transactionOptions can't be null");
}
checkChannelState();
User userContext = transactionOptions.userContext != null ? transactionOptions.userContext : client.getUserContext();
userContextCheck(userContext);
if (null == proposalResponses) {
throw new InvalidArgumentException("sendTransaction proposalResponses was null");
}
List<Orderer> orderers = transactionOptions.orderers != null ? transactionOptions.orderers : new ArrayList<>(getOrderers());
// make certain we have our own copy
final List<Orderer> shuffeledOrderers = new ArrayList<>(orderers);
if (transactionOptions.shuffleOrders) {
Collections.shuffle(shuffeledOrderers);
}
if (config.getProposalConsistencyValidation()) {
HashSet<ProposalResponse> invalid = new HashSet<>();
int consistencyGroups = SDKUtils.getProposalConsistencySets(proposalResponses, invalid).size();
if (consistencyGroups != 1 || !invalid.isEmpty()) {
throw new IllegalArgumentException(format("The proposal responses have %d inconsistent groups with %d that are invalid." + " Expected all to be consistent and none to be invalid.", consistencyGroups, invalid.size()));
}
}
List<FabricProposalResponse.Endorsement> ed = new LinkedList<>();
FabricProposal.Proposal proposal = null;
ByteString proposalResponsePayload = null;
String proposalTransactionID = null;
for (ProposalResponse sdkProposalResponse : proposalResponses) {
ed.add(sdkProposalResponse.getProposalResponse().getEndorsement());
if (proposal == null) {
proposal = sdkProposalResponse.getProposal();
proposalTransactionID = sdkProposalResponse.getTransactionID();
proposalResponsePayload = sdkProposalResponse.getProposalResponse().getPayload();
}
}
TransactionBuilder transactionBuilder = TransactionBuilder.newBuilder();
Payload transactionPayload = transactionBuilder.chaincodeProposal(proposal).endorsements(ed).proposalResponsePayload(proposalResponsePayload).build();
Envelope transactionEnvelope = createTransactionEnvelope(transactionPayload, userContext);
NOfEvents nOfEvents = transactionOptions.nOfEvents;
if (nOfEvents == null) {
nOfEvents = NOfEvents.createNofEvents();
Collection<Peer> eventingPeers = getEventingPeers();
boolean anyAdded = false;
if (!eventingPeers.isEmpty()) {
anyAdded = true;
nOfEvents.addPeers(eventingPeers);
}
Collection<EventHub> eventHubs = getEventHubs();
if (!eventHubs.isEmpty()) {
anyAdded = true;
nOfEvents.addEventHubs(getEventHubs());
}
if (!anyAdded) {
nOfEvents = NOfEvents.createNoEvents();
}
} else if (nOfEvents != NOfEvents.nofNoEvents) {
StringBuilder issues = new StringBuilder(100);
Collection<Peer> eventingPeers = getEventingPeers();
nOfEvents.unSeenPeers().forEach(peer -> {
if (peer.getChannel() != this) {
issues.append(format("Peer %s added to NOFEvents does not belong this channel. ", peer.getName()));
} else if (!eventingPeers.contains(peer)) {
issues.append(format("Peer %s added to NOFEvents is not a eventing Peer in this channel. ", peer.getName()));
}
});
nOfEvents.unSeenEventHubs().forEach(eventHub -> {
if (!eventHubs.contains(eventHub)) {
issues.append(format("Eventhub %s added to NOFEvents does not belong this channel. ", eventHub.getName()));
}
});
if (nOfEvents.unSeenEventHubs().isEmpty() && nOfEvents.unSeenPeers().isEmpty()) {
issues.append("NofEvents had no Eventhubs added or Peer eventing services.");
}
String foundIssues = issues.toString();
if (!foundIssues.isEmpty()) {
throw new InvalidArgumentException(foundIssues);
}
}
final boolean replyonly = nOfEvents == NOfEvents.nofNoEvents || (getEventHubs().isEmpty() && getEventingPeers().isEmpty());
CompletableFuture<TransactionEvent> sret;
if (replyonly) {
// If there are no eventhubs to complete the future, complete it
// immediately but give no transaction event
logger.debug(format("Completing transaction id %s immediately no event hubs or peer eventing services found in channel %s.", proposalTransactionID, name));
sret = new CompletableFuture<>();
} else {
sret = registerTxListener(proposalTransactionID, nOfEvents, transactionOptions.failFast);
}
logger.debug(format("Channel %s sending transaction to orderer(s) with TxID %s ", name, proposalTransactionID));
boolean success = false;
// Save last exception to report to user .. others are just logged.
Exception lException = null;
BroadcastResponse resp = null;
Orderer failed = null;
for (Orderer orderer : shuffeledOrderers) {
if (failed != null) {
logger.warn(format("Channel %s %s failed. Now trying %s.", name, failed, orderer));
}
failed = orderer;
try {
if (null != diagnosticFileDumper) {
logger.trace(format("Sending to channel %s, orderer: %s, transaction: %s", name, orderer.getName(), diagnosticFileDumper.createDiagnosticProtobufFile(transactionEnvelope.toByteArray())));
}
resp = orderer.sendTransaction(transactionEnvelope);
// no longer last exception .. maybe just failed.
lException = null;
if (resp.getStatus() == Status.SUCCESS) {
success = true;
break;
} else {
logger.warn(format("Channel %s %s failed. Status returned %s", name, orderer, getRespData(resp)));
}
} catch (Exception e) {
String emsg = format("Channel %s unsuccessful sendTransaction to orderer %s (%s)", name, orderer.getName(), orderer.getUrl());
if (resp != null) {
emsg = format("Channel %s unsuccessful sendTransaction to orderer %s (%s). %s", name, orderer.getName(), orderer.getUrl(), getRespData(resp));
}
logger.error(emsg);
lException = new Exception(emsg, e);
}
}
if (success) {
logger.debug(format("Channel %s successful sent to Orderer transaction id: %s", name, proposalTransactionID));
if (replyonly) {
// just say we're done.
sret.complete(null);
}
return sret;
} else {
String emsg = format("Channel %s failed to place transaction %s on Orderer. Cause: UNSUCCESSFUL. %s", name, proposalTransactionID, getRespData(resp));
unregisterTxListener(proposalTransactionID);
CompletableFuture<TransactionEvent> ret = new CompletableFuture<>();
ret.completeExceptionally(lException != null ? new Exception(emsg, lException) : new Exception(emsg));
return ret;
}
} catch (Exception e) {
CompletableFuture<TransactionEvent> future = new CompletableFuture<>();
future.completeExceptionally(e);
return future;
}
}
Aggregations