From e50d9cef081708d7d6b92701f7f941c36ef6f920 Mon Sep 17 00:00:00 2001 From: Peter Somogyvari Date: Thu, 12 Nov 2020 12:38:29 -0800 Subject: [PATCH] feat(core-api): add instanceId getter to ICactusPlugin This will enable us to differentiate between instances of the same plugin class at runtime which is a pre- requisite for having intra-node routing among plugins and also for better supporting fine grained dependency injection at runtime where a certain plugin wants to import another one and it's not enough to have the plugin aspect available or even the exact class that was instantiated. An example of the above situation would be where you have multiple different ledger connectors who all need their own keychain plugins that may be connecting to different underlying key management solutions because of some exotic deployment topology where let's say you keep your keys for your Fabric legder in a Vault instance but the Corda or Besu related private keys are in the built-in KMS of your cloud provider of choice. In this situation you might need two separate instances of the keychain plugin and the ledger connectors need to have the ability to import exactly the instance of them that they need otherwise they'll be talking to the wrong KMS backend and that is not just a security hole but but also just breaks everything in the Cactus node. Lots of files had to be changed for this one simple change in the interface because it's a new mandatory method prescribed for every single class that claims to implement a Cactus plugin. So because of that the diff is huge but you should be looking at this one in particular: ./packages/cactus-core-api/src/main/typescript/plugin/i-cactus-plugin.ts Signed-off-by: Peter Somogyvari --- .../main/typescript/plugin/i-cactus-plugin.ts | 49 +++++++++++++++++++ .../src/main/typescript/public-api.ts | 6 ++- .../typescript/plugin-consortium-manual.ts | 15 +++++- .../package.json | 3 +- .../typescript/plugin-factory-keychain.ts | 7 ++- .../main/typescript/plugin-keychain-memory.ts | 16 +++++- .../package.json | 3 +- .../typescript/plugin-factory-kv-storage.ts | 7 ++- .../typescript/plugin-kv-storage-memory.ts | 16 +++++- .../plugin-ledger-connector-besu.ts | 15 +++++- .../deploy-contract-from-json.ts | 2 + .../plugin-ledger-connector-fabric.ts | 12 ++++- .../deploy-cc-from-golang-source.test.ts | 2 + .../plugin-ledger-connector-quorum.ts | 11 ++++- .../deploy-contract-from-json.test.ts | 1 + .../main/typescript/plugin-validator-besu.ts | 11 ++++- .../api-client-routing-node-to-node.test.ts | 4 ++ .../get-consortium-jws-endpoint.test.ts | 3 ++ ...security-isolation-via-api-server-ports.ts | 4 +- .../deploy-contract-via-web-service.test.ts | 4 +- .../sign-transaction-endpoint.test.ts | 2 + 21 files changed, 175 insertions(+), 18 deletions(-) diff --git a/packages/cactus-core-api/src/main/typescript/plugin/i-cactus-plugin.ts b/packages/cactus-core-api/src/main/typescript/plugin/i-cactus-plugin.ts index f48b19b610..9890492448 100644 --- a/packages/cactus-core-api/src/main/typescript/plugin/i-cactus-plugin.ts +++ b/packages/cactus-core-api/src/main/typescript/plugin/i-cactus-plugin.ts @@ -1,9 +1,58 @@ import { PluginAspect } from "./plugin-aspect"; +/** + * The common interface definiton that plugin classes can use to inherit from + * when defining their own options interface for their constructors. + * + * Not all plugins need to have a unique plugin ID, so if the plugin you are + * working does not, it is okay to provide a dummy implementation, but it is + * not really recommended. Instead the constructor of your plugin should + * generate one automatically at runtime if you definitely do not want the + * caller of your plugin class to have to provide an instanceID. + * + * For example if you have a ledger called `FooBar` then this could be seen as + * a recommended implementation: + * + * ```typescript + * + * interface IPluginLedgerConnectorFooBarOptions extends ICactusPluginOptions { + * logLevel?: LogLevelDesc; + * // your other FooBar specific parameters here + * } + * + * class PluginLedgerConnectorFooBar implements ICactusPlugin { + * constructor(public readonly options: IPluginLedgerConnectorFooBarOptions) { + * // your constructor logic here + * } + * + * public getInstanceId(): string { + * // this works because your {IPluginLedgerConnectorFooBarOptions} + * // inherits from the ICactusPluginOptions interface. + * return this.options.instanceId; + * } + * ``` + * + */ +export interface ICactusPluginOptions { + instanceId: string; +} + /** * This is the common base for all other plugin interface definitions to have as a parent. */ export interface ICactusPlugin { + /** + * Returns a string that uniquely identifies the specific instance of a plugin + * from other instances that may have been created from the exact same class. + * We need this to cover scenarios where identical plugin implementations + * need to be used because for example you have two different deployments of + * the same kind of ledger, leading to you needing two separate instances of + * the same kind of plugin in the plugin registry as well. + * + * @see {ICactusPluginOptions} For further details relevant to the instanceId + */ + getInstanceId(): string; + /** * Returns the NodeJS/npm package name of the plugin which is used to identify * plugin instances at runtime and differentiate them from other types of plugins. diff --git a/packages/cactus-core-api/src/main/typescript/public-api.ts b/packages/cactus-core-api/src/main/typescript/public-api.ts index 4ff76c9b24..f48d80eeaa 100755 --- a/packages/cactus-core-api/src/main/typescript/public-api.ts +++ b/packages/cactus-core-api/src/main/typescript/public-api.ts @@ -9,6 +9,10 @@ export { } from "./plugin/web-service/i-plugin-web-service"; export { IWebServiceEndpoint } from "./plugin/web-service/i-web-service-endpoint"; export { PluginFactory } from "./plugin/plugin-factory"; -export { ICactusPlugin, isICactusPlugin } from "./plugin/i-cactus-plugin"; +export { + ICactusPlugin, + ICactusPluginOptions, + isICactusPlugin, +} from "./plugin/i-cactus-plugin"; export { PluginAspect } from "./plugin/plugin-aspect"; export { PluginRegistry } from "./plugin/plugin-registry"; diff --git a/packages/cactus-plugin-consortium-manual/src/main/typescript/plugin-consortium-manual.ts b/packages/cactus-plugin-consortium-manual/src/main/typescript/plugin-consortium-manual.ts index 135c103f36..33e6f629d4 100644 --- a/packages/cactus-plugin-consortium-manual/src/main/typescript/plugin-consortium-manual.ts +++ b/packages/cactus-plugin-consortium-manual/src/main/typescript/plugin-consortium-manual.ts @@ -12,21 +12,24 @@ import { PluginRegistry, IWebServiceEndpoint, ICactusPlugin, + ICactusPluginOptions, } from "@hyperledger/cactus-core-api"; import { + Checks, Logger, LoggerProvider, LogLevelDesc, } from "@hyperledger/cactus-common"; import { GetConsortiumEndpointV1 } from "./consortium/get-consortium-jws-endpoint-v1"; import { GetNodeJwsEndpoint } from "./consortium/get-node-jws-endpoint-v1"; +import uuid from "uuid"; export interface IWebAppOptions { port: number; hostname: string; } -export interface IPluginConsortiumManualOptions { +export interface IPluginConsortiumManualOptions extends ICactusPluginOptions { keyPairPem: string; consortium: Consortium; pluginRegistry?: PluginRegistry; @@ -37,15 +40,23 @@ export interface IPluginConsortiumManualOptions { export class PluginConsortiumManual implements ICactusPlugin, IPluginWebService { private readonly log: Logger; + private readonly instanceId: string; private httpServer: Server | SecureServer | null = null; constructor(public readonly options: IPluginConsortiumManualOptions) { + const fnTag = `PluginConsortiumManual#constructor()`; if (!options) { - throw new Error(`PluginConsortiumManual#ctor options falsy.`); + throw new Error(`${fnTag} options falsy.`); } + Checks.truthy(options.instanceId, `${fnTag} options.instanceId`); this.log = LoggerProvider.getOrCreate({ label: "plugin-consortium-manual", }); + this.instanceId = this.options.instanceId; + } + + public getInstanceId(): string { + return this.instanceId; } public async shutdown(): Promise { diff --git a/packages/cactus-plugin-keychain-memory/package.json b/packages/cactus-plugin-keychain-memory/package.json index 4e6dbb284b..791bc5c005 100644 --- a/packages/cactus-plugin-keychain-memory/package.json +++ b/packages/cactus-plugin-keychain-memory/package.json @@ -62,6 +62,7 @@ }, "homepage": "https://github.com/hyperledger/cactus#readme", "dependencies": { + "@hyperledger/cactus-common": "^0.2.0", "@hyperledger/cactus-core-api": "^0.2.0", "joi": "14.3.1", "typescript-optional": "2.0.1" @@ -69,4 +70,4 @@ "devDependencies": { "@types/joi": "14.3.4" } -} \ No newline at end of file +} diff --git a/packages/cactus-plugin-keychain-memory/src/main/typescript/plugin-factory-keychain.ts b/packages/cactus-plugin-keychain-memory/src/main/typescript/plugin-factory-keychain.ts index 4229906925..adb0cfbec9 100644 --- a/packages/cactus-plugin-keychain-memory/src/main/typescript/plugin-factory-keychain.ts +++ b/packages/cactus-plugin-keychain-memory/src/main/typescript/plugin-factory-keychain.ts @@ -1,3 +1,5 @@ +import { v4 as uuidv4 } from "uuid"; + import { PluginFactory } from "@hyperledger/cactus-core-api"; import { IPluginKeychainOptions, @@ -9,7 +11,10 @@ export class PluginFactoryKeychain extends PluginFactory< IPluginKeychainOptions > { async create( - options: IPluginKeychainOptions = { backend: new Map() } + options: IPluginKeychainOptions = { + backend: new Map(), + instanceId: uuidv4(), + } ): Promise { return new PluginKeychainMemory(options); } diff --git a/packages/cactus-plugin-keychain-memory/src/main/typescript/plugin-keychain-memory.ts b/packages/cactus-plugin-keychain-memory/src/main/typescript/plugin-keychain-memory.ts index 47a402dcb5..ee49707f36 100644 --- a/packages/cactus-plugin-keychain-memory/src/main/typescript/plugin-keychain-memory.ts +++ b/packages/cactus-plugin-keychain-memory/src/main/typescript/plugin-keychain-memory.ts @@ -1,21 +1,33 @@ import { ICactusPlugin, + ICactusPluginOptions, IPluginKeychain, PluginAspect, } from "@hyperledger/cactus-core-api"; -export interface IPluginKeychainOptions { +import { Checks } from "@hyperledger/cactus-common"; + +export interface IPluginKeychainOptions extends ICactusPluginOptions { backend: Map; } export class PluginKeychainMemory implements ICactusPlugin, IPluginKeychain { + private readonly instanceId: string; + constructor(public readonly options: IPluginKeychainOptions) { + const fnTag = `PluginKeychainMemory#constructor()`; if (!options) { - throw new Error(`PluginKeychainMemory#ctor options falsy.`); + throw new Error(`${fnTag} options falsy.`); } + Checks.truthy(options.instanceId, `${fnTag} options.instanceId`); if (!options.backend) { options.backend = new Map(); } + this.instanceId = this.options.instanceId; + } + + public getInstanceId(): string { + return this.instanceId; } public getPackageName(): string { diff --git a/packages/cactus-plugin-kv-storage-memory/package.json b/packages/cactus-plugin-kv-storage-memory/package.json index 02377642df..48b6c4bd42 100644 --- a/packages/cactus-plugin-kv-storage-memory/package.json +++ b/packages/cactus-plugin-kv-storage-memory/package.json @@ -59,6 +59,7 @@ }, "homepage": "https://github.com/hyperledger/cactus#readme", "dependencies": { + "@hyperledger/cactus-common": "^0.2.0", "@hyperledger/cactus-core-api": "^0.2.0", "joi": "14.3.1", "typescript-optional": "2.0.1" @@ -66,4 +67,4 @@ "devDependencies": { "@types/joi": "14.3.4" } -} \ No newline at end of file +} diff --git a/packages/cactus-plugin-kv-storage-memory/src/main/typescript/plugin-factory-kv-storage.ts b/packages/cactus-plugin-kv-storage-memory/src/main/typescript/plugin-factory-kv-storage.ts index 68682295ba..212c692a21 100644 --- a/packages/cactus-plugin-kv-storage-memory/src/main/typescript/plugin-factory-kv-storage.ts +++ b/packages/cactus-plugin-kv-storage-memory/src/main/typescript/plugin-factory-kv-storage.ts @@ -1,3 +1,5 @@ +import { v4 as uuidv4 } from "uuid"; + import { PluginFactory } from "@hyperledger/cactus-core-api"; import { IPluginKVStorageOptions, @@ -9,7 +11,10 @@ export class PluginFactoryKVStorage extends PluginFactory< IPluginKVStorageOptions > { async create( - options: IPluginKVStorageOptions = { backend: new Map() } + options: IPluginKVStorageOptions = { + backend: new Map(), + instanceId: uuidv4(), + } ): Promise { return new PluginKVStorageMemory(options); } diff --git a/packages/cactus-plugin-kv-storage-memory/src/main/typescript/plugin-kv-storage-memory.ts b/packages/cactus-plugin-kv-storage-memory/src/main/typescript/plugin-kv-storage-memory.ts index 264640c6aa..09e99a6f51 100644 --- a/packages/cactus-plugin-kv-storage-memory/src/main/typescript/plugin-kv-storage-memory.ts +++ b/packages/cactus-plugin-kv-storage-memory/src/main/typescript/plugin-kv-storage-memory.ts @@ -1,21 +1,33 @@ import { ICactusPlugin, + ICactusPluginOptions, IPluginKVStorage, PluginAspect, } from "@hyperledger/cactus-core-api"; -export interface IPluginKVStorageOptions { +import { Checks } from "@hyperledger/cactus-common"; + +export interface IPluginKVStorageOptions extends ICactusPluginOptions { backend: Map; } export class PluginKVStorageMemory implements ICactusPlugin, IPluginKVStorage { + private readonly instanceId: string; + constructor(public readonly options: IPluginKVStorageOptions) { + const fnTag = `PluginKVStorageMemory#constructor()`; if (!options) { - throw new Error(`PluginKVStorageMemory#ctor options falsy.`); + throw new Error(`${fnTag} options falsy.`); } + Checks.truthy(options.instanceId, `${fnTag} options.instanceId`); if (!options.backend) { options.backend = new Map(); } + this.instanceId = this.options.instanceId; + } + + public getInstanceId(): string { + return this.instanceId; } public getPackageName(): string { diff --git a/packages/cactus-plugin-ledger-connector-besu/src/main/typescript/plugin-ledger-connector-besu.ts b/packages/cactus-plugin-ledger-connector-besu/src/main/typescript/plugin-ledger-connector-besu.ts index 87e41e5bea..1f601b64fa 100644 --- a/packages/cactus-plugin-ledger-connector-besu/src/main/typescript/plugin-ledger-connector-besu.ts +++ b/packages/cactus-plugin-ledger-connector-besu/src/main/typescript/plugin-ledger-connector-besu.ts @@ -1,5 +1,6 @@ import { ICactusPlugin, + ICactusPluginOptions, IPluginLedgerConnector, PluginAspect, } from "@hyperledger/cactus-core-api"; @@ -7,12 +8,14 @@ import Web3 from "web3"; import EEAClient, { IWeb3InstanceExtended } from "web3-eea"; import { + Checks, Logger, LoggerProvider, LogLevelDesc, } from "@hyperledger/cactus-common"; -export interface IPluginLedgerConnectorBesuOptions { +export interface IPluginLedgerConnectorBesuOptions + extends ICactusPluginOptions { rpcApiHttpHost: string; logLevel?: LogLevelDesc; } @@ -72,14 +75,17 @@ export class PluginLedgerConnectorBesu IBesuTransactionIn, IBesuTransactionOut > { + private readonly instanceId: string; private readonly log: Logger; private readonly web3: Web3; private readonly web3Eea: IWeb3InstanceExtended; constructor(public readonly options: IPluginLedgerConnectorBesuOptions) { + const fnTag = `PluginLedgerConnectorBesu#constructor()`; if (!options) { - throw new Error(`PluginLedgerConnectorBesu#ctor options falsy.`); + throw new Error(`${fnTag} options falsy.`); } + Checks.truthy(options.instanceId, `${fnTag} options.instanceId`); const web3Provider = new Web3.providers.HttpProvider( this.options.rpcApiHttpHost ); @@ -89,6 +95,11 @@ export class PluginLedgerConnectorBesu const level = options.logLevel || "INFO"; const label = "plugin-ledger-connector-besu"; this.log = LoggerProvider.getOrCreate({ level, label }); + this.instanceId = this.options.instanceId; + } + + public getInstanceId(): string { + return this.instanceId; } public getPackageName(): string { diff --git a/packages/cactus-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-ledger-connector-besu/deploy-contract/deploy-contract-from-json.ts b/packages/cactus-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-ledger-connector-besu/deploy-contract/deploy-contract-from-json.ts index f39b16ac0c..ef3df9bdc9 100644 --- a/packages/cactus-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-ledger-connector-besu/deploy-contract/deploy-contract-from-json.ts +++ b/packages/cactus-plugin-ledger-connector-besu/src/test/typescript/integration/plugin-ledger-connector-besu/deploy-contract/deploy-contract-from-json.ts @@ -1,5 +1,6 @@ // tslint:disable-next-line: no-var-requires const tap = require("tap"); +import { v4 as uuidv4 } from "uuid"; import { PluginLedgerConnectorBesu, PluginFactoryLedgerConnector, @@ -26,6 +27,7 @@ tap.test("deploys contract via .json file", async (assert: any) => { const factory = new PluginFactoryLedgerConnector(); const connector: PluginLedgerConnectorBesu = await factory.create({ rpcApiHttpHost, + instanceId: uuidv4(), }); const options = { 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 e836fdb96a..d3359894b0 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 @@ -13,6 +13,7 @@ import { IPluginWebService, IWebServiceEndpoint, ICactusPlugin, + ICactusPluginOptions, } from "@hyperledger/cactus-core-api"; import { @@ -27,7 +28,8 @@ import { } from "./deploy-contract-go-bin-endpoint-v1"; import { ISigningIdentity } from "./i-fabric-signing-identity"; -export interface IPluginLedgerConnectorFabricOptions { +export interface IPluginLedgerConnectorFabricOptions + extends ICactusPluginOptions { opsApiHttpHost: string; logLevel?: LogLevelDesc; webAppOptions?: any; @@ -45,6 +47,7 @@ export class PluginLedgerConnectorFabric IPluginLedgerConnector, ICactusPlugin, IPluginWebService { + private readonly instanceId: string; private readonly log: Logger; private httpServer: Server | SecureServer | undefined; @@ -53,6 +56,9 @@ export class PluginLedgerConnectorFabric const fnTag = "PluginLedgerConnectorFabric#constructor()"; Checks.truthy(options, `${fnTag} arg options`); + Checks.truthy(options.instanceId, `${fnTag} options.instanceId`); + + this.instanceId = options.instanceId; const level = this.options.logLevel || "INFO"; const label = "plugin-ledger-connector-fabric"; @@ -66,6 +72,10 @@ export class PluginLedgerConnectorFabric throw new Error("Method not implemented."); } + public getInstanceId(): string { + return this.instanceId; + } + public getPackageName(): string { return `@hyperledger/cactus-plugin-ledger-connectur-fabric`; } diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/deploy-contract-go-bin-endpoint-v1/deploy-contract/deploy-cc-from-golang-source.test.ts b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/deploy-contract-go-bin-endpoint-v1/deploy-contract/deploy-cc-from-golang-source.test.ts index 4609fc831e..ccf9ada200 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/deploy-contract-go-bin-endpoint-v1/deploy-contract/deploy-cc-from-golang-source.test.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/deploy-contract-go-bin-endpoint-v1/deploy-contract/deploy-cc-from-golang-source.test.ts @@ -3,6 +3,7 @@ import { AddressInfo } from "net"; import path from "path"; import test, { Test } from "tape"; +import { v4 as uuidv4 } from "uuid"; import axios, { AxiosRequestConfig } from "axios"; import FormData from "form-data"; @@ -39,6 +40,7 @@ test("deploys contract from go source", async (t: Test) => { const adminSigningIdentity = await ledger.getAdminSigningIdentity(); const pluginOpts: IPluginLedgerConnectorFabricOptions = { + instanceId: uuidv4(), opsApiHttpHost, connectionProfile, adminSigningIdentity, diff --git a/packages/cactus-plugin-ledger-connector-quorum/src/main/typescript/plugin-ledger-connector-quorum.ts b/packages/cactus-plugin-ledger-connector-quorum/src/main/typescript/plugin-ledger-connector-quorum.ts index 38121485e8..eac48358b3 100644 --- a/packages/cactus-plugin-ledger-connector-quorum/src/main/typescript/plugin-ledger-connector-quorum.ts +++ b/packages/cactus-plugin-ledger-connector-quorum/src/main/typescript/plugin-ledger-connector-quorum.ts @@ -15,6 +15,7 @@ import { IPluginWebService, PluginAspect, ICactusPlugin, + ICactusPluginOptions, } from "@hyperledger/cactus-core-api"; import { @@ -44,7 +45,8 @@ import { RunTransactionEndpoint } from "./web-services/run-transaction-endpoint" import { InvokeContractEndpoint } from "./web-services/invoke-contract-endpoint"; import { isWeb3SigningCredentialNone } from "./model-type-guards"; -export interface IPluginLedgerConnectorQuorumOptions { +export interface IPluginLedgerConnectorQuorumOptions + extends ICactusPluginOptions { rpcApiHttpHost: string; logLevel?: LogLevelDesc; } @@ -59,6 +61,7 @@ export class PluginLedgerConnectorQuorum >, ICactusPlugin, IPluginWebService { + private readonly instanceId: string; private readonly log: Logger; private readonly web3: Web3; private httpServer: Server | SecureServer | null = null; @@ -73,6 +76,7 @@ export class PluginLedgerConnectorQuorum const fnTag = `${this.className}#constructor()`; Checks.truthy(options, `${fnTag} arg options`); Checks.truthy(options.rpcApiHttpHost, `${fnTag} options.rpcApiHttpHost`); + Checks.truthy(options.instanceId, `${fnTag} options.instanceId`); const level = this.options.logLevel || "INFO"; const label = this.className; @@ -82,6 +86,11 @@ export class PluginLedgerConnectorQuorum this.options.rpcApiHttpHost ); this.web3 = new Web3(web3Provider); + this.instanceId = options.instanceId; + } + + public getInstanceId(): string { + return this.instanceId; } public getHttpServer(): Optional { diff --git a/packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/deploy-contract-from-json.test.ts b/packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/deploy-contract-from-json.test.ts index 76203038b5..73528f41bc 100644 --- a/packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/deploy-contract-from-json.test.ts +++ b/packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/deploy-contract-from-json.test.ts @@ -55,6 +55,7 @@ test("Quorum Ledger Connector Plugin", async (t: Test) => { const connector: PluginLedgerConnectorQuorum = new PluginLedgerConnectorQuorum( { + instanceId: uuidV4(), rpcApiHttpHost, logLevel, } diff --git a/packages/cactus-plugin-validator-besu/src/main/typescript/plugin-validator-besu.ts b/packages/cactus-plugin-validator-besu/src/main/typescript/plugin-validator-besu.ts index 0bc9eef92c..a1897d6ce4 100644 --- a/packages/cactus-plugin-validator-besu/src/main/typescript/plugin-validator-besu.ts +++ b/packages/cactus-plugin-validator-besu/src/main/typescript/plugin-validator-besu.ts @@ -13,11 +13,13 @@ import { PluginRegistry, IWebServiceEndpoint, ICactusPlugin, + ICactusPluginOptions, } from "@hyperledger/cactus-core-api"; import { LogLevelDesc, Logger, LoggerProvider, + Checks, } from "@hyperledger/cactus-common"; import { BesuSignTransactionEndpointV1 } from "./besu/sign-transaction-endpoint-v1"; @@ -28,7 +30,7 @@ export interface IWebAppOptions { hostname: string; } -export interface IPluginValidatorBesuOptions { +export interface IPluginValidatorBesuOptions extends ICactusPluginOptions { rpcApiHttpHost: string; keyPairPem: string; pluginRegistry: PluginRegistry; @@ -37,6 +39,7 @@ export interface IPluginValidatorBesuOptions { } export class PluginValidatorBesu implements ICactusPlugin, IPluginWebService { + private readonly instanceId: string; private readonly log: Logger; private httpServer: Server | SecureServer | null = null; @@ -54,11 +57,17 @@ export class PluginValidatorBesu implements ICactusPlugin, IPluginWebService { if (!options.pluginRegistry) { throw new Error(`${fnTag} options.pluginRegistry falsy.`); } + Checks.truthy(options.instanceId, `${fnTag}#options.instanceId`); this.log = LoggerProvider.getOrCreate({ label: "plugin-validator-besu", level: options.logLevel || "INFO", }); + this.instanceId = options.instanceId; + } + + public getInstanceId(): string { + return this.instanceId; } public async shutdown(): Promise { diff --git a/packages/cactus-test-api-client/src/test/typescript/integration/api-client-routing-node-to-node.test.ts b/packages/cactus-test-api-client/src/test/typescript/integration/api-client-routing-node-to-node.test.ts index a757f06150..d7342dd89b 100644 --- a/packages/cactus-test-api-client/src/test/typescript/integration/api-client-routing-node-to-node.test.ts +++ b/packages/cactus-test-api-client/src/test/typescript/integration/api-client-routing-node-to-node.test.ts @@ -131,11 +131,13 @@ test("Routes to correct node based on ledger ID", async (t: Test) => { const pluginRegistry = new PluginRegistry({ plugins: [] }); const pluginQuorumConnector = new PluginLedgerConnectorQuorum({ + instanceId: uuidV4(), rpcApiHttpHost: rpcApiHttpHost1, logLevel, }); const options: IPluginConsortiumManualOptions = { + instanceId: uuidV4(), pluginRegistry, keyPairPem: keyPair1.toPEM(true), consortium, @@ -169,11 +171,13 @@ test("Routes to correct node based on ledger ID", async (t: Test) => { const pluginRegistry = new PluginRegistry({ plugins: [] }); const pluginQuorumConnector = new PluginLedgerConnectorQuorum({ + instanceId: uuidV4(), rpcApiHttpHost: rpcApiHttpHost2, logLevel, }); const options: IPluginConsortiumManualOptions = { + instanceId: uuidV4(), pluginRegistry, keyPairPem: keyPair2.toPEM(true), consortium, diff --git a/packages/cactus-test-plugin-consortium-manual/src/test/typescript/integration/plugin-consortium-manual/get-consortium-jws-endpoint.test.ts b/packages/cactus-test-plugin-consortium-manual/src/test/typescript/integration/plugin-consortium-manual/get-consortium-jws-endpoint.test.ts index 45fc73d060..953b0a6eac 100644 --- a/packages/cactus-test-plugin-consortium-manual/src/test/typescript/integration/plugin-consortium-manual/get-consortium-jws-endpoint.test.ts +++ b/packages/cactus-test-plugin-consortium-manual/src/test/typescript/integration/plugin-consortium-manual/get-consortium-jws-endpoint.test.ts @@ -125,6 +125,7 @@ test("member node public keys and hosts are pre-shared", async (t: Test) => { // 3. Instantiate the web service consortium plugin const options: IPluginConsortiumManualOptions = { + instanceId: uuidV4(), pluginRegistry, keyPairPem: keyPair1.toPEM(true), consortium, @@ -177,6 +178,7 @@ test("member node public keys and hosts are pre-shared", async (t: Test) => { const pluginRegistry = new PluginRegistry({ plugins: [] }); const options: IPluginConsortiumManualOptions = { + instanceId: uuidV4(), pluginRegistry, keyPairPem: keyPair2.toPEM(true), consortium, @@ -230,6 +232,7 @@ test("member node public keys and hosts are pre-shared", async (t: Test) => { // 3. Instantiate the web service consortium plugin const options: IPluginConsortiumManualOptions = { + instanceId: uuidV4(), pluginRegistry, keyPairPem: keyPair3.toPEM(true), consortium, diff --git a/packages/cactus-test-plugin-consortium-manual/src/test/typescript/integration/plugin-consortium-manual/security-isolation-via-api-server-ports.ts b/packages/cactus-test-plugin-consortium-manual/src/test/typescript/integration/plugin-consortium-manual/security-isolation-via-api-server-ports.ts index 65dd1ff606..99c63b0f14 100644 --- a/packages/cactus-test-plugin-consortium-manual/src/test/typescript/integration/plugin-consortium-manual/security-isolation-via-api-server-ports.ts +++ b/packages/cactus-test-plugin-consortium-manual/src/test/typescript/integration/plugin-consortium-manual/security-isolation-via-api-server-ports.ts @@ -29,7 +29,8 @@ tap.test( "pulls up API server with consortium web service on different port", async (assert: any) => { // 1. Instantiate a key value storage plugin that works in memory (good here because we don't need persistence) - const kvStoragePlugin = new PluginKVStorageMemory({ backend: new Map() }); + const opts = { backend: new Map(), instanceId: uuidV4() }; + const kvStoragePlugin = new PluginKVStorageMemory(opts); // 2. Instantiate plugin registry which will provide the web service plugin with the key value storage plugin const pluginRegistry = new PluginRegistry({ plugins: [kvStoragePlugin] }); @@ -69,6 +70,7 @@ tap.test( // Note that if we omitted the `webAppOptions` object that the web service plugin would default to installing itself // on the default port of the API server. This allows for flexibility in deployments. const options: IPluginConsortiumManualOptions = { + instanceId: uuidV4(), pluginRegistry, keyPairPem, consortium, diff --git a/packages/cactus-test-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/deploy-contract-via-web-service.test.ts b/packages/cactus-test-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/deploy-contract-via-web-service.test.ts index 92cbcc4b6f..937d0e2ceb 100644 --- a/packages/cactus-test-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/deploy-contract-via-web-service.test.ts +++ b/packages/cactus-test-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/deploy-contract-via-web-service.test.ts @@ -56,10 +56,12 @@ test("deploys contract via REST API", async (t: Test) => { const config = configService.newExampleConfigConvict(cactusApiServerOptions); const plugins: ICactusPlugin[] = []; - const kvStoragePlugin = new PluginKVStorageMemory({ backend: new Map() }); + const kvpOpts = { backend: new Map(), instanceId: uuidV4() }; + const kvStoragePlugin = new PluginKVStorageMemory(kvpOpts); plugins.push(kvStoragePlugin); const ledgerConnectorQuorum = new PluginLedgerConnectorQuorum({ + instanceId: uuidV4(), rpcApiHttpHost, }); plugins.push(ledgerConnectorQuorum); diff --git a/packages/cactus-test-plugin-validator-besu/src/test/typescript/integration/plugin-validator-besu/sign-transaction-endpoint.test.ts b/packages/cactus-test-plugin-validator-besu/src/test/typescript/integration/plugin-validator-besu/sign-transaction-endpoint.test.ts index a84479c096..e4f99bdbe7 100644 --- a/packages/cactus-test-plugin-validator-besu/src/test/typescript/integration/plugin-validator-besu/sign-transaction-endpoint.test.ts +++ b/packages/cactus-test-plugin-validator-besu/src/test/typescript/integration/plugin-validator-besu/sign-transaction-endpoint.test.ts @@ -1,5 +1,6 @@ import test, { Test } from "tape"; +import { v4 as uuidv4 } from "uuid"; import crypto from "crypto"; import { createServer } from "http"; import KeyEncoder from "key-encoder"; @@ -71,6 +72,7 @@ test("Test sign transaction endpoint", async (t: Test) => { // 3. Instantiate the web service consortium plugin const options: IPluginValidatorBesuOptions = { + instanceId: uuidv4(), rpcApiHttpHost: rcpHttpHost, keyPairPem: pemPrivate, pluginRegistry,