Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fabric): serialization of ccp and sshconfig #3578

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import temp from "temp";
import fs from "fs/promises";

import {
Config as SshConfig,
NodeSSH,
SSHExecCommandOptions,
SSHExecCommandResponse,
Expand Down Expand Up @@ -35,6 +36,7 @@ export interface IDeployContractGoSourceImplFabricV256Context {
readonly log: Logger;
readonly className: string;
readonly dockerBinary: string;
readonly sshConfig: SshConfig;
readonly opts: IPluginLedgerConnectorFabricOptions;
}

Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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 });
Expand Down Expand Up @@ -277,9 +280,34 @@ export class PluginLedgerConnectorFabric
});
this.certStore = new CertDatastore(opts.pluginRegistry);

if (this.opts.connectionProfile) {
this.connectionProfile = this.opts.connectionProfile;
}
if (this.opts.connectionProfileB64) {
const connectionProfileBuffer = Buffer.from(
this.opts.connectionProfileB64,
"base64",
);
const connectionProfileString = connectionProfileBuffer.toString("utf-8");
this.connectionProfile = JSON.parse(connectionProfileString);
} else {
throw new Error(
"Cannot instantiate Fabric connector without connection profile.",
);
}

this.sshDebugOn = opts.sshDebugOn === true;
if (this.opts.sshConfig) {
this.sshConfig = this.opts.sshConfig;
} else if (this.opts.sshConfigB64) {
const sshConfigBuffer = Buffer.from(this.opts.sshConfigB64, "base64");
const sshConfigString = sshConfigBuffer.toString("utf-8");
this.sshConfig = JSON.parse(sshConfigString);
} else {
throw new Error("Cannot instantiate Fabric connector without SSH config");
}
if (this.sshDebugOn) {
this.opts.sshConfig = this.enableSshDebugLogs(this.opts.sshConfig);
this.sshConfig = this.enableSshDebugLogs(this.sshConfig);
}

this.signCallback = opts.signCallback;
Expand Down Expand Up @@ -361,11 +389,11 @@ export class PluginLedgerConnectorFabric
req: DeployContractV1Request,
): Promise<DeployContractV1Response> {
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) {
Expand Down Expand Up @@ -666,6 +694,7 @@ export class PluginLedgerConnectorFabric
log,
opts: this.opts,
dockerBinary: this.dockerBinary,
sshConfig: this.sshConfig,
className: this.className,
};
return deployContractGoSourceImplFabricV256(ctx, req);
Expand Down Expand Up @@ -910,7 +939,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,
Expand All @@ -935,7 +964,8 @@ export class PluginLedgerConnectorFabric
protected async createGatewayLegacy(
signingCredential: FabricSigningCredential,
): Promise<Gateway> {
const { connectionProfile, eventHandlerOptions: eho } = this.opts;
const { eventHandlerOptions: eho } = this.opts;
const connectionProfile = this.connectionProfile;

const iType = signingCredential.type || FabricSigningCredentialType.X509;

Expand Down Expand Up @@ -1264,7 +1294,7 @@ export class PluginLedgerConnectorFabric
public async createCaClient(caId: string): Promise<FabricCAServices> {
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.`);
}
Expand Down Expand Up @@ -1669,7 +1699,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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
Loading