Skip to content

Commit

Permalink
fix(api-server): runtime plugin imports
Browse files Browse the repository at this point in the history
- Upgrades webpack to the version[1] of it that
supports the webpackIgnore magic comment
for require calls not just for import calls.

- Adds a dedicated test package for the API server
which is necessary because that's how we can
verify that not just the Typescript compilation
output (./dist/lib/.../*.js) files but also
the webpack bundles are good when it comes to
runtime plugin importing.
Why? Because only when importing from another
package will the bundle be used so the local
test cases inside the cmd-api-server package
directory could not verify this particular
edge case.

[1]: This version is not yet officially released
becaue the PR for it has been stuck without review
since August 2020 so for now the workaround for
that is to specify the webpack version as the
direct commit reference on the fork that has the
required enhancements for this issue to be resolved.

Fixes hyperledger#346

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed Dec 1, 2020
1 parent 29665bc commit dcdfcf5
Show file tree
Hide file tree
Showing 17 changed files with 1,232 additions and 674 deletions.
1,565 changes: 911 additions & 654 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"ts-node": "8.9.1",
"tslint": "6.0.0",
"typescript": "4.0.3",
"webpack": "5.4.0",
"webpack": "git+https://github.com/petermetz/webpack.git#a1021fd674dd24b13d759611b77b5d7057f7f0ea",
"webpack-bundle-analyzer": "3.6.0",
"webpack-cli": "3.3.11"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ const main = async () => {
}
};

main()
.then(() => {
export async function launchApp(cliOpts?: any): Promise<void> {
try {
await main();
log.info(`Cactus API server launched OK `);
})
.catch((ex) => {
} catch (ex) {
log.error(`Cactus API server crashed: `, ex);
process.exit(1);
});
}
}

if (require.main === module) {
launchApp();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export { ApiServer, IApiServerConstructorOptions } from "./api-server";

export { launchApp } from "./cmd/cactus-api";

export {
ConfigService,
IPluginImport,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// tslint:disable-next-line: no-var-requires
const tap = require("tap");
import { ApiServer } from "../../../main/typescript/public-api";
import test, { Test } from "tape";

tap.pass("Test file can be executed");
import * as publicApi from "../../../main/typescript/public-api";

tap.test("Library can be loaded", (assert: any) => {
assert.plan(1);
assert.ok(ApiServer);
test("Library can be loaded", (t: Test) => {
t.ok(publicApi);
t.end();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import test, { Test } from "tape-promise/tape";
import { v4 as uuidv4 } from "uuid";

import { LogLevelDesc } from "@hyperledger/cactus-common";
import { PluginRegistry } from "@hyperledger/cactus-core-api";

import { ApiServer, ConfigService } from "../../../main/typescript/public-api";
import { IPluginKeychainMemoryOptions } from "../../../../../cactus-plugin-keychain-memory/dist/types/main/typescript";

const logLevel: LogLevelDesc = "TRACE";

test("can import plugins at runtime (CLI)", async (t: Test) => {
const pluginRegistry = new PluginRegistry({ plugins: [] });

const configService = new ConfigService();
const apiServerOptions = configService.newExampleConfig();
apiServerOptions.configFile = "";
apiServerOptions.apiCorsDomainCsv = "*";
apiServerOptions.apiPort = 0;
apiServerOptions.cockpitPort = 0;
apiServerOptions.apiTlsEnabled = false;
apiServerOptions.plugins = [
{
packageName: "@hyperledger/cactus-plugin-keychain-memory",
options: {
instanceId: uuidv4(),
keychainId: uuidv4(),
logLevel,
} as IPluginKeychainMemoryOptions,
},
];
const config = configService.newExampleConfigConvict(apiServerOptions);

const apiServer = new ApiServer({
config: config.getProperties(),
});

await t.doesNotReject(
apiServer.start(),
"failed to start API server with dynamic plugin imports configured for it..."
);
test.onFinish(() => apiServer.shutdown());
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// tslint:disable-next-line: no-var-requires
const tap = require("tap");
import { ApiServer } from "../../../main/typescript/public-api";
import test, { Test } from "tape";

tap.pass("Test file can be executed");
import * as publicApi from "../../../main/typescript/public-api";

tap.test("Library can be loaded", (assert: any) => {
assert.plan(1);
assert.ok(ApiServer);
test("Library can be loaded", (t: Test) => {
t.ok(publicApi);
t.end();
});
15 changes: 15 additions & 0 deletions packages/cactus-test-cmd-api-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# `@hyperledger/cactus-test-cmd-api-server`

This is the test package for the package that's called `cactus-cmd-api-server`

## Usage

```
// TODO: DEMONSTRATE API
```

## FAQ

### **What is a dedicated test package for?**

This is a dedicated test package meaning that it verifies the integration between two packages that are somehow dependent on each other and therefore these tests cannot be added properly in the child package due to circular dependency issues and it would not be fitting to add it in the parent because the child package's tests should not be held by the parent as a matter of principle.
84 changes: 84 additions & 0 deletions packages/cactus-test-cmd-api-server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 82 additions & 0 deletions packages/cactus-test-cmd-api-server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"name": "@hyperledger/cactus-test-cmd-api-server",
"version": "0.2.0",
"description": "Integration tests for the Cactus API Client package (formerly known as the Cactus SDK package that has been renamed for to purpose of being less ambiguous)",
"main": "dist/cactus-test-cmd-api-server.node.umd.js",
"mainMinified": "dist/cactus-test-cmd-api-server.node.umd.min.js",
"browser": "dist/cactus-test-cmd-api-server.web.umd.js",
"browserMinified": "dist/cactus-test-cmd-api-server.web.umd.min.js",
"module": "dist/lib/main/typescript/index.js",
"types": "dist/types/main/typescript/index.d.ts",
"files": [
"dist/*"
],
"scripts": {
"tsc": "tsc --project ./tsconfig.json",
"webpack": "npm-run-all webpack:dev webpack:prod",
"webpack:dev": "npm-run-all webpack:dev:node webpack:dev:web",
"webpack:dev:web": "webpack --env=dev --target=web --config ../../webpack.config.js",
"webpack:dev:node": "webpack --env=dev --target=node --config ../../webpack.config.js",
"webpack:prod": "npm-run-all webpack:prod:node webpack:prod:web",
"webpack:prod:web": "webpack --env=prod --target=web --config ../../webpack.config.js",
"webpack:prod:node": "webpack --env=prod --target=node --config ../../webpack.config.js"
},
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=10",
"npm": ">=6"
},
"repository": {
"type": "git",
"url": "git+https://github.com/hyperledger/cactus.git"
},
"keywords": [
"Hyperledger",
"Cactus",
"Integration",
"Blockchain",
"Distributed Ledger Technology"
],
"author": {
"name": "Hyperledger Cactus Contributors",
"email": "cactus@lists.hyperledger.org",
"url": "https://www.hyperledger.org/use/cactus"
},
"contributors": [
{
"name": "Please add yourself to the list of contributors",
"email": "your.name@example.com",
"url": "https://example.com"
},
{
"name": "Peter Somogyvari",
"email": "peter.somogyvari@accenture.com",
"url": "https://accenture.com"
}
],
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/hyperledger/cactus/issues"
},
"homepage": "https://github.com/hyperledger/cactus#readme",
"dependencies": {
"@hyperledger/cactus-api-client": "^0.2.0",
"@hyperledger/cactus-cmd-api-server": "^0.2.0",
"@hyperledger/cactus-common": "0.2.0",
"@hyperledger/cactus-core-api": "^0.2.0",
"@hyperledger/cactus-plugin-consortium-manual": "^0.2.0",
"@hyperledger/cactus-plugin-keychain-memory": "^0.2.0",
"@hyperledger/cactus-plugin-ledger-connector-besu": "^0.2.0",
"@hyperledger/cactus-plugin-ledger-connector-fabric": "^0.2.0",
"@hyperledger/cactus-plugin-ledger-connector-quorum": "^0.2.0",
"axios": "0.19.2",
"joi": "14.3.1",
"typescript-optional": "2.0.1"
},
"devDependencies": {
"@hyperledger/cactus-test-tooling": "0.2.0",
"@types/joi": "14.3.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./public-api";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import test, { Test } from "tape";
import * as publicApi from "../../../main/typescript/public-api";

test("Library can be loaded", (t: Test) => {
t.plan(1);
t.ok(publicApi);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import test, { Test } from "tape-promise/tape";
import { v4 as uuidv4 } from "uuid";

import { LogLevelDesc } from "@hyperledger/cactus-common";
import { PluginRegistry } from "@hyperledger/cactus-core-api";

import { ApiServer, ConfigService } from "@hyperledger/cactus-cmd-api-server";
import { IPluginKeychainMemoryOptions } from "@hyperledger/cactus-plugin-keychain-memory";

const logLevel: LogLevelDesc = "TRACE";

test("can import plugins at runtime (CLI)", async (t: Test) => {
// const pluginRegistry = new PluginRegistry({ plugins: [] });

const configService = new ConfigService();
const apiServerOptions = configService.newExampleConfig();
apiServerOptions.configFile = "";
apiServerOptions.apiCorsDomainCsv = "*";
apiServerOptions.apiPort = 0;
apiServerOptions.cockpitPort = 0;
apiServerOptions.apiTlsEnabled = false;
apiServerOptions.plugins = [
{
packageName: "@hyperledger/cactus-plugin-keychain-memory",
options: {
instanceId: uuidv4(),
keychainId: uuidv4(),
logLevel,
} as IPluginKeychainMemoryOptions,
},
];
const config = configService.newExampleConfigConvict(apiServerOptions);

const apiServer = new ApiServer({
config: config.getProperties(),
});

await t.doesNotReject(
apiServer.start(),
"failed to start API server with dynamic plugin imports configured for it..."
);
test.onFinish(() => apiServer.shutdown());
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// tslint:disable-next-line: no-var-requires
const tap = require("tap");
import * as publicApi from "../../../main/typescript/public-api";

tap.pass("Test file can be executed");

tap.test("Library can be loaded", (assert: any) => {
assert.plan(1);
assert.ok(publicApi);
});
11 changes: 11 additions & 0 deletions packages/cactus-test-cmd-api-server/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist/lib/", /* Redirect output structure to the directory. */
"declarationDir": "dist/types",
"resolveJsonModule": true,
},
"include": [
"./src"
]
}

0 comments on commit dcdfcf5

Please sign in to comment.