Skip to content

Commit

Permalink
FABN-1347 NodeSDK add new low level tests
Browse files Browse the repository at this point in the history
Add the intergration, cucumber tests for the
new low level NodeSDK.

Signed-off-by: Bret Harrison <[email protected]>
Change-Id: I537380b3f3ecfe3a055982fd35b0e3b55b53cfd6
  • Loading branch information
harrisob committed Oct 11, 2019
1 parent 5834c7d commit b7ce073
Show file tree
Hide file tree
Showing 35 changed files with 1,420 additions and 144 deletions.
2 changes: 1 addition & 1 deletion fabric-client/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"grpc.http2.min_time_between_pings_ms": 120000,
"grpc.keepalive_timeout_ms": 20000,
"grpc.http2.max_pings_without_data": 0,
"grpc.keepalive_permit_without_calls": 1
"grpc.keepalive_permit_without_calls": 1
},
"network-config-schema" : {
"1.0": "fabric-client/lib/impl/NetworkConfig_1_0.js"
Expand Down
2 changes: 2 additions & 0 deletions fabric-common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ const SigningIdentity = require('./lib/SigningIdentity');
const Utils = require('./lib/Utils');
const User = require('./lib/User');
const BaseClient = require('./lib/BaseClient');
const Client = require('./lib/Client');

module.exports = {
Client,
Config,
CryptoAlgorithms,
CryptoSuite,
Expand Down
33 changes: 33 additions & 0 deletions fabric-common/lib/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ const Client = class extends BaseClient {
this.channels = new Map();
}

/**
* Construct a Client object.
*
* @param {string} name - The name of the client.
*/
static newClient(name) {
return new Client(name);
}

/**
* @typedef {Object} ConnectOptions
* @property {string} url The committer URL with format of 'grpc(s)://host:port'.
Expand Down Expand Up @@ -108,6 +117,30 @@ const Client = class extends BaseClient {
const options = this.getConnectionOptions(opts);
const ssl_target_name_override = options['ssl-target-name-override'];

// make sure we have wait for ready timeout
const timeout = options['grpc-wait-for-ready-timeout'];
if (!timeout) {
options['grpc-wait-for-ready-timeout'] = 3000; // default 3 seconds
} else {
if (Number.isInteger(timeout)) {
logger.debug('%s grpc-wait-for-ready-timeout set to %s', method, timeout);
} else {
throw Error(`invalid grpc-wait-for-ready-timeout :: ${timeout}`);
}
}

// make sure we have wait for request timeout
const requestTimeout = options.requestTimeout;
if (!requestTimeout) {
options.requestTimeout = 3000; // default 3 seconds
} else {
if (Number.isInteger(requestTimeout)) {
logger.debug('%s requestTimeout set to %s', method, requestTimeout);
} else {
throw Error(`invalid requestTimeout :: ${requestTimeout}`);
}
}

if (typeof ssl_target_name_override === 'string') {
options['grpc.ssl_target_name_override'] = ssl_target_name_override;
options['grpc.default_authority'] = ssl_target_name_override;
Expand Down
6 changes: 3 additions & 3 deletions fabric-common/lib/Commit.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class Commit extends Proposal {
* When not included an handler must be included.
* @property {EndorsementHandler} - [handler] - Optional. The handler to send the endorsements.
* When not included, targets must be included.
* @property {Number} [request_timeout] - Optional. The request timeout
* @property {Number} [requestTimeout] - Optional. The request timeout
*/

/**
Expand All @@ -147,7 +147,7 @@ class Commit extends Proposal {
const method = `send[${this.chaincodeName}]`;
logger.debug('%s - start', method);

const {handler, targets, request_timeout} = request;
const {handler, targets, requestTimeout} = request;

const envelope = this.getSignedEnvelope();

Expand All @@ -162,7 +162,7 @@ class Commit extends Proposal {
let bad_result = {};
bad_result.status = 'UNKNOWN';
for (const committer of committers) {
const result = await committer.sendBroadcast(envelope, request_timeout);
const result = await committer.sendBroadcast(envelope, requestTimeout);
if (result.status === 'SUCCESS') {

return result;
Expand Down
42 changes: 21 additions & 21 deletions fabric-common/lib/Committer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,37 @@ const fabprotos = require('fabric-protos');
const logger = getLogger(TYPE);

/**
* @typedef {Error} SYSTEM_TIMEOUT The Error message string that indicates that
* @typedef {Error} SYSTEM TIMEOUT The Error message string that indicates that
* the request operation has timed out due to a system issue. This will
* indicate that the issue is local rather than remote. If there is
* an issue with the remote node a 'REQUEST_TIMEOUT' error message
* an issue with the remote node a 'REQUEST TIMEOUT' error message
* will be returned.
* The operation will only use one timer for both types of timeouts.
* The timer will start running as the operation begins. If the timer
* expires before the local instance is able to make the outbound
* request then 'SYSTEM_TIMEOUT' error will be returned. If the local
* request then 'SYSTEM TIMEOUT' error will be returned. If the local
* instance is able to make the outbound request and the timer expires
* before the remote node responds then the 'REQUEST_TIMEOUT' is
* returned. The timer is controlled by the 'request-timeout' setting
* before the remote node responds then the 'REQUEST TIMEOUT' is
* returned. The timer is controlled by the 'requestTimeout' setting
* or passed on a call that makes an outbound request
* @example 'client.setConfigSetting('request-timeout', 3000)'
* @example 'client.setConfigSetting('requestTimeout', 3000)'
* @example 'channel.sendTranaction(request, 3000)'
*/

/**
* @typedef {Error} REQUEST_TIMEOUT The Error message string that indicates that
* @typedef {Error} REQUEST TIMEOUT The Error message string that indicates that
* the request operation has timed out due to a remote node issue.
* If there is an issue with the local system a 'SYSTEM_TIMEOUT'
* If there is an issue with the local system a 'SYSTEM TIMEOUT'
* error message will be returned.
* The operation will only use one timer for both types of timeouts.
* The timer will start running as the operation begins. If the timer
* expires before the local instance is able to make the outbound
* request then 'SYSTEM_TIMEOUT' error will be returned. If the local
* request then 'SYSTEM TIMEOUT' error will be returned. If the local
* instance is able to make the outbound request and the timer expires
* before the remote node responds then the 'REQUEST_TIMEOUT' is
* returned. The timer is controlled by the 'request-timeout' setting
* before the remote node responds then the 'REQUEST TIMEOUT' is
* returned. The timer is controlled by the 'requestTimeout' setting
* or passed on a call that makes an outbound request
* @example 'client.setConfigSetting('request-timeout', 3000)'
* @example 'client.setConfigSetting('requestTimeout', 3000)'
* @example 'channel.sendTranaction(request, 3000)'
*/

Expand Down Expand Up @@ -101,7 +101,7 @@ class Committer extends ServiceEndpoint {
* response before rejecting the promise with a timeout error. This
* overrides the request-timeout config connection setting of this instance.
* @returns {Promise} A Promise for a {@link BroadcastResponse} object
* @throws {SYSTEM_TIMEOUT | REQUEST_TIMEOUT}
* @throws {SYSTEM TIMEOUT | REQUEST TIMEOUT}
*/
sendBroadcast(envelope, timeout) {
const method = 'sendBroadcast';
Expand All @@ -115,15 +115,15 @@ class Committer extends ServiceEndpoint {
if (this.connected === false) {
throw Error(`Broadcast Client ${this.name} ${this.endpoint.url} is not connected`);
}
let rto = this.options['request-timeout'];
let rto = this.options.requestTimeout;
if (typeof timeout === 'number') {
rto = timeout;
}

const broadcast = this.service.broadcast();
// if it timeouts before the send of the envelope completes
// we will get a SYSTEM_TIMEOUT
let error_msg = 'SYSTEM_TIMEOUT';
// we will get a SYSTEM TIMEOUT
let error_msg = 'SYSTEM TIMEOUT';

const broadcast_timeout = setTimeout(() => {
logger.error(`${this.name} - ${method} timed out after:${rto}`);
Expand All @@ -142,7 +142,7 @@ class Committer extends ServiceEndpoint {
return resolve(response);
} else {
logger.error(`${this.name} ERROR - ${method} reject with invalid response from the committer`);
return reject(new Error('SYSTEM_ERROR'));
return reject(new Error('SYSTEM ERROR'));
}
});

Expand All @@ -157,8 +157,8 @@ class Committer extends ServiceEndpoint {
broadcast.end();
if (err && err.code) {
if (err.code === 14) {
logger.error(`${method} - ${this.name} SERVICE_UNAVAILABLE on error code: ${err.code}`);
return reject(new Error('SERVICE_UNAVAILABLE'));
logger.error(`${method} - ${this.name} SERVICE UNAVAILABLE on error code: ${err.code}`);
return reject(new Error('SERVICE UNAVAILABLE'));
}
}
logger.error(`${method} - ${this.name} on error: ${JSON.stringify(err.stack ? err.stack : err)}`);
Expand All @@ -167,8 +167,8 @@ class Committer extends ServiceEndpoint {

broadcast.write(envelope);
// the send of envelope has completed
// if it timeouts after this point we will get a REQUEST_TIMEOUT
error_msg = 'REQUEST_TIMEOUT';
// if it timeouts after this point we will get a REQUEST TIMEOUT
error_msg = 'REQUEST TIMEOUT';
logger.debug(`${method} - sent message`);
});
}
Expand Down
4 changes: 2 additions & 2 deletions fabric-common/lib/Discoverer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ class Discoverer extends ServiceEndpoint {
if (this.connected === false) {
throw Error(`Discovery Client ${this.name} ${this.endpoint.url} is not connected`);
}
let rto = this.options['request-timeout'];
let rto = this.options.requestTimeout;
if (typeof timeout === 'number') {
rto = timeout;
}

const send_timeout = setTimeout(() => {
clearTimeout(send_timeout);
logger.error(`${method} - timed out after:${rto}`);
return reject(new Error('REQUEST_TIMEOUT'));
return reject(new Error('REQUEST TIMEOUT'));
}, rto);

this.service.discover(signedEnvelope, (err, response) => {
Expand Down
53 changes: 29 additions & 24 deletions fabric-common/lib/Discovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ class Discovery extends ServiceAction {
this.channel = channel;
this.client = channel.client;
this.type = TYPE;
this.refresh_age = 5 * 60 * 1000; // 5 minutes default
this.refreshAge = 5 * 60 * 1000; // 5 minutes default

this.discoveryResults = null;
this.as_localhost = false;
this.asLocalhost = false;

this._current_target = null;

Expand Down Expand Up @@ -209,14 +209,14 @@ class Discovery extends ServiceAction {

/**
* @typedef {Object} DiscoverRequest
* @property {boolean} [as_localhost] - Optional. When discovery is running in a
* @property {boolean} [asLocalhost] - Optional. When discovery is running in a
* virtual environment, the host name of peers and orderers created by this
* service may have to converted to localhost for connections to be established.
* @property {number} [request_timeout] - Optional. The request timeout
* @property {number} [refresh_age] - Optional. The milliseconds before the
* @property {number} [requestTimeout] - Optional. The request timeout
* @property {number} [refreshAge] - Optional. The milliseconds before the
* discovery results will be refreshed automatically. When the {@link Discovery#getDiscoveryResults}
* is called with refresh = true and the age of the discovery results
* is older then 'refresh_age' the current signed request will be sent
* is older then 'refreshAge' the current signed request will be sent
* to the peer's discovery service.
* Default: 5 minutes.
*/
Expand All @@ -231,21 +231,21 @@ class Discovery extends ServiceAction {
const method = `send[${this.name}]`;
logger.debug(`${method} - start`);

const {request_timeout, as_localhost, refresh_age, targets = checkParameter('targets')} = request;
const {requestTimeout, asLocalhost, refreshAge, targets = checkParameter('targets')} = request;

// may be needed later for refresh
this.as_localhost = as_localhost;
this.refresh_age = refresh_age;
this.request_timeout = request_timeout;
this.asLocalhost = asLocalhost;
this.refreshAge = refreshAge;
this.requestTimeout = requestTimeout;
this.targets = targets;

const signed_envelope = this.getSignedEnvelope();
const signedEnvelope = this.getSignedEnvelope();

let response;
for (const target of targets) {
logger.debug(`${method} - about to discover on ${target.endpoint.url}`);
try {
response = await target.sendDiscovery(signed_envelope, this.request_timeout);
response = await target.sendDiscovery(signedEnvelope, this.requestTimeout);
this._current_target = target;
break;
} catch (error) {
Expand Down Expand Up @@ -273,9 +273,9 @@ class Discovery extends ServiceAction {
logger.debug(`${method} - process result index:${index}`);
if (result.config_result) {
logger.debug(`${method} - process result - have config_result in ${index}`);
const config = await this._processConfig(result.config_result);
const config = this._processConfig(result.config_result);
this.discoveryResults.msps = config.msps;
this.discoveryResults.orderers = config.orderers;
this.discoveryResults.orderers = await this._buildOrderers(config.orderers);
}
if (result.members) {
logger.debug(`${method} - process result - have members in ${index}`);
Expand Down Expand Up @@ -313,8 +313,8 @@ class Discovery extends ServiceAction {
if (!this.discoveryResults) {
throw Error('No discovery results found');
}
if (refresh && (new Date()).getTime() - this.discoveryResults.timestamp > this.refresh_age) {
await this.send({as_localhost: this.as_localhost, request_timeout: this.request_timeout, targets: this.targets});
if (refresh && (new Date()).getTime() - this.discoveryResults.timestamp > this.refreshAge) {
await this.send({asLocalhost: this.asLocalhost, requestTimeout: this.requestTimeout, targets: this.targets});
} else {
logger.debug(`${method} - not refreshing`);
}
Expand Down Expand Up @@ -396,7 +396,7 @@ class Discovery extends ServiceAction {
return endorsement_plan;
}

async _processConfig(q_config) {
_processConfig(q_config) {
const method = `_processConfig[${this.name}]`;
logger.debug(`${method} - start`);
const config = {};
Expand Down Expand Up @@ -436,7 +436,6 @@ class Discovery extends ServiceAction {
config.orderers[mspid].endpoints.push(endpoint);
}
}
await this._buildOrderers(config.orderers);
} else {
logger.debug(`${method} - no orderers found`);
}
Expand Down Expand Up @@ -513,12 +512,18 @@ class Discovery extends ServiceAction {
const method = `_buildOrderers[${this.name}]`;
logger.debug(`${method} - start`);

for (const msp_id in orderers) {
logger.debug(`${method} - orderer msp:${msp_id}`);
for (const endpoint of orderers[msp_id].endpoints) {
endpoint.name = this._buildOrderer(endpoint.host, endpoint.port, msp_id);
if (!orderers) {
logger.debug('%s - no orderers to build', method);
} else {
for (const msp_id in orderers) {
logger.debug(`${method} - orderer msp:${msp_id}`);
for (const endpoint of orderers[msp_id].endpoints) {
endpoint.name = await this._buildOrderer(endpoint.host, endpoint.port, msp_id);
}
}
}

return orderers;
}

async _buildOrderer(host, port, msp_id) {
Expand All @@ -528,7 +533,7 @@ class Discovery extends ServiceAction {
const address = `${host}:${port}`;
const found = this.channel.getCommitter(address);
if (found) {
logger.debug(`${method} - orderer is already added to the channel - ${address}`);
logger.debug('%s - orderer is already added to the channel - %s', method, address);
return found.name;
}

Expand Down Expand Up @@ -585,7 +590,7 @@ class Discovery extends ServiceAction {

let t_hostname = hostname;
// endpoints may be running in containers on the local system
if (this.as_localhost) {
if (this.asLocalhost) {
t_hostname = 'localhost';
}

Expand Down
Loading

0 comments on commit b7ce073

Please sign in to comment.