Skip to content

Commit

Permalink
FABN-864 Discovery support in fabric-network api
Browse files Browse the repository at this point in the history
Enhance the fabric-network API to use service discovery by
default when initializing the channel.
Add option to disable it and option to translate discovered
endpoints to localhost

Change-Id: I9a81b87751b40dd125a9989f831760950d00c826
Signed-off-by: andrew-coleman <[email protected]>
  • Loading branch information
andrew-coleman committed Oct 31, 2018
1 parent 52c82cc commit 4f65a2e
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 28 deletions.
1 change: 0 additions & 1 deletion fabric-client/lib/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,6 @@ const Client = class extends BaseClient {
throw new Error('Missing "chaincodePath" parameter in the proposal request');
}

console.log('request.targets', request.targets);
let peers = this.getTargetPeers(request.targets);
if (!peers && request.channelNames) {
peers = this.getPeersForOrgOnChannel(request.channelNames);
Expand Down
16 changes: 13 additions & 3 deletions fabric-network/lib/gateway.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class Gateway {
eventHandlerOptions: {
commitTimeout: 300, // 5 minutes
strategy: EventStrategies.MSPID_SCOPE_ALLFORTX
},
discovery: {
enabled: true,
asLocalhost: false
}
};
}
Expand Down Expand Up @@ -130,7 +134,7 @@ class Gateway {
}

Gateway._mergeOptions(this.options, options);
logger.debug('connection options: %O', options);
logger.debug('connection options: %j', options);

if (!(config instanceof Client)) {
// still use a ccp for the discovery peer and ca information
Expand All @@ -142,6 +146,12 @@ class Gateway {
this.client = config;
}

if(this.options.discovery && this.options.discovery.enabled) {
this.client.setConfigSetting('initialize-with-discovery', true);
} else {
this.client.setConfigSetting('initialize-with-discovery', false);
}

// setup an initial identity for the Gateway
if (options.identity) {
logger.debug('%s - setting identity', method);
Expand All @@ -163,7 +173,7 @@ class Gateway {
try {
this.queryHandlerClass = require(this.options.queryHandler);
} catch(error) {
logger.error('%s - unable to load provided query handler: %s. Error %O', method, this.options.queryHandler, error);
logger.error('%s - unable to load provided query handler: %s. Error %j', method, this.options.queryHandler, error);
throw new Error(`unable to load provided query handler: ${this.options.queryHandler}. Error ${error}`);
}
}
Expand Down Expand Up @@ -231,7 +241,7 @@ class Gateway {
logger.debug('getNetwork: create network object and initialize');
const channel = this.client.getChannel(networkName);
const newNetwork = new Network(this, channel);
await newNetwork._initialize();
await newNetwork._initialize(this.options.discovery);
this.networks.set(networkName, newNetwork);
return newNetwork;
}
Expand Down
2 changes: 1 addition & 1 deletion fabric-network/lib/impl/event/transactioneventhandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class TransactionEventHandler {
};
this.options = Object.assign(defaultOptions, options);

logger.debug('constructor:', util.format('transactionId = %s, options = %O', this.transactionId, this.options));
logger.debug('constructor:', util.format('transactionId = %s, options = %j', this.transactionId, this.options));

this.eventHubs = [];
this.respondedEventHubs = new Set();
Expand Down
2 changes: 1 addition & 1 deletion fabric-network/lib/impl/wallet/basewallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class BaseWallet extends Wallet {

constructor(walletMixin = new X509WalletMixin()) {
super();
logger.debug('in BaseWallet constructor, mixin = %O', walletMixin);
logger.debug('in BaseWallet constructor, mixin = %j', walletMixin);
this.storesInitialized = false;
this.walletMixin = walletMixin;
}
Expand Down
11 changes: 7 additions & 4 deletions fabric-network/lib/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class Network {
* initialize the channel if it hasn't been done
* @private
*/
async _initializeInternalChannel() {
async _initializeInternalChannel(discovery) {
logger.debug('in _initializeInternalChannel');

//TODO: Should this work across all peers or just orgs peers ?
Expand All @@ -100,10 +100,13 @@ class Network {
while (!success) {
try {
const initOptions = {
target: ledgerPeers[ledgerPeerIndex]
target: ledgerPeers[ledgerPeerIndex],
discover: discovery.enabled,
asLocalhost: discovery.asLocalhost
};

await this.channel.initialize(initOptions);

success = true;
} catch(error) {
if (ledgerPeerIndex >= ledgerPeers.length - 1) {
Expand All @@ -121,14 +124,14 @@ class Network {
* @private
* @memberof Network
*/
async _initialize() {
async _initialize(discover) {
logger.debug('in initialize');

if (this.initialized) {
return;
}

await this._initializeInternalChannel();
await this._initializeInternalChannel(discover);
const peerMap = this._mapPeersToMSPid();
this.queryHandler = await this.gateway._createQueryHandler(this.channel, peerMap);
this.initialized = true;
Expand Down
16 changes: 8 additions & 8 deletions fabric-network/test/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe('Network', () => {

it('should initialize the network using the first peer', async () => {
mockChannel.initialize.resolves();
await network._initializeInternalChannel();
await network._initializeInternalChannel({enabled:false, asLocalhost: false});
sinon.assert.calledOnce(mockChannel.initialize);
});

Expand All @@ -104,10 +104,10 @@ describe('Network', () => {
// create a real mock
mockChannel.initialize.onCall(0).rejects(new Error('connect failed'));
mockChannel.initialize.onCall(1).resolves();
await network._initializeInternalChannel();
await network._initializeInternalChannel({enabled:false, asLocalhost: false});
sinon.assert.calledTwice(mockChannel.initialize);
sinon.assert.calledWith(mockChannel.initialize.firstCall, {target: mockPeer1});
sinon.assert.calledWith(mockChannel.initialize.secondCall, {target: mockPeer3});
sinon.assert.calledWith(mockChannel.initialize.firstCall, {target: mockPeer1, discover:false, asLocalhost: false});
sinon.assert.calledWith(mockChannel.initialize.secondCall, {target: mockPeer3, discover: false, asLocalhost: false});
});

it('should fail if all peers fail', async () => {
Expand All @@ -117,15 +117,15 @@ describe('Network', () => {
mockChannel.initialize.onCall(2).rejects(new Error('connect failed again'));
let error;
try {
await network._initializeInternalChannel();
await network._initializeInternalChannel({enabled:true, asLocalhost: true});
} catch(_error) {
error = _error;
}
error.should.match(/connect failed again/);
sinon.assert.calledThrice(mockChannel.initialize);
sinon.assert.calledWith(mockChannel.initialize.firstCall, {target: mockPeer1});
sinon.assert.calledWith(mockChannel.initialize.secondCall, {target: mockPeer3});
sinon.assert.calledWith(mockChannel.initialize.thirdCall, {target: mockPeer4});
sinon.assert.calledWith(mockChannel.initialize.firstCall, {target: mockPeer1, discover: true, asLocalhost: true});
sinon.assert.calledWith(mockChannel.initialize.secondCall, {target: mockPeer3, discover: true, asLocalhost: true});
sinon.assert.calledWith(mockChannel.initialize.thirdCall, {target: mockPeer4, discover: true, asLocalhost: true});
});

it('should fail if there are no LEDGER_QUERY_ROLE peers', async () => {
Expand Down
35 changes: 35 additions & 0 deletions test/fixtures/network-discovery.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name":"global-trade-network",
"description":"The network to be in if you want to stay in the global trade business",
"version":"1.0",
"client":{
"organization":"Org1"
},
"channels":{
"mychannel":{
"peers":{
"peer0.org1.example.com":{
}
}
}
},
"organizations":{
"Org1":{
"mspid":"Org1MSP",
"peers":[
"peer0.org1.example.com"
]
}
},
"peers":{
"peer0.org1.example.com":{
"url":"grpcs://localhost:7051",
"grpcOptions":{
"ssl-target-name-override":"peer0.org1.example.com"
},
"tlsCACerts":{
"path":"test/fixtures/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tlscacerts/org1.example.com-cert.pem"
}
}
}
}
35 changes: 35 additions & 0 deletions test/integration/network-e2e/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"test-network": {
"orderer": {
"url": "grpcs://localhost:7050",
"server-hostname": "orderer.example.com",
"tls_cacerts": "../../fixtures/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tlscacerts/example.com-cert.pem"
},
"org1": {
"name": "peerOrg1",
"mspid": "Org1MSP",
"ca": {
"url": "https://localhost:7054",
"name": "ca-org1"
},
"peer1": {
"requests": "grpcs://localhost:7051",
"server-hostname": "peer0.org1.example.com",
"tls_cacerts": "../../fixtures/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tlscacerts/org1.example.com-cert.pem"
}
},
"org2": {
"name": "peerOrg2",
"mspid": "Org2MSP",
"ca": {
"url": "https://localhost:8054",
"name": "ca-org2"
},
"peer1": {
"requests": "grpcs://localhost:8051",
"server-hostname": "peer0.org2.example.com",
"tls_cacerts": "../../fixtures/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tlscacerts/org2.example.com-cert.pem"
}
}
}
}
1 change: 1 addition & 0 deletions test/integration/network-e2e/e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ require('../e2e/create-channel.js');
require('../e2e/join-channel.js');
require('./install-chaincode.js');
require('./instantiate-chaincode.js');
require('./updateAnchorPeers');
require('./invoke.js');
require('./query.js');
1 change: 1 addition & 0 deletions test/integration/network-e2e/invoke-hsm.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ test('\n\n***** Network End-to-end flow: invoke transaction to move money using
wallet: hsmWallet,
identity: hsmUser,
tlsInfo,
discovery: { enabled: false }
});

// Obtain an event hub that that will be used by the underlying implementation
Expand Down
Loading

0 comments on commit 4f65a2e

Please sign in to comment.