|
35 | 35 | import java.util.HashMap;
|
36 | 36 | import java.util.List;
|
37 | 37 | import java.util.Map;
|
| 38 | +import java.util.stream.Collectors; |
38 | 39 |
|
39 | 40 | import org.apache.commons.logging.Log;
|
40 | 41 | import org.apache.commons.logging.LogFactory;
|
@@ -635,78 +636,64 @@ public QueryStateResponse handleGetStateByRange(String startKey, String endKey,
|
635 | 636 | }
|
636 | 637 | }
|
637 | 638 | */
|
638 |
| - public ByteString handleInvokeChaincode(String chaincodeName, String function, List<ByteString> args, String uuid) { |
639 |
| - // Check if this is a transaction |
640 |
| - if (!isTransaction.containsKey(uuid)) { |
641 |
| - throw new RuntimeException("Cannot invoke chaincode in query context"); |
642 |
| - } |
643 |
| - |
644 |
| - ChaincodeID id = ChaincodeID.newBuilder() |
645 |
| - .setName(chaincodeName).build(); |
646 |
| - ChaincodeInput input = ChaincodeInput.newBuilder() |
647 |
| - .addArgs(ByteString.copyFromUtf8(function)) |
648 |
| - .addAllArgs(args) |
649 |
| - .build(); |
650 |
| - ChaincodeSpec payload = ChaincodeSpec.newBuilder() |
651 |
| - .setChaincodeId(id) |
652 |
| - .setInput(input) |
| 639 | + public Response handleInvokeChaincode(String chaincodeName, List<byte[]> args, String txid) { |
| 640 | + |
| 641 | + // create invocation specification of the chaincode to invoke |
| 642 | + final ChaincodeSpec invocationSpec = ChaincodeSpec.newBuilder() |
| 643 | + .setChaincodeId(ChaincodeID.newBuilder() |
| 644 | + .setName(chaincodeName) |
| 645 | + .build()) |
| 646 | + .setInput(ChaincodeInput.newBuilder() |
| 647 | + .addAllArgs(args.stream().map(ByteString::copyFrom).collect(Collectors.toList())) |
| 648 | + .build()) |
653 | 649 | .build();
|
654 | 650 |
|
655 |
| - // Create the channel on which to communicate the response from validating peer |
656 |
| - Channel<ChaincodeMessage> responseChannel; |
657 |
| - try { |
658 |
| - responseChannel = createChannel(uuid); |
659 |
| - } catch (Exception e) { |
660 |
| - logger.error(String.format("[%s]Another state request pending for this Uuid. Cannot process.", shortID(uuid))); |
661 |
| - throw e; |
662 |
| - } |
663 |
| - |
664 |
| - //Defer |
665 | 651 | try {
|
| 652 | + // create the channel on which to communicate the response from validating peer |
| 653 | + final Channel<ChaincodeMessage> responseChannel = createChannel(txid); |
| 654 | + |
666 | 655 | // Send INVOKE_CHAINCODE message to validator chaincode support
|
667 |
| - ChaincodeMessage message = ChaincodeMessage.newBuilder() |
668 |
| - .setType(INVOKE_CHAINCODE) |
669 |
| - .setPayload(payload.toByteString()) |
670 |
| - .setTxid(uuid) |
671 |
| - .build(); |
672 |
| - |
673 |
| - logger.debug(String.format("[%s]Sending %s", |
674 |
| - shortID(message), INVOKE_CHAINCODE)); |
675 |
| - |
676 |
| - try { |
677 |
| - serialSend(message); |
678 |
| - } catch (Exception e) { |
679 |
| - logger.error("["+ shortID(message)+"]Error sending "+INVOKE_CHAINCODE+": "+e.getMessage()); |
680 |
| - throw e; |
681 |
| - } |
682 |
| - |
683 |
| - // Wait on responseChannel for response |
684 |
| - ChaincodeMessage response; |
685 |
| - try { |
686 |
| - response = receiveChannel(responseChannel); |
687 |
| - } catch (Exception e) { |
688 |
| - logger.error(String.format("[%s]Received unexpected message type", shortID(message))); |
689 |
| - throw new RuntimeException("Received unexpected message type"); |
690 |
| - } |
| 656 | + final ChaincodeMessage message = HandlerHelper.newInvokeChaincodeMessage(txid, invocationSpec.toByteString()); |
| 657 | + logger.debug(String.format("[%s]Sending %s", shortID(message), INVOKE_CHAINCODE)); |
| 658 | + serialSend(message); |
691 | 659 |
|
692 |
| - if (response.getType() == RESPONSE) { |
693 |
| - // Success response |
694 |
| - logger.debug(String.format("[%s]Received %s. Successfully invoked chaincode", shortID(response.getTxid()), RESPONSE)); |
695 |
| - return response.getPayload(); |
| 660 | + // wait for response chaincode message |
| 661 | + final ChaincodeMessage outerResponseMessage = receiveChannel(responseChannel); |
| 662 | + |
| 663 | + if(outerResponseMessage == null) { |
| 664 | + return ChaincodeHelper.newInternalServerErrorResponse("chaincode invoke returned null"); |
696 | 665 | }
|
697 |
| - |
698 |
| - if (response.getType() == ERROR) { |
| 666 | + |
| 667 | + logger.debug(String.format("[%s]Received %s.", shortID(outerResponseMessage.getTxid()), outerResponseMessage.getType())); |
| 668 | + |
| 669 | + switch (outerResponseMessage.getType()) { |
| 670 | + case RESPONSE: |
| 671 | + // response message payload should be yet another chaincode message (the actual response message) |
| 672 | + final ChaincodeMessage responseMessage = ChaincodeMessage.parseFrom(outerResponseMessage.getPayload()); |
| 673 | + // the actual response message must be of type COMPLETED |
| 674 | + logger.debug(String.format("[%s]Received %s.", shortID(responseMessage.getTxid()), responseMessage.getType())); |
| 675 | + if(responseMessage.getType() == COMPLETED) { |
| 676 | + // success |
| 677 | + return Response.parseFrom(responseMessage.getPayload()); |
| 678 | + } else { |
| 679 | + // error |
| 680 | + return ChaincodeHelper.newInternalServerErrorResponse(responseMessage.getPayload().toByteArray()); |
| 681 | + } |
| 682 | + case ERROR: |
699 | 683 | // Error response
|
700 |
| - logger.error(String.format("[%s]Received %s.", shortID(response.getTxid()), ERROR)); |
701 |
| - throw new RuntimeException(response.getPayload().toStringUtf8()); |
| 684 | + logger.error(String.format("[%s]Received %s.", shortID(outerResponseMessage.getTxid()), ERROR)); |
| 685 | + return ChaincodeHelper.newInternalServerErrorResponse(outerResponseMessage.getPayload().toByteArray()); |
| 686 | + default: |
| 687 | + // Incorrect chaincode message received |
| 688 | + logger.debug(String.format("[%s]Incorrect chaincode message %s received. Expecting %s or %s",shortID(outerResponseMessage.getTxid()), outerResponseMessage.getType(), RESPONSE, ERROR)); |
| 689 | + return ChaincodeHelper.newInternalServerErrorResponse("Incorrect chaincode message received.", outerResponseMessage.toByteArray()); |
702 | 690 | }
|
703 |
| - |
704 |
| - // Incorrect chaincode message received |
705 |
| - logger.debug(String.format("[%s]Incorrect chaincode message %s received. Expecting %s or %s", |
706 |
| - shortID(response.getTxid()), response.getType(), RESPONSE, ERROR)); |
707 |
| - throw new RuntimeException("Incorrect chaincode message received"); |
| 691 | + } catch (InvalidProtocolBufferException e) { |
| 692 | + return ChaincodeHelper.newInternalServerErrorResponse(e); |
| 693 | + } catch (RuntimeException e) { |
| 694 | + return ChaincodeHelper.newInternalServerErrorResponse(e); |
708 | 695 | } finally {
|
709 |
| - deleteChannel(uuid); |
| 696 | + deleteChannel(txid); |
710 | 697 | }
|
711 | 698 | }
|
712 | 699 |
|
|
0 commit comments