Skip to content

Commit

Permalink
FABN-1557 NodeSDK all restart event service (#237)
Browse files Browse the repository at this point in the history
Event Service would not reconnect after a disconnect. Checking to
avoid connecting during a connect was not reset during the disconnect.

Added more logging and testing.

Signed-off-by: Bret Harrison <beharrison@nc.rr.com>
  • Loading branch information
harrisob authored May 20, 2020
1 parent 44bbab0 commit ba11979
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 13 deletions.
9 changes: 9 additions & 0 deletions fabric-common/lib/EventService.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class EventService extends ServiceAction {
this._current_eventer.disconnect();
logger.debug('%s - closing stream %s', method, this.currentStreamNumber);
this._current_eventer = null;
} else {
logger.debug('%s - no current eventer - not shutting down stream', method);
}
this._close_running = false;

Expand Down Expand Up @@ -356,16 +358,20 @@ class EventService extends ServiceAction {
for (const target of this.targets) {
try {
if (target.stream) {
logger.debug('%s - target has a stream, is already listening %s', method, target.toString());
start_error = Error(`Event service ${target.name} is currently listening`);
} else {
if (target.isConnectable()) {
logger.debug('%s - target needs to connect %s', method, target.toString());
await target.connect(); // target endpoint has been previously assigned, but not connected yet
}
const isConnected = await target.checkConnection();
if (!isConnected) {
start_error = Error(`Event service ${target.name} is not connected`);
logger.debug('%s - target is not connected %s', method, target.toString());
} else {
this._current_eventer = await this._startService(target, envelope, requestTimeout);
logger.debug('%s - set current eventer %s', method, this._current_eventer.toString());
}
}
} catch (error) {
Expand All @@ -384,8 +390,11 @@ class EventService extends ServiceAction {
// if we ran through the all targets and have start_error then we
// have not found a working target endpoint, so tell user error
if (start_error) {
logger.error('%s - no targets started - %s', method, start_error);
throw start_error;
}

logger.debug('%s - end', method);
}

/*
Expand Down
2 changes: 1 addition & 1 deletion fabric-common/lib/Eventer.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class Eventer extends ServiceEndpoint {
}
}

logger.debug('%s - end', method);
logger.debug('%s - end return:%s', method, result);
return result;
}

Expand Down
9 changes: 6 additions & 3 deletions fabric-common/lib/ServiceEndpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class ServiceEndpoint {
logger.debug(`${method} - create the grpc service for ${this.name}`);
this.service = new this.serviceClass(this.endpoint.addr, this.endpoint.creds, this.options);
await this.waitForReady(this.service);
logger.debug(`${method} - completed the waitForReady for ${this.name}`);
logger.debug(`${method} - end - completed the waitForReady for ${this.name}`);
}

/**
Expand All @@ -135,14 +135,16 @@ class ServiceEndpoint {
this.service.close();
this.service = null;
this.connected = false;
this.connectAttempted = false;
}
}

/**
* Check the connection status
*/
async checkConnection() {
logger.debug(`checkConnection[${this.name}] - start `);
const method = `checkConnection[${this.name}]`;
logger.debug('%s - start - connected:%s', method, this.connected);

if (this.connected) {
try {
Expand All @@ -153,6 +155,7 @@ class ServiceEndpoint {
}
}

logger.debug('%s - end - connected:%s', method, this.connected);
return this.connected;
}

Expand Down Expand Up @@ -227,7 +230,7 @@ class ServiceEndpoint {
url = this.endpoint.url;
}

return `${this.type}- name: ${this.name}, url:${url}`;
return `${this.type}- name: ${this.name}, url:${url}, connected:${this.connected}, connectAttempted:${this.connectAttempted}`;
}

}
Expand Down
2 changes: 1 addition & 1 deletion fabric-common/test/Channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ describe('Channel', () => {
channel.addCommitter(getCommitter('committer1'));
const channel_string = channel.toString();
assert.equal(channel_string,
'{"name":"mychannel","committers":["Committer- name: committer1, url:<not connected>"],"endorsers":["Endorser- name: endorser1, url:<not connected>"]}',
'{"name":"mychannel","committers":["Committer- name: committer1, url:<not connected>, connected:true, connectAttempted:false"],"endorsers":["Endorser- name: endorser1, url:<not connected>, connected:true, connectAttempted:false"]}',
'toString has all this'
);
});
Expand Down
4 changes: 2 additions & 2 deletions fabric-common/test/ServiceEndpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,12 @@ describe('ServiceEndpoint', () => {
describe('#toString', () => {
it('should get a string url', async () => {
const results = serviceEndpoint.toString();
results.should.be.equal('ServiceEndpoint- name: myserviceEndpoint, url:grpc://host:2700');
results.should.be.equal('ServiceEndpoint- name: myserviceEndpoint, url:grpc://host:2700, connected:true, connectAttempted:false');
});
it('should get a string result', async () => {
serviceEndpoint.endpoint = null;
const results = serviceEndpoint.toString();
results.should.be.equal('ServiceEndpoint- name: myserviceEndpoint, url:<not connected>');
results.should.be.equal('ServiceEndpoint- name: myserviceEndpoint, url:<not connected>, connected:true, connectAttempted:false');
});
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"test:cucumber": "cucumber-js -f node_modules/cucumber-pretty ./test/scenario/features/*.feature",
"test:ts-cucumber": "cucumber-js -f node_modules/cucumber-pretty ./test/ts-scenario/features/*.feature --require './test/ts-scenario/steps/**/*.ts' --require './test/ts-scenario/support/**/*.ts' --require-module ts-node/register",
"test:ts-cucumberNoHSM": "cucumber-js -f node_modules/cucumber-pretty ./test/ts-scenario/features/*.feature --require './test/ts-scenario/steps/**/*.ts' --require './test/ts-scenario/support/**/*.ts' --require-module ts-node/register --tags 'not @gateway_hsm'",
"test:ts-cucumber-tagged": "npm run test:ts-cucumber -- --tags @base_api_1",
"test:ts-cucumber-tagged": "npm run test:ts-cucumber -- --tags @base_api_2",
"testHeadless": "run-s cleanUp compile lint unitTest:all",
"tapeAndCucumber": "run-s tapeIntegration dockerClean cucumberScenario"
},
Expand Down
14 changes: 13 additions & 1 deletion test/ts-scenario/features/base_api_v2.feature
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ Scenario: Using only fabric-common on V2 channel
And the request named myDiscoveryRequest for client fred has a event result matching {"result":"Commit success"}
And the request named myDiscoveryRequest for client fred has a commit result matching {"status":"SUCCESS"}


When I create an event service myFilteredEventService as client fred on channel basev2channel
And I regisister a block listener named myFilteredBlockListener with myFilteredEventService for startBlock 1 and endBlock 3 as client fred
And I regisister a chaincode listener named myFilteredChaincodeListener with myFilteredEventService for createCar event on contract fabcar as client fred
Expand All @@ -57,3 +56,16 @@ Scenario: Using only fabric-common on V2 channel
Then the event listener myFullBlockListener of myFullEventService has results matching {"block":"4"} as client fred
Then the event listener myFullChaincodeListener of myFullEventService has results matching {"createCar":"Focus"} as client fred
Then the event listener myFullTransactionListener of myFullEventService has results matching {"transaction":"7"} as client fred

When I disconnect Event Service myFilteredEventService as client fred
And I regisister a block listener named myRestartListener with myFilteredEventService for startBlock 1 and endBlock 6 as client fred
And I restart the event service myFilteredEventService as filtered blocks to start at block 0 and end at block 6 as client fred
When I build a new endorsement request named myEventRequest for smart contract named fabcar with arguments [createCar,2008,Chrysler,PTCurser,white,Jones] as client fred on discovery channel basev2channel
And I commit the endorsement request named myEventRequest as client fred on channel basev2channel
Then the event listener myRestartListener of myFilteredEventService has results matching {"block":"6"} as client fred
When I disconnect Event Service myFilteredEventService as client fred
And I regisister a block listener named myRestartListener with myFilteredEventService for startBlock 1 and endBlock 6 as client fred
And I restart the event service myFilteredEventService as filtered blocks to start at block 0 and end at block 6 as client fred
When I build a new endorsement request named myEventRequest for smart contract named fabcar with arguments [createCar,2008,Chrysler,PTCurser,white,Jones] as client fred on discovery channel basev2channel
And I commit the endorsement request named myEventRequest as client fred on channel basev2channel
Then the event listener myRestartListener of myFilteredEventService has results matching {"block":"6"} as client fred
10 changes: 7 additions & 3 deletions test/ts-scenario/steps/base_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ When(/^I create an event service (.+?) as client (.+?) on channel (.+?)$/, { tim
await ClientHelper.createEventService(eventServiceName, clientName, channelName);
});

Then(/^I start the event service (.+?) as (.+?) blocks to start at block (.+?) and end at block (.+?) as client (.+?)$/, { timeout: Constants.INC_SHORT as number },
async (eventServiceName: string, blockType: 'filtered' | 'full' | 'private' | undefined, startBlock: string, endBlock: string, clientName: string) => {
await ClientHelper.startEventService(blockType, eventServiceName, clientName, startBlock, endBlock);
Then(/^I (.+?) the event service (.+?) as (.+?) blocks to start at block (.+?) and end at block (.+?) as client (.+?)$/, { timeout: Constants.INC_SHORT as number },
async (start: 'start' | 'restart', eventServiceName: string, blockType: 'filtered' | 'full' | 'private' | undefined, startBlock: string, endBlock: string, clientName: string) => {
await ClientHelper.startEventService(blockType, eventServiceName, clientName, startBlock, endBlock, start);
});

Then(/^I regisister a block listener named (.+?) with (.+?) for startBlock (.+?) and endBlock (.+?) as client (.+?)$/, { timeout: Constants.INC_SHORT as number },
Expand All @@ -86,3 +86,7 @@ Then(/^the event listener (.+?) of (.+?) has results matching (.+?) as client (.
async (listenerName: string, eventServiceName: string, check: string, clientName: string) => {
await ClientHelper.checkEventListenerResults(eventServiceName, clientName, listenerName, check);
});

When(/^I disconnect Event Service (.+?) as client (.+?)$/, {timeout: Constants.HUGE_TIME as number }, async (eventServiceName: string, clientName: string) => {
await ClientHelper.disconnectEventService(eventServiceName, clientName);
});
23 changes: 22 additions & 1 deletion test/ts-scenario/steps/lib/utility/clientUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,14 @@ export async function createEventService(eventServiceName: string, clientName: s
}
}

export async function startEventService(blockType: 'filtered' | 'full' | 'private' | undefined, eventServiceName: string, clientName: string, startBlock: string, endBlock: string): Promise<void> {
export async function startEventService(
blockType: 'filtered' | 'full' | 'private' | undefined,
eventServiceName: string,
clientName: string,
startBlock: string,
endBlock: string,
start: string): Promise<void> {

const clientObject: any = retrieveClientObject(clientName);
const client: Client = clientObject.client;
const ccp: CommonConnectionProfileHelper = clientObject.ccp;
Expand Down Expand Up @@ -631,6 +638,12 @@ export async function startEventService(blockType: 'filtered' | 'full' | 'privat
const peerNames: any = ccp.getPeersForChannel(channelName);
const endpoints: Endpoint[] = [];

if (start === 'restart') {
// we want to use the targets that we used last time
await eventService.send();
return;
}

for (const peerName of peerNames) {
const peerObject: any = ccp.getPeer(peerName);
const endpoint: Endpoint = client.newEndpoint({
Expand Down Expand Up @@ -805,3 +818,11 @@ export async function checkEventListenerResults(
BaseUtils.logAndThrow(`Listener object not found ${listenerName}`);
}
}

export async function disconnectEventService(
eventServiceName: string, clientName: string): Promise<void> {
const clientObject: any = retrieveClientObject(clientName);
const eventServiceObject: any = clientObject.eventServices.get(eventServiceName);

eventServiceObject.eventService.close();
}

0 comments on commit ba11979

Please sign in to comment.