Skip to content

Commit

Permalink
refactor(plugin-registry): getOneById to use instanceId #1197
Browse files Browse the repository at this point in the history
The getOneById function will now use the instance ID
for lookups instead of the package name.

Also added a couple of extra convenience methods to make
them more consistent in general and increased the
test coverage of the plugin registry.

Fixes #1197

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed Aug 13, 2021
1 parent 22eac9a commit 5cb03d0
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 41 deletions.
25 changes: 24 additions & 1 deletion packages/cactus-core/src/main/typescript/plugin-registry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Optional } from "typescript-optional";
import {
Checks,
Logger,
LoggerProvider,
LogLevelDesc,
Expand Down Expand Up @@ -57,6 +58,28 @@ export class PluginRegistry {
return this.plugins;
}

/**
* Same as `findOneById()` but throws instead of returning an `EMPTY` `Optional`
* when the plugin does not exist in the registry.
*
* @param instanceId The `instanceId` 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 `instanceId` specificed.
*/
public getOneById<T extends ICactusPlugin>(instanceId: string): T {
Checks.nonBlankString(instanceId, "instanceId");
return this.findOneById(instanceId).orElseThrow(
() => new Error(`Plugin ${instanceId} not present in registry`),
) as T;
}

public findOneById<T extends ICactusPlugin>(instanceId: string): Optional<T> {
Checks.nonBlankString(instanceId, "instanceId");
const plugin = this.getPlugins().find(
(p) => p.getInstanceId() === instanceId,
);
return Optional.ofNullable(plugin as T);
}

/**
* 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
Expand All @@ -65,7 +88,7 @@ export class PluginRegistry {
* @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>(packageName: string): T {
public getOneByPackageName<T extends ICactusPlugin>(packageName: string): T {
return this.findOneByPackageName(packageName).orElseThrow(
() => new Error(`Plugin ${packageName} not present in registry`),
) as T;
Expand Down
119 changes: 79 additions & 40 deletions packages/cactus-core/src/test/typescript/unit/plugin-registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,47 @@ import { PluginRegistry } from "../../../main/typescript/public-api";
import { ICactusPlugin, IPluginKeychain } from "@hyperledger/cactus-core-api";

test("PluginRegistry", (tMain: Test) => {
test("findOneByKeychainId() finds plugin by keychain ID", (t: Test) => {
const keychainId = uuidv4();
const instanceId = uuidv4();

const mockKeychainPlugin: IPluginKeychain = {
getInstanceId: () => instanceId,
getKeychainId: () => keychainId,
delete: async () => {
throw new Error("This is a mock. Not implemented.");
},
has: async () => {
throw new Error("This is a mock. Not implemented.");
},
get: async () => {
throw new Error("This is a mock. Not implemented.");
},
set: async () => {
throw new Error("This is a mock. Not implemented.");
},
getPackageName: () => "@hyperledger/cactus-plugin-keychain-mock",

onPluginInit: async () => {
throw new Error("not sure how this works");
},
};

const pluginRegistry = new PluginRegistry({
plugins: [
mockKeychainPlugin,
{
getInstanceId: () => "some-mock-plugin-instance-id-1",
} as ICactusPlugin,
{
getInstanceId: () => "some-mock-plugin-instance-id-2",
} as ICactusPlugin,
{
getInstanceId: () => "some-mock-plugin-instance-id-3",
} as ICactusPlugin,
],
});
const keychainId = uuidv4();
const instanceId = uuidv4();

const mockKeychainPlugin: IPluginKeychain = {
getInstanceId: () => instanceId,
getKeychainId: () => keychainId,
delete: async () => {
throw new Error("This is a mock. Not implemented.");
},
has: async () => {
throw new Error("This is a mock. Not implemented.");
},
get: async () => {
throw new Error("This is a mock. Not implemented.");
},
set: async () => {
throw new Error("This is a mock. Not implemented.");
},
getPackageName: () => "@hyperledger/cactus-plugin-keychain-mock",

onPluginInit: async () => {
throw new Error("not sure how this works");
},
};

const pluginRegistry = new PluginRegistry({
plugins: [
mockKeychainPlugin,
{
getInstanceId: () => "some-mock-plugin-instance-id-1",
} as ICactusPlugin,
{
getInstanceId: () => "some-mock-plugin-instance-id-2",
} as ICactusPlugin,
{
getInstanceId: () => "some-mock-plugin-instance-id-3",
} as ICactusPlugin,
],
});

test("findOneByKeychainId() finds plugin by keychain ID", (t: Test) => {
t.doesNotThrow(() => pluginRegistry.findOneByKeychainId(keychainId));
const keychainPlugin = pluginRegistry.findOneByKeychainId(keychainId);
t.equal(keychainPlugin, mockKeychainPlugin, "Finds same object OK");
Expand All @@ -65,5 +65,44 @@ test("PluginRegistry", (tMain: Test) => {
t.end();
});

test("findOneById() finds plugin by its instanceID", (t: Test) => {
t.doesNotThrow(() => pluginRegistry.findOneById(instanceId));
const keychainPlugin = pluginRegistry.findOneById(instanceId).get();
t.equal(keychainPlugin, mockKeychainPlugin, "Finds same object by ID OK");

t.throws(
() => pluginRegistry.findOneById(""),
/instanceId.*Need non-blank/,
"Check for instance ID blankness OK",
);

t.true(
pluginRegistry.findOneById("x").isEmpty(),
"return empty optional for non-existent instance ID OK",
);

t.end();
});

test("getOneById() finds plugin by its instanceID", (t: Test) => {
t.doesNotThrow(() => pluginRegistry.getOneById(instanceId));
const keychainPlugin = pluginRegistry.getOneById(instanceId);
t.equal(keychainPlugin, mockKeychainPlugin, "Finds same object by ID OK");

t.throws(
() => pluginRegistry.getOneById(""),
/instanceId.*Need non-blank/,
"Check for instance ID blankness OK",
);

t.throws(
() => pluginRegistry.getOneById("x"),
/not/,
"Plugin x not present in registry",
);

t.end();
});

tMain.end();
});

0 comments on commit 5cb03d0

Please sign in to comment.