From f6779c618980827a4f85d9facd262728d7297571 Mon Sep 17 00:00:00 2001 From: jagpreetsinghsasan Date: Mon, 21 Oct 2024 08:12:44 +0000 Subject: [PATCH] feat(fabric): serialization of ccp and sshconfig Primary Changes --------------- 1. sshConfig and connectionProfile can now be passed as base64 encoded strings Changes required to incorporate 1) --------------------------------- 2. Added sshConfigBase64Encoded and connectionProfileBase64encoded properties to IPluginLedgerConnectorFabricOptions 3. Added necessary FabricConnector class variables 4. Added a new testcase to demonstrate the same 5. Updated an implementation which fetches sshConfig from class variable Fixes #3577 Signed-off-by: jagpreetsinghsasan --- ...y-contract-go-source-impl-fabric-v2-5-6.ts | 4 +- .../plugin-ledger-connector-fabric.ts | 44 ++++++++++++++----- .../run-transaction-endpoint-v1.test.ts | 26 +++++++++++ 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6.ts index 1176f6eabf..55244970f9 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6.ts @@ -3,6 +3,7 @@ import temp from "temp"; import fs from "fs/promises"; import { + Config as SshConfig, NodeSSH, SSHExecCommandOptions, SSHExecCommandResponse, @@ -35,6 +36,7 @@ export interface IDeployContractGoSourceImplFabricV256Context { readonly log: Logger; readonly className: string; readonly dockerBinary: string; + readonly sshConfig: SshConfig; readonly opts: IPluginLedgerConnectorFabricOptions; } @@ -53,7 +55,7 @@ export async function deployContractGoSourceImplFabricV256( ctx.opts.cliContainerGoPath || K_DEFAULT_CLI_CONTAINER_GO_PATH; const ssh = new NodeSSH(); - await ssh.connect(ctx.opts.sshConfig); + await ssh.connect(ctx.sshConfig); log.debug(`SSH connection OK`); try { diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts index b0f2fe0c07..82614369ed 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts @@ -189,9 +189,11 @@ export interface IPluginLedgerConnectorFabricOptions cliContainerGoPath?: string; cliContainerEnv: NodeJS.ProcessEnv; pluginRegistry: PluginRegistry; - sshConfig: SshConfig; + sshConfig?: SshConfig; + sshConfigB64?: string; readonly sshDebugOn?: boolean; - connectionProfile: ConnectionProfile; + connectionProfile?: ConnectionProfile; + connectionProfileB64?: string; prometheusExporter?: PrometheusExporter; discoveryOptions?: GatewayDiscoveryOptions; eventHandlerOptions?: GatewayEventHandlerOptions; @@ -219,6 +221,8 @@ export class PluginLedgerConnectorFabric private readonly peerBinary: string; private readonly goBinary: string; private readonly cliContainerGoPath: string; + private readonly sshConfig!: SshConfig; + private readonly connectionProfile!: ConnectionProfile; public prometheusExporter: PrometheusExporter; private endpoints: IWebServiceEndpoint[] | undefined; private readonly secureIdentity: SecureIdentityProviders; @@ -241,7 +245,6 @@ export class PluginLedgerConnectorFabric Checks.truthy(opts.instanceId, `${fnTag} options.instanceId`); Checks.truthy(opts.peerBinary, `${fnTag} options.peerBinary`); Checks.truthy(opts.pluginRegistry, `${fnTag} options.pluginRegistry`); - Checks.truthy(opts.connectionProfile, `${fnTag} options.connectionProfile`); this.prometheusExporter = opts.prometheusExporter || new PrometheusExporter({ pollingIntervalInMin: 1 }); @@ -277,9 +280,28 @@ export class PluginLedgerConnectorFabric }); this.certStore = new CertDatastore(opts.pluginRegistry); + if (this.opts.connectionProfile) + this.connectionProfile = this.opts.connectionProfile; + if (this.opts.connectionProfileB64 && !this.connectionProfile) { + const connectionProfileBuffer = Buffer.from( + this.opts.connectionProfileB64, + "base64", + ); + const connectionProfileString = connectionProfileBuffer.toString("utf-8"); + this.connectionProfile = JSON.parse(connectionProfileString); + } + Checks.truthy(this.connectionProfile != null, `${fnTag}:connectionProfile`); + this.sshDebugOn = opts.sshDebugOn === true; + if (this.opts.sshConfig) this.sshConfig = this.opts.sshConfig; + if (this.opts.sshConfigB64 && !this.sshConfig) { + const sshConfigBuffer = Buffer.from(this.opts.sshConfigB64, "base64"); + const sshConfigString = sshConfigBuffer.toString("utf-8"); + this.sshConfig = JSON.parse(sshConfigString); + } + Checks.truthy(this.sshConfig != null, `${fnTag}:sshConfig`); if (this.sshDebugOn) { - this.opts.sshConfig = this.enableSshDebugLogs(this.opts.sshConfig); + this.sshConfig = this.enableSshDebugLogs(this.sshConfig); } this.signCallback = opts.signCallback; @@ -361,11 +383,11 @@ export class PluginLedgerConnectorFabric req: DeployContractV1Request, ): Promise { const fnTag = `${this.className}#deployContract()`; - const { log, opts } = this; + const { log } = this; const ssh = new NodeSSH(); this.log.debug(`${fnTag} Establishing SSH connection to peer...`); - await ssh.connect(opts.sshConfig); + await ssh.connect(this.sshConfig); this.log.debug(`${fnTag} Established SSH connection to peer OK.`); if (req.collectionsConfigFile) { @@ -666,6 +688,7 @@ export class PluginLedgerConnectorFabric log, opts: this.opts, dockerBinary: this.dockerBinary, + sshConfig: this.sshConfig, className: this.className, }; return deployContractGoSourceImplFabricV256(ctx, req); @@ -910,7 +933,7 @@ export class PluginLedgerConnectorFabric return createGateway({ logLevel: this.opts.logLevel, pluginRegistry: this.opts.pluginRegistry, - defaultConnectionProfile: this.opts.connectionProfile, + defaultConnectionProfile: this.connectionProfile, defaultDiscoveryOptions: this.opts.discoveryOptions || { enabled: true, asLocalhost: true, @@ -935,7 +958,8 @@ export class PluginLedgerConnectorFabric protected async createGatewayLegacy( signingCredential: FabricSigningCredential, ): Promise { - const { connectionProfile, eventHandlerOptions: eho } = this.opts; + const { eventHandlerOptions: eho } = this.opts; + const connectionProfile = this.connectionProfile; const iType = signingCredential.type || FabricSigningCredentialType.X509; @@ -1264,7 +1288,7 @@ export class PluginLedgerConnectorFabric public async createCaClient(caId: string): Promise { const fnTag = `${this.className}#createCaClient()`; try { - const ccp = this.opts.connectionProfile; + const ccp = this.connectionProfile; if (!ccp.certificateAuthorities) { throw new Error(`${fnTag} conn. profile certificateAuthorities falsy.`); } @@ -1669,7 +1693,7 @@ export class PluginLedgerConnectorFabric this.log.debug("Create Fabric Client without a signer with ID", clientId); const client = new Client(clientId); // Use fabric SDK methods for parsing connection profile into Client structure - await loadFromConfig(client, this.opts.connectionProfile); + await loadFromConfig(client, this.connectionProfile); // Create user const user = User.createUser("", "", signerMspID, signerCertificate); diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts index a1933710c4..e45e833d4a 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts @@ -251,6 +251,32 @@ describe(testCase, () => { } { + const connectionProfileString = JSON.stringify(connectionProfile); + const connectionProfileB64Buffer = Buffer.from(connectionProfileString); + const sshConfigString = JSON.stringify(sshConfig); + const connectionProfileB64 = + connectionProfileB64Buffer.toString("base64"); + const sshConfigB64Buffer = Buffer.from(sshConfigString); + const sshConfigB64 = sshConfigB64Buffer.toString("base64"); + const pluginOptionsSerialized: IPluginLedgerConnectorFabricOptions = { + instanceId: uuidv4(), + pluginRegistry, + sshConfigB64, + cliContainerEnv: {}, + peerBinary: "/fabric-samples/bin/peer", + logLevel, + connectionProfileB64, + discoveryOptions, + eventHandlerOptions: { + strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx, + commitTimeout: 300, + }, + }; + const pluginWithSerializedInputs = new PluginLedgerConnectorFabric( + pluginOptionsSerialized, + ); + await pluginWithSerializedInputs.getOrCreateWebServices(); + await pluginWithSerializedInputs.registerWebServices(expressApp); const req: RunTransactionRequest = { signingCredential, gatewayOptions: {