diff --git a/packages/caliper-fabric/lib/connector-versions/peer-gateway/PeerGateway.js b/packages/caliper-fabric/lib/connector-versions/peer-gateway/PeerGateway.js index e02f199d2..3b96ce265 100644 --- a/packages/caliper-fabric/lib/connector-versions/peer-gateway/PeerGateway.js +++ b/packages/caliper-fabric/lib/connector-versions/peer-gateway/PeerGateway.js @@ -43,6 +43,8 @@ const logger = CaliperUtils.getLogger('connectors/peer-gateway/PeerGateway'); * @property {string} invokerIdentity Required. The identity name of the invoker * @property {boolean} [readOnly] Optional. Indicates whether the request is a submit or evaluation. * contract. If an admin is needed, use the organization name prefixed with a _ symbol. + * @property {string[]} [targetOrganizations] Optional. An array of endorsing organizations as the + * targets of the invoke. */ ///////////////////////////// @@ -152,8 +154,8 @@ class PeerGateway extends ConnectorBase { request.contractArguments = []; } - if (request.targetPeers || request.targetOrganizations) { - throw new Error('targetPeers or targetOrganizations options are not supported by the Peer Gateway connector'); + if (request.targetPeers) { + throw new Error('targetPeers option is not supported by the Peer Gateway connector, use targetOrganizations instead'); } return await this._submitOrEvaluateTransaction(request, request.readOnly === undefined || !request.readOnly); } @@ -292,6 +294,7 @@ class PeerGateway extends ConnectorBase { const proposalOptions = {}; // add contract arguments to proposal Options proposalOptions.arguments = invokeSettings.contractArguments; + // Add transient data if present if (invokeSettings.transientMap) { const transientData = {}; @@ -301,6 +304,15 @@ class PeerGateway extends ConnectorBase { }); proposalOptions.transientData = transientData; } + + if (invokeSettings.targetOrganizations) { + if (Array.isArray(invokeSettings.targetOrganizations) && invokeSettings.targetOrganizations.length > 0) { + proposalOptions.endorsingOrganizations = invokeSettings.targetOrganizations; + } else { + logger.warn(`${invokeSettings.targetOrganizations} is not a populated array, no orgs targeted`); + } + } + // set transaction invocation result to return try { const proposal = smartContract.newProposal(invokeSettings.contractFunction, proposalOptions); diff --git a/packages/caliper-fabric/test/connector-versions/peer-gateway/PeerGateway.js b/packages/caliper-fabric/test/connector-versions/peer-gateway/PeerGateway.js index 7b3c2676d..8b8f6e789 100644 --- a/packages/caliper-fabric/test/connector-versions/peer-gateway/PeerGateway.js +++ b/packages/caliper-fabric/test/connector-versions/peer-gateway/PeerGateway.js @@ -321,7 +321,7 @@ describe('A Fabric Peer Gateway sdk gateway', () => { await peerGateway._sendSingleRequest(request).should.be.rejectedWith(/Could not find details for contract ID not-a-valid-contract-id/); }); - it('when tergetPeers is specified', async () => { + it('when targetPeers is specified', async () => { const request = { channel: 'mychannel', contractId: 'marbles', @@ -329,18 +329,7 @@ describe('A Fabric Peer Gateway sdk gateway', () => { invokerIdentity: 'admin', targetPeers: 'peer0.org2.example.com' }; - await peerGateway._sendSingleRequest(request).should.be.rejectedWith(/targetPeers or targetOrganizations options are not supported by the Peer Gateway connector/); - }); - - it('when targetOrganizations is specified', async () => { - const request = { - channel: 'mychannel', - contractId: 'marbles', - contractFunction: 'myFunction', - invokerIdentity: 'admin', - targetOrganizations: 'Org2MSP' - }; - await peerGateway._sendSingleRequest(request).should.be.rejectedWith(/targetPeers or targetOrganizations options are not supported by the Peer Gateway connector/); + await peerGateway._sendSingleRequest(request).should.be.rejectedWith(/targetPeers option is not supported by the Peer Gateway connector, use targetOrganizations instead/); }); }); @@ -364,6 +353,8 @@ describe('A Fabric Peer Gateway sdk gateway', () => { Transaction.submit.should.be.true; Transaction.submitArgs.should.deep.equal(args); Transaction.constructorArgs.should.equal('myFunction'); + chai.expect(Transaction.endorsingOrgs).to.be.null; + chai.expect(Transaction.transient).to.be.null; Transaction.reset(); @@ -414,6 +405,51 @@ describe('A Fabric Peer Gateway sdk gateway', () => { Transaction.constructorArgs.should.equal('myFunction'); }); + it('should set the endorsing organisations if targetOrganizations is specified', async () => { + const request = { + channel: 'mychannel', + contractId: 'marbles', + contractFunction: 'myFunction', + targetOrganizations: ['myOrg1', 'myOrg2', 'myOrg3'], + invokerIdentity: 'admin' + }; + await peerGateway._sendSingleRequest(request); + Transaction.submit.should.be.true; + Transaction.submitArgs.should.deep.equal([]); + Transaction.endorsingOrgs.should.deep.equal(['myOrg1', 'myOrg2', 'myOrg3']); + Transaction.constructorArgs.should.equal('myFunction'); + }); + + it('should not set endorsing organisations if it is not an array', async () => { + const request = { + channel: 'mychannel', + contractId: 'marbles', + contractFunction: 'myFunction', + targetOrganizations: 'myOrg1', + invokerIdentity: 'admin' + }; + await peerGateway._sendSingleRequest(request); + Transaction.submit.should.be.true; + Transaction.submitArgs.should.deep.equal([]); + chai.expect(Transaction.endorsingOrgs).to.be.null; + Transaction.constructorArgs.should.equal('myFunction'); + }); + + it('should not set endorsing organisations if it is an empty array', async () => { + const request = { + channel: 'mychannel', + contractId: 'marbles', + contractFunction: 'myFunction', + targetOrganizations: [], + invokerIdentity: 'admin' + }; + await peerGateway._sendSingleRequest(request); + Transaction.submit.should.be.true; + Transaction.submitArgs.should.deep.equal([]); + chai.expect(Transaction.endorsingOrgs).to.be.null; + Transaction.constructorArgs.should.equal('myFunction'); + }); + it('should look up the channel and chaincode id from contractId when no channel provided', async () => { const request = { contractId: 'lostMyMarbles', diff --git a/packages/caliper-fabric/test/connector-versions/peer-gateway/PeerGatewayStubs.js b/packages/caliper-fabric/test/connector-versions/peer-gateway/PeerGatewayStubs.js index ce0052b58..4376708d5 100644 --- a/packages/caliper-fabric/test/connector-versions/peer-gateway/PeerGatewayStubs.js +++ b/packages/caliper-fabric/test/connector-versions/peer-gateway/PeerGatewayStubs.js @@ -75,7 +75,12 @@ class Transaction { constructor(name, args) { Transaction.constructorArgs = name; this.args = args; - this.setTransient(this.args.transientData); + if (this.args.transientData !== undefined) { + this.setTransient(this.args.transientData); + } + if (this.args.endorsingOrganizations !== undefined) { + this.setEndorsingOrgs(this.args.endorsingOrganizations); + } } async endorse(){ @@ -104,6 +109,10 @@ class Transaction { Transaction.transient = contents; } + setEndorsingOrgs(contents) { + Transaction.endorsingOrgs = contents; + } + getTransactionId() { return '1'; } @@ -121,7 +130,8 @@ class Transaction { Transaction.submitArgs = null; Transaction.evaluate = false; Transaction.evaluateArgs = null; - Transaction.transient = undefined; + Transaction.transient = null; + Transaction.endorsingOrgs = null; Transaction.err = undefined; Transaction.fails = false; }