Skip to content

Commit

Permalink
added logic to pick new Peer Gateway connector in the connector selec…
Browse files Browse the repository at this point in the history
…tor in FabriConnectorFactory.js + added 2.4 fabric SUT version with binding packages in .config.yaml + added last fixes for the Peer Gateway connector implementation (#1298)

Signed-off-by: fraVlaca <ocsenarf@outlook.com>
  • Loading branch information
fraVlaca committed Apr 6, 2022
1 parent 7c33aca commit 25f905d
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 45 deletions.
2 changes: 2 additions & 0 deletions packages/caliper-cli/lib/lib/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ sut:
2.2.11: &fabric-v2-lts
packages: ['fabric-network@2.2.11']
2.2: *fabric-v2-lts
2.4:
packages: ['@hyperledger/fabric-gateway@1.0.1']
latest: *fabric-v1-lts
latest-v2-lts: *fabric-v2-lts
latest-v2: *fabric-v2-lts
Expand Down
95 changes: 65 additions & 30 deletions packages/caliper-fabric/lib/FabricConnectorFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,53 +19,87 @@ const ConnectorConfigurationFactory = require('./connector-configuration/Connect
const Logger = CaliperUtils.getLogger('FabricConnectorFactory');
const semver = require('semver');

const NEW_V1_NODE_CONNECTOR = './connector-versions/v1/FabricNonGateway.js';
const NEW_V1_GATEWAY_CONNECTOR = './connector-versions/v1/FabricGateway.js';
const NEW_V1_WALLET_FACADE_FACTORY = './connector-versions/v1/WalletFacadeFactory.js';
const V1_NODE_CONNECTOR = './connector-versions/v1/FabricNonGateway.js';
const V1_GATEWAY_CONNECTOR = './connector-versions/v1/FabricGateway.js';
const V1_WALLET_FACADE_FACTORY = './connector-versions/v1/WalletFacadeFactory.js';

const NEW_V2_GATEWAY_CONNECTOR = './connector-versions/v2/FabricGateway.js';
const NEW_V2_WALLET_FACADE_FACTORY = './connector-versions/v2/WalletFacadeFactory.js';
const V2_GATEWAY_CONNECTOR = './connector-versions/v2/FabricGateway.js';
const V2_WALLET_FACADE_FACTORY = './connector-versions/v2/WalletFacadeFactory.js';

const PEER_GATEWAY_CONNECTOR = './connector-versions/peer-gateway/PeerGateway.js';
const PEER_WALLET_FACADE_FACTORY = './connector-versions/peer-gateway/WalletFacadeFactory.js';

/**
* @returns {string} version
* @typedef {Object} Sdk
* @property {String} module - The sdk module name
* @property {String} version - The version of the sdk module
*/
const _determineInstalledNodeSDKVersion = () => {

/**
* @returns {Sdk} installedSDKmodule and version
*/
const _determineInstalledNodeSDKandVersion = () => {
// Caliper can only work if you use bind and it will pull in fabric network even for non gateway 1.4
let sdk, packageVersion;

if (CaliperUtils.moduleIsInstalled('@hyperledger/fabric-gateway')) {
packageVersion = semver.coerce(require('@hyperledger/fabric-gateway/package').version);
sdk = 'fabric-gateway';
}

if (CaliperUtils.moduleIsInstalled('fabric-network')) {
const packageVersion = require('fabric-network/package').version;
return semver.coerce(packageVersion);
} else {
if (sdk) {
throw new Error('Multiple bindings for fabric have been detected, you need to unbind one or more to ensure only a single bind is present to continue');
}
packageVersion = semver.coerce(require('fabric-network/package').version);
sdk = 'fabric-network';
}


if (!sdk) {
throw new Error('Unable to detect required Fabric binding packages');
}

return {sdk, packageVersion};
};

const _loadAppropriateConnectorClass = (installedNodeSDKVersion) => {
const _loadAppropriateConnectorClass = (installedNodeSdk, version) => {
let connectorPath;
let walletFacadeFactoryPath;

if (semver.satisfies(installedNodeSDKVersion, '=1.x')) {
const useGateway = ConfigUtil.get(ConfigUtil.keys.Fabric.Gateway.Enabled, false);
Logger.info(`Initializing ${useGateway ? 'gateway' : 'standard' } connector compatible with installed SDK: ${installedNodeSDKVersion}`);
if (installedNodeSdk === 'fabric-network') {
if (semver.satisfies(version, '=1.x')) {
const useGateway = ConfigUtil.get(ConfigUtil.keys.Fabric.Gateway.Enabled, false);
Logger.info(`Initializing ${useGateway ? 'gateway' : 'standard' } connector compatible with installed fabric-network SDK: ${version}`);

if (!useGateway) {
connectorPath = NEW_V1_NODE_CONNECTOR;
walletFacadeFactoryPath = NEW_V1_WALLET_FACADE_FACTORY;
} else {
// gateway with default event handlers appears in SDK > 1.4.2
if (semver.satisfies(installedNodeSDKVersion, '>=1.4.2')) {
connectorPath = NEW_V1_GATEWAY_CONNECTOR;
walletFacadeFactoryPath = NEW_V1_WALLET_FACADE_FACTORY;
if (!useGateway) {
connectorPath = V1_NODE_CONNECTOR;
walletFacadeFactoryPath = V1_WALLET_FACADE_FACTORY;
} else {
throw new Error('Caliper currently only supports Fabric gateway based operation using Fabric-SDK 1.4.2 and higher. Please retry with a different SDK binding');
// gateway with default event handlers appears in SDK > 1.4.2
if (semver.satisfies(version, '>=1.4.2')) {
connectorPath = V1_GATEWAY_CONNECTOR;
walletFacadeFactoryPath = V1_WALLET_FACADE_FACTORY;
} else {
throw new Error('Caliper currently only supports Fabric gateway based operation using Fabric-SDK 1.4.2 and higher. Please retry with a different SDK binding');
}
}
} else if (semver.satisfies(version, '=2.x')) {
Logger.info(`Initializing gateway connector compatible with installed SDK: ${version}`);
connectorPath = V2_GATEWAY_CONNECTOR;
walletFacadeFactoryPath = V2_WALLET_FACADE_FACTORY;
} else {
throw new Error(`Installed fabric-network SDK version ${version} did not match any compatible Fabric connectors`);
}
} else if (semver.satisfies(installedNodeSDKVersion, '=2.x')) {
Logger.info(`Initializing gateway connector compatible with installed SDK: ${installedNodeSDKVersion}`);
connectorPath = NEW_V2_GATEWAY_CONNECTOR;
walletFacadeFactoryPath = NEW_V2_WALLET_FACADE_FACTORY;
} else {
throw new Error(`Installed SDK version ${installedNodeSDKVersion} did not match any compatible Fabric connectors`);
// can only be fabric-gateway binding due to check done in _determineInstalledNodeSDKandVersion
if (semver.satisfies(version, '=1.x')) {
Logger.info(`Initializing peer gateway connector compatible with installed fabric-gateway SDK: ${version}`);
connectorPath = PEER_GATEWAY_CONNECTOR;
walletFacadeFactoryPath = PEER_WALLET_FACADE_FACTORY;
} else {
throw new Error(`Installed fabric-gateway SDK version ${version} did not match any compatible Fabric connectors`);
}
}

const fabricConnectorClass = require(connectorPath);
Expand Down Expand Up @@ -95,8 +129,9 @@ const connectorFactory = async (workerIndex) => {
throw new Error(`Unknown network configuration version ${loadedConnectorConfiguration.version} specified`);
}

const installedNodeSDKVersion = _determineInstalledNodeSDKVersion();
const {fabricConnectorClass, walletFacadeFactoryClass} = _loadAppropriateConnectorClass(installedNodeSDKVersion);
const sdk = _determineInstalledNodeSDKandVersion();

const {fabricConnectorClass, walletFacadeFactoryClass} = _loadAppropriateConnectorClass(sdk.sdk, sdk.packageVersion);
const connectorConfiguration = await new ConnectorConfigurationFactory().create(connectorConfigurationFile, new walletFacadeFactoryClass());
const fabricConnector = new fabricConnectorClass(connectorConfiguration, workerIndex, 'fabric');

Expand Down
48 changes: 44 additions & 4 deletions packages/caliper-fabric/test/FabricConnectorFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const { ConfigUtil } = require('@hyperledger/caliper-core');
const unsupportedConfig = './sample-configs/LegacyNetworkConfig.yaml';
const v2Config = './sample-configs/NoIdentitiesNetworkConfig.yaml';
const unknownVersionConfig = './sample-configs/UnknownVersionConfig.yaml';
const peerGatewayConfig = './sample-configs/BasicConfig.yaml';

const DefaultEventHandlerStrategies = {};
const DefaultQueryHandlerStrategies = {};
Expand Down Expand Up @@ -163,20 +164,59 @@ describe('A Fabric Connector Factory', () => {
mockery.deregisterAll();
});

it('should create a Peer Gateway Fabric connector if a 1.x fabric-gateway library is bound', async () => {
mockery.registerMock('@hyperledger/fabric-gateway', {});
mockery.registerMock('@hyperledger/fabric-gateway/package', {version: '1.0.1'});
mockery.registerMock('@grpc/grpc-js', {});
ConfigUtil.set(ConfigUtil.keys.NetworkConfig, path.resolve(__dirname, peerGatewayConfig));
ConfigUtil.set(ConfigUtil.keys.Fabric.Gateway.Enabled, false);
const connector = await ConnectorFactory(1);
connector.constructor.name.should.equal('PeerGateway');
mockery.deregisterAll();
});

it('should throw an error if no fabric library is bound', async () => {
// Can't test this with mockery because really need require to fail trying to
// find `fabric-network` or `fabric-client`
ConfigUtil.set(ConfigUtil.keys.NetworkConfig, path.resolve(__dirname, peerGatewayConfig));
ConfigUtil.set(ConfigUtil.keys.Fabric.Gateway.Enabled, true);
await ConnectorFactory(1).should.be.rejectedWith(/Unable to detect required Fabric binding packages/);
});

it('should throw an error if fabric-gateway library bound is not than v1.x', async () => {
mockery.registerMock('@hyperledger/fabric-gateway', {});
mockery.registerMock('@hyperledger/fabric-gateway/package', {version: '0.5.0'});
ConfigUtil.set(ConfigUtil.keys.NetworkConfig, path.resolve(__dirname, peerGatewayConfig));
ConfigUtil.set(ConfigUtil.keys.Fabric.Gateway.Enabled, true);
await ConnectorFactory(1).should.be.rejectedWith(/Installed fabric-gateway SDK version 0.5.0 did not match any compatible Fabric connectors/);
mockery.deregisterAll();
mockery.registerMock('@hyperledger/fabric-gateway', {});
mockery.registerMock('@hyperledger/fabric-gateway/package', {version: '2.5.0'});
await ConnectorFactory(1).should.be.rejectedWith(/Installed fabric-gateway SDK version 2.5.0 did not match any compatible Fabric connectors/);
mockery.deregisterAll();
});

it('should throw an error if fabric network library bound is not v1.4, v2.x', async () => {
mockery.registerMock('fabric-network', {});
mockery.registerMock('fabric-network/package', {version: '3.0.0'});
ConfigUtil.set(ConfigUtil.keys.NetworkConfig, path.resolve(__dirname, v2Config));
ConfigUtil.set(ConfigUtil.keys.Fabric.Gateway.Enabled, true);
await ConnectorFactory(1).should.be.rejectedWith(/Installed fabric-network SDK version 3.0.0 did not match any compatible Fabric connectors/);
mockery.deregisterAll();
});

it('should throw an error if fabric library bound is not V1 or V2', async () => {
it('should throw an error if both fabric-network and fabric-gateway are bound', async () => {
mockery.registerMock('fabric-network', {});
mockery.registerMock('fabric-network/package', {version: '3.0.0'});
ConfigUtil.set(ConfigUtil.keys.NetworkConfig, path.resolve(__dirname, v2Config));
ConfigUtil.set(ConfigUtil.keys.Fabric.Gateway.Enabled, true);
await ConnectorFactory(1).should.be.rejectedWith(/Installed SDK version 3.0.0 did not match any compatible Fabric connectors/);
mockery.registerMock('@hyperledger/fabric-gateway', {});
mockery.registerMock('@hyperledger/fabric-gateway/package', {version: '1.0.1'});
ConfigUtil.set(ConfigUtil.keys.NetworkConfig, path.resolve(__dirname, peerGatewayConfig));
ConfigUtil.set(ConfigUtil.keys.Fabric.Gateway.Enabled, true);
await ConnectorFactory(1).should.be.rejectedWith(/Multiple bindings for fabric have been detected, you need to unbind one or more to ensure only a single bind is present to continue/);
mockery.deregisterAll();
});


it('should throw a generic error if network configuration version is not 1.0 or 2.0', async () => {
mockery.registerMock('fabric-network', {});
mockery.registerMock('fabric-network/package', {version: '1.4.11'});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ describe('A Fabric Peer Gateway sdk gateway', () => {
});


it('should pass a defined grpcClinet in the gateway options', async () => {
it('should pass a defined grpcClient in the gateway options', async () => {
const connectorConfiguration = await new ConnectorConfigurationFactory().create(path.resolve(__dirname, configWith2Orgs1AdminInWalletNotMutual), walletFacadeFactory);
const peerGateway = new PeerGateway(connectorConfiguration, 1, 'fabric');
await peerGateway.getContext();
Expand All @@ -137,16 +137,6 @@ describe('A Fabric Peer Gateway sdk gateway', () => {
clock.restore();
});

it('should pass the default timeout in the gateway options', async () => {
const connectorConfiguration = await new ConnectorConfigurationFactory().create(path.resolve(__dirname, configWith2Orgs1AdminInWalletNotMutual), walletFacadeFactory);
const peerGateway = new PeerGateway(connectorConfiguration, 1, 'fabric');
const now = new Date();
const clock = sinon.useFakeTimers(now.getTime());
await peerGateway.getContext();
Gateway.connectArgs[0].evaluateOptions().should.be.deep.equal({deadline: now.getTime() + 60000});
clock.restore();
});

it('should pass the timeout from invokeOrQuery in the gateway options', async () => {
ConfigUtil.set(ConfigUtil.keys.Fabric.Timeout.InvokeOrQuery, 99);
const connectorConfiguration = await new ConnectorConfigurationFactory().create(path.resolve(__dirname, configWith2Orgs1AdminInWalletNotMutual), walletFacadeFactory);
Expand Down Expand Up @@ -175,6 +165,14 @@ describe('A Fabric Peer Gateway sdk gateway', () => {
Gateway.constructed.should.equal(4);
});


it('should create a Gateway with the specified created identity', async () => {
const connectorConfiguration = await new ConnectorConfigurationFactory().create(path.resolve(__dirname, configWith2Orgs1AdminInWalletNotMutual), walletFacadeFactory);
const peerGateway = new PeerGateway(connectorConfiguration, 1, 'fabric');
await peerGateway.getContext();
Gateway.connectArgs[0].identity.should.deep.equal({mspId: 'Org1MSP', credentials: Buffer.from('-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----')});
});

it('should a attempt to create a grpc client with default grpc options when not provided through the connection profile', async () => {
const connectorConfiguration = await new ConnectorConfigurationFactory().create(path.resolve(__dirname, configWith2Orgs1AdminInWalletNotMutual), walletFacadeFactory);
const peerGateway = new PeerGateway(connectorConfiguration, 1, 'fabric');
Expand Down

0 comments on commit 25f905d

Please sign in to comment.