Skip to content

Commit

Permalink
refactor(core-api): renames the plugin id getter to package name
Browse files Browse the repository at this point in the history
Doing so better represents what the getter is actually for.
Calling it plugin ID is semantically
incorrect because
It does not uniquely identify the plugin instance
only the plugin package.

Fixes hyperledger#262

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed Oct 17, 2020
1 parent f6454c8 commit 5731f25
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@ import { PluginAspect } from "./plugin-aspect";

/**
* This is the common base for all other plugin interface definitions to have as a parent.
*
*/
export interface ICactusPlugin {
/**
* Returns the ID of the plugin which is a string uniquely identifying the plugin among other plugins so that they can
* be managed separately without conflicts or runtime errors.
* Important: This is not just uniqely identifying the plugin aspect, but the implementation as well.
* For example a plugin aspect would we `ledger-connector` or `storage` and implementations are the ones within those
* aspects such as `plugin-ledger-connector-besu` or `plugin-storage-kv-in-memory`.
* 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.
*
* Important: This is not just uniqely identifying the plugin aspect, but the
* implementation as well.
* For example a plugin aspect would we `ledger-connector` or `storage` and
* implementations are the ones within those
* aspects such as `plugin-ledger-connector-besu` or
* `plugin-storage-kv-in-memory`.
* Also important: There can be two plugin instances that have the same
* package name and yet serve different purposes in cases like when you have
* two ledger connector plugins connecting to the same kind of ledger, but
* different instances of it (e.g. two companies both have their own private
* Hyperledger Besu deployment)
*/
getId(): string;
getPackageName(): string;

/**
* Returns the aspect of which this plugin implementation belongs to such as the aspect of `ledger-connector` or
Expand All @@ -23,7 +31,7 @@ export interface ICactusPlugin {
}

export function isICactusPlugin(
pluginInstance: ICactusPlugin
pluginInstance: any
): pluginInstance is ICactusPlugin {
return typeof pluginInstance.getId === "function";
return typeof pluginInstance?.getPackageName === "function";
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ export class PluginRegistry {
public readonly plugins: ICactusPlugin[];

constructor(public readonly options: IPluginRegistryOptions = {}) {
const fnTag = `PluginRegistry#constructor()`;
if (!options) {
throw new TypeError(`PluginRegistry#ctor options falsy`);
throw new TypeError(`${fnTag} options falsy`);
}
if (options.plugins && !Array.isArray(options.plugins)) {
throw new TypeError(
`PluginRegistry#ctor options.plugins truthy but non-Array`
);
throw new TypeError(`${fnTag} options.plugins truthy but non-Array`);
}
this.plugins = options.plugins || [];
}
Expand All @@ -38,16 +37,16 @@ export class PluginRegistry {
}

/**
* The main difference between this method and `findOneById` is that this throws an Error if there was nothing to
* return. It is recommended to use this method over `findOneById` if you have a hard dependency on a certain
* The main difference between this method and `findOneByPackageName` is that this throws an Error if there was nothing to
* return. It is recommended to use this method over `findOneByPackageName` if you have a hard dependency on a certain
* plugin being loaded for your code.
*
* @param id The ID of the plugin that you are looking to obtain an instance of from the registry.
* @throws If there is no plugin in the registry by the ID specificed.
* @param packageName The package name of the plugin that you are looking to obtain an instance of from the registry.
* @throws If there is no plugin in the registry by the package name specificed.
*/
public getOneById<T extends ICactusPlugin>(id: string): T {
return this.findOneById(id).orElseThrow(
() => new Error(`Plugin ${id} not present in registry`)
public getOneById<T extends ICactusPlugin>(packageName: string): T {
return this.findOneByPackageName(packageName).orElseThrow(
() => new Error(`Plugin ${packageName} not present in registry`)
) as T;
}

Expand All @@ -57,13 +56,21 @@ export class PluginRegistry {
) as T;
}

public findOneById<T extends ICactusPlugin>(pluginId: string): Optional<T> {
const plugin = this.getPlugins().find((p) => p.getId() === pluginId);
public findOneByPackageName<T extends ICactusPlugin>(
packageName: string
): Optional<T> {
const plugin = this.getPlugins().find(
(p) => p.getPackageName() === packageName
);
return Optional.ofNullable(plugin as T);
}

public findManyById<T extends ICactusPlugin>(id: string): T[] {
return this.getPlugins().filter((p) => p.getId() === id) as T[];
public findManyByPackageName<T extends ICactusPlugin>(
packageName: string
): T[] {
return this.getPlugins().filter(
(p) => p.getPackageName() === packageName
) as T[];
}

public findOneByAspect<T extends ICactusPlugin>(
Expand All @@ -81,14 +88,14 @@ export class PluginRegistry {
return this.findOneByAspect(aspect).isPresent();
}

public hasById(id: string): boolean {
return this.findOneById(id).isPresent();
public hasByPackageName(packageName: string): boolean {
return this.findOneByPackageName(packageName).isPresent();
}

public deleteById(id: string): [number] {
public deleteByPackageName(packageName: string): [number] {
let deleteCount: number = 0;
this.plugins.forEach((p, i) => {
if (p.getId() === id) {
if (p.getPackageName() === packageName) {
this.plugins.splice(i, 1);
deleteCount++;
}
Expand All @@ -103,14 +110,14 @@ export class PluginRegistry {
if (!isICactusPlugin(plugin)) {
throw new Error(`PluginRegistry#add() plugin not an ICactusPlugin`);
}
const id = plugin.getId();
const hasConfclit = this.hasById(id);
const pkgName = plugin.getPackageName();
const hasConfclit = this.hasByPackageName(pkgName);
if (hasConfclit && !replaceOnConflict) {
throw new Error(`PluginRegistry#add() already have plugin: ${id}`);
throw new Error(`PluginRegistry#add() already have plugin: ${pkgName}`);
}
let deleteCount: number = 0;
if (replaceOnConflict) {
[deleteCount] = this.deleteById(plugin.getId());
[deleteCount] = this.deleteByPackageName(plugin.getPackageName());
}
this.getPlugins().push(plugin);
return [deleteCount];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export function isIPluginWebService(
typeof (pluginInstance as IPluginWebService).installWebServices ===
"function" &&
typeof (pluginInstance as IPluginWebService).getHttpServer === "function" &&
typeof (pluginInstance as IPluginWebService).getId === "function" &&
typeof (pluginInstance as IPluginWebService).getPackageName ===
"function" &&
typeof (pluginInstance as IPluginWebService).getAspect === "function" &&
typeof (pluginInstance as IPluginWebService).shutdown === "function"
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
PluginAspect,
PluginRegistry,
IWebServiceEndpoint,
ICactusPlugin,
} from "@hyperledger/cactus-core-api";
import { Logger, LoggerProvider } from "@hyperledger/cactus-common";
import { GetConsortiumEndpointV1 } from "./consortium/get-consortium-jws-endpoint-v1";
Expand All @@ -29,7 +30,8 @@ export interface IPluginConsortiumManualOptions {
webAppOptions?: IWebAppOptions;
}

export class PluginConsortiumManual implements IPluginWebService {
export class PluginConsortiumManual
implements ICactusPlugin, IPluginWebService {
private readonly log: Logger;
private httpServer: Server | SecureServer | null = null;

Expand Down Expand Up @@ -60,7 +62,7 @@ export class PluginConsortiumManual implements IPluginWebService {
): Promise<IWebServiceEndpoint[]> {
const { log } = this;

log.info(`Installing web services for plugin ${this.getId()}...`);
log.info(`Installing web services for plugin ${this.getPackageName()}...`);
const webApp: Express = this.options.webAppOptions ? express() : expressApp;

// presence of webAppOptions implies that caller wants the plugin to configure it's own express instance on a custom
Expand All @@ -87,35 +89,37 @@ export class PluginConsortiumManual implements IPluginWebService {
}

const { consortium, keyPairPem } = this.options;
const pluginId = this.getId();
const packageName = this.getPackageName();

const endpoints: IWebServiceEndpoint[] = [];
{
const path = `/api/v1/plugins/${pluginId}/consortium/jws`;
const path = `/api/v1/plugins/${packageName}/consortium/jws`;
const options = { path, keyPairPem, consortium };
const endpoint = new GetConsortiumEndpointV1(options);
webApp.get(endpoint.getPath(), endpoint.getExpressRequestHandler());
endpoints.push(endpoint);
this.log.info(`Registered contract deployment endpoint at ${path}`);
}
{
const path = `/api/v1/plugins/${pluginId}/node/jws`;
const path = `/api/v1/plugins/${packageName}/node/jws`;
const options = { path, keyPairPem, consortium };
const endpoint = new GetNodeJwsEndpoint(options);
webApp.get(endpoint.getPath(), endpoint.getExpressRequestHandler());
endpoints.push(endpoint);
this.log.info(`Registered contract deployment endpoint at ${path}`);
}

log.info(`Installed web svcs for plugin ${this.getId()} OK`, { endpoints });
log.info(`Installed web svcs for plugin ${this.getPackageName()} OK`, {
endpoints,
});
return endpoints;
}

public getHttpServer(): Optional<Server | SecureServer> {
return Optional.ofNullable(this.httpServer);
}

public getId(): string {
public getPackageName(): string {
return `@hyperledger/cactus-plugin-consortium-manual`;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { IPluginKeychain, PluginAspect } from "@hyperledger/cactus-core-api";
import {
ICactusPlugin,
IPluginKeychain,
PluginAspect,
} from "@hyperledger/cactus-core-api";

export interface IPluginKeychainOptions {
backend: Map<string, any>;
}

export class PluginKeychainMemory implements IPluginKeychain {
export class PluginKeychainMemory implements ICactusPlugin, IPluginKeychain {
constructor(public readonly options: IPluginKeychainOptions) {
if (!options) {
throw new Error(`PluginKeychainMemory#ctor options falsy.`);
Expand All @@ -14,7 +18,7 @@ export class PluginKeychainMemory implements IPluginKeychain {
}
}

public getId(): string {
public getPackageName(): string {
return `@hyperledger/cactus-plugin-keychain-memory`;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { IPluginKVStorage, PluginAspect } from "@hyperledger/cactus-core-api";
import {
ICactusPlugin,
IPluginKVStorage,
PluginAspect,
} from "@hyperledger/cactus-core-api";

export interface IPluginKVStorageOptions {
backend: Map<string, any>;
}

export class PluginKVStorageMemory implements IPluginKVStorage {
export class PluginKVStorageMemory implements ICactusPlugin, IPluginKVStorage {
constructor(public readonly options: IPluginKVStorageOptions) {
if (!options) {
throw new Error(`PluginKVStorageMemory#ctor options falsy.`);
Expand All @@ -14,7 +18,7 @@ export class PluginKVStorageMemory implements IPluginKVStorage {
}
}

public getId(): string {
public getPackageName(): string {
return `@hyperledger/cactus-plugin-kv-storage-memory`;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
ICactusPlugin,
IPluginLedgerConnector,
PluginAspect,
} from "@hyperledger/cactus-core-api";
Expand Down Expand Up @@ -58,6 +59,7 @@ export interface IBesuTransactionOut {

export class PluginLedgerConnectorBesu
implements
ICactusPlugin,
IPluginLedgerConnector<
IBesuDeployContractIn,
IBesuDeployContractOut,
Expand All @@ -78,7 +80,7 @@ export class PluginLedgerConnectorBesu
this.web3Eea = EEAClient(this.web3, 2018);
}

public getId(): string {
public getPackageName(): string {
return `@hyperledger/cactus-plugin-ledger-connectur-besu`;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
PluginAspect,
IPluginWebService,
IWebServiceEndpoint,
ICactusPlugin,
} from "@hyperledger/cactus-core-api";

import {
Expand Down Expand Up @@ -40,7 +41,10 @@ export interface ITransactionOptions {
}

export class PluginLedgerConnectorFabric
implements IPluginLedgerConnector<any, any, any, any>, IPluginWebService {
implements
IPluginLedgerConnector<any, any, any, any>,
ICactusPlugin,
IPluginWebService {
private readonly log: Logger;

private httpServer: Server | SecureServer | undefined;
Expand All @@ -62,7 +66,7 @@ export class PluginLedgerConnectorFabric
throw new Error("Method not implemented.");
}

public getId(): string {
public getPackageName(): string {
return `@hyperledger/cactus-plugin-ledger-connectur-fabric`;
}

Expand Down Expand Up @@ -95,7 +99,7 @@ export class PluginLedgerConnectorFabric
): Promise<IWebServiceEndpoint[]> {
const { log } = this;

log.info(`Installing web services for plugin ${this.getId()}...`);
log.info(`Installing web services for plugin ${this.getPackageName()}...`);
const webApp: Express = this.options.webAppOptions ? express() : expressApp;

// FIXME refactor this
Expand Down Expand Up @@ -123,14 +127,14 @@ export class PluginLedgerConnectorFabric
}

const { sshConfig, connectionProfile, adminSigningIdentity } = this.options;
const pluginId = this.getId();
const packageName = this.getPackageName();

const storage = multer.memoryStorage();
const upload = multer({ storage });

const endpoints: IWebServiceEndpoint[] = [];
{
const path = `/api/v1/plugins/${pluginId}/deploy-contract-go-bin`;
const path = `/api/v1/plugins/${packageName}/deploy-contract-go-bin`;
const opts: IDeployContractGoBinEndpointV1Options = {
path,
sshConfig,
Expand All @@ -148,7 +152,9 @@ export class PluginLedgerConnectorFabric
this.log.info(`Registered contract deployment endpoint at ${path}`);
}

log.info(`Installed web svcs for plugin ${this.getId()} OK`, { endpoints });
log.info(`Installed web svcs for plugin ${this.getPackageName()} OK`, {
endpoints,
});
return endpoints;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
IWebServiceEndpoint,
IPluginWebService,
PluginAspect,
ICactusPlugin,
} from "@hyperledger/cactus-core-api";

import {
Expand Down Expand Up @@ -56,6 +57,7 @@ export class PluginLedgerConnectorQuorum
RunTransactionRequest,
RunTransactionResponse
>,
ICactusPlugin,
IPluginWebService {
private readonly log: Logger;
private readonly web3: Web3;
Expand Down Expand Up @@ -125,7 +127,7 @@ export class PluginLedgerConnectorQuorum
return endpoints;
}

public getId(): string {
public getPackageName(): string {
return `@hyperledger/cactus-plugin-ledger-connector-quorum`;
}

Expand Down
Loading

0 comments on commit 5731f25

Please sign in to comment.