Skip to content

Commit

Permalink
Add Support for Org targeting to peer gateway (hyperledger-caliper#1582)
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Kelsey <[email protected]>
  • Loading branch information
Dave Kelsey authored Jun 3, 2024
1 parent 44b3c52 commit b97c4b3
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/

/////////////////////////////
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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 = {};
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,26 +321,15 @@ 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',
contractFunction: 'myFunction',
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/);
});
});

Expand All @@ -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();

Expand Down Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(){
Expand Down Expand Up @@ -104,6 +109,10 @@ class Transaction {
Transaction.transient = contents;
}

setEndorsingOrgs(contents) {
Transaction.endorsingOrgs = contents;
}

getTransactionId() {
return '1';
}
Expand All @@ -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;
}
Expand Down

0 comments on commit b97c4b3

Please sign in to comment.