Skip to content

Commit

Permalink
feat(connector-fabric): identity json signing credentials hyperledger…
Browse files Browse the repository at this point in the history
…#1130

Introduces a new, optional (for now) parameter on the run tx
endpoint's request object called gatewayOptions which is capable
of including everything that one needs to instantiate a gateway
object of the underlying Fabric Node SDK.

This change makes it possible to not need the keychain plugin
at all when someone does not need/want it.

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed Jul 14, 2021
1 parent b6f3b89 commit c04172f
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
"ChainCodeLifeCycleCommandResponses": {
"type": "object",
"required": [
"queryInstalledList", "approveForMyOrgList", "installList"
"queryInstalledList",
"approveForMyOrgList",
"installList"
],
"properties": {
"packaging": {
Expand Down Expand Up @@ -184,6 +186,42 @@
}
}
},
"GatewayOptions": {
"type": "object",
"required": ["identity", "wallet"],
"properties": {
"connectionProfile": {
"$ref": "#/components/schemas/ConnectionProfile"
},
"discovery": {
"$ref": "#/components/schemas/GatewayDiscoveryOptions",
"nullable": false
},
"eventHandlerOptions": {
"$ref": "#/components/schemas/GatewayEventHandlerOptions",
"nullable": false
},
"identity": {
"type": "string"
},
"wallet": {
"type": "object",
"minProperties": 1,
"maxProperties": 1,
"properties": {
"keychain": {
"$ref": "#/components/schemas/FabricSigningCredential"
},
"json": {
"type": "string",
"nullable": false,
"minLength": 1,
"maxLength": 65535
}
}
}
}
},
"DefaultEventHandlerStrategy": {
"type": "string",
"enum": [
Expand All @@ -204,6 +242,10 @@
"type": "number",
"nullable": false
},
"endorseTimeout": {
"type": "number",
"nullable": false
},
"strategy": {
"description": "The name of the strategy to be used when looking up the TxEventHandlerFactory to pass in to the Fabric Gateway as the strategy property of the discovery options.",
"$ref": "#/components/schemas/DefaultEventHandlerStrategy"
Expand Down Expand Up @@ -293,6 +335,10 @@
"type": "object",
"nullable": true
},
"gatewayOptions": {
"$ref": "#/components/schemas/GatewayOptions",
"nullable": false
},
"signingCredential": {
"$ref": "#/components/schemas/FabricSigningCredential",
"nullable": false
Expand Down Expand Up @@ -329,7 +375,6 @@
"nullable": true
}
},

"endorsingParties": {
"type": "array",
"nullable": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { DefaultEventHandlerOptions } from "fabric-network";
import { DefaultEventHandlerStrategies, Wallets } from "fabric-network";
import { Gateway } from "fabric-network";
import { GatewayOptions as FabricGatewayOptions } from "fabric-network";
import { Checks, LoggerProvider } from "@hyperledger/cactus-common";
import { LogLevelDesc } from "@hyperledger/cactus-common";
import { PluginRegistry } from "@hyperledger/cactus-core";
import { ConnectionProfile } from "../generated/openapi/typescript-axios/index";
import { GatewayDiscoveryOptions } from "../generated/openapi/typescript-axios/index";
import { GatewayEventHandlerOptions } from "../generated/openapi/typescript-axios/index";
import { GatewayOptions } from "../generated/openapi/typescript-axios/index";

export interface ICreateGatewayContext {
readonly logLevel?: LogLevelDesc;
readonly pluginRegistry: PluginRegistry;
readonly defaultConnectionProfile: ConnectionProfile;
readonly defaultDiscoveryOptions: GatewayDiscoveryOptions;
readonly defaultEventHandlerOptions: GatewayEventHandlerOptions;
readonly gatewayOptions: GatewayOptions;
}

export const E_CREATE_GATEWAY_WALLET =
"Invalid opts.gatewayOptions.wallet. Need json or keychain, none provided.";

export async function createGateway(
ctx: ICreateGatewayContext,
): Promise<Gateway> {
const log = LoggerProvider.getOrCreate({
label: "create-gateway",
level: ctx?.logLevel || "INFO",
});
log.debug("Creating Fabric Node SDK Gateway object...");

Checks.truthy(ctx, "createGateway#ctx");
Checks.truthy(ctx.gatewayOptions, "createGateway#ctx.gatewayOptions");

const { defaultConnectionProfile } = ctx;
const cp = ctx.gatewayOptions.connectionProfile || defaultConnectionProfile;

const wallet = await Wallets.newInMemoryWallet();

let identity;
if (ctx.gatewayOptions.wallet.json) {
log.debug("Parsing wallet from JSON representation...");
identity = JSON.parse(ctx.gatewayOptions.wallet.json);
} else if (ctx.gatewayOptions.wallet.keychain) {
log.debug("Fetching wallet from JSON keychain...");
const keychain = ctx.pluginRegistry.findOneByKeychainId(
ctx.gatewayOptions.wallet.keychain.keychainId,
);
identity = await keychain.get<string>(
ctx.gatewayOptions.wallet.keychain.keychainRef,
);
} else {
throw new Error(E_CREATE_GATEWAY_WALLET);
}

await wallet.put(ctx.gatewayOptions.identity, identity);
log.debug(`Imported identity ${ctx.gatewayOptions.identity} to wallet OK`);

const eventHandlerOptions: DefaultEventHandlerOptions = {
commitTimeout: ctx.gatewayOptions.eventHandlerOptions?.commitTimeout || 300,
endorseTimeout:
ctx.gatewayOptions.eventHandlerOptions?.endorseTimeout || 300,
};

const strategy =
ctx.gatewayOptions.eventHandlerOptions?.strategy ||
ctx.defaultEventHandlerOptions.strategy;

if (strategy) {
eventHandlerOptions.strategy = DefaultEventHandlerStrategies[strategy];
}

log.debug(`Gateway EventHandlerOptions: `, eventHandlerOptions);

const gatewayOptions: FabricGatewayOptions = {
discovery: ctx.gatewayOptions.discovery || ctx.defaultDiscoveryOptions,
eventHandlerOptions,
identity: ctx.gatewayOptions.identity,
wallet,
};

log.debug("Instantiating and connecting gateway...");

const gateway = new Gateway();
await gateway.connect(cp, gatewayOptions);

log.debug("Connection established by gateway OK");

return gateway;
}
Original file line number Diff line number Diff line change
Expand Up @@ -592,13 +592,75 @@ export interface GatewayEventHandlerOptions {
* @memberof GatewayEventHandlerOptions
*/
commitTimeout?: number;
/**
*
* @type {number}
* @memberof GatewayEventHandlerOptions
*/
endorseTimeout?: number;
/**
*
* @type {DefaultEventHandlerStrategy}
* @memberof GatewayEventHandlerOptions
*/
strategy: DefaultEventHandlerStrategy;
}
/**
*
* @export
* @interface GatewayOptions
*/
export interface GatewayOptions {
/**
*
* @type {ConnectionProfile}
* @memberof GatewayOptions
*/
connectionProfile?: ConnectionProfile;
/**
*
* @type {GatewayDiscoveryOptions}
* @memberof GatewayOptions
*/
discovery?: GatewayDiscoveryOptions;
/**
*
* @type {GatewayEventHandlerOptions}
* @memberof GatewayOptions
*/
eventHandlerOptions?: GatewayEventHandlerOptions;
/**
*
* @type {string}
* @memberof GatewayOptions
*/
identity: string;
/**
*
* @type {GatewayOptionsWallet}
* @memberof GatewayOptions
*/
wallet: GatewayOptionsWallet;
}
/**
*
* @export
* @interface GatewayOptionsWallet
*/
export interface GatewayOptionsWallet {
/**
*
* @type {FabricSigningCredential}
* @memberof GatewayOptionsWallet
*/
keychain?: FabricSigningCredential;
/**
*
* @type {string}
* @memberof GatewayOptionsWallet
*/
json?: string;
}
/**
*
* @export
Expand All @@ -624,6 +686,12 @@ export interface RunTransactionRequest {
* @memberof RunTransactionRequest
*/
transientData?: object | null;
/**
*
* @type {GatewayOptions}
* @memberof RunTransactionRequest
*/
gatewayOptions?: GatewayOptions;
/**
*
* @type {FabricSigningCredential}
Expand Down
Loading

0 comments on commit c04172f

Please sign in to comment.