Skip to content

Commit dcdfcf5

Browse files
committed
fix(api-server): runtime plugin imports
- 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-cacti#346 Signed-off-by: Peter Somogyvari <[email protected]>
1 parent 29665bc commit dcdfcf5

File tree

17 files changed

+1232
-674
lines changed

17 files changed

+1232
-674
lines changed

package-lock.json

+911-654
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
"ts-node": "8.9.1",
9595
"tslint": "6.0.0",
9696
"typescript": "4.0.3",
97-
"webpack": "5.4.0",
97+
"webpack": "git+https://github.com/petermetz/webpack.git#a1021fd674dd24b13d759611b77b5d7057f7f0ea",
9898
"webpack-bundle-analyzer": "3.6.0",
9999
"webpack-cli": "3.3.11"
100100
},

packages/cactus-cmd-api-server/src/main/typescript/cmd/cactus-api.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,16 @@ const main = async () => {
2828
}
2929
};
3030

31-
main()
32-
.then(() => {
31+
export async function launchApp(cliOpts?: any): Promise<void> {
32+
try {
33+
await main();
3334
log.info(`Cactus API server launched OK `);
34-
})
35-
.catch((ex) => {
35+
} catch (ex) {
3636
log.error(`Cactus API server crashed: `, ex);
3737
process.exit(1);
38-
});
38+
}
39+
}
40+
41+
if (require.main === module) {
42+
launchApp();
43+
}

packages/cactus-cmd-api-server/src/main/typescript/public-api.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export { ApiServer, IApiServerConstructorOptions } from "./api-server";
22

3+
export { launchApp } from "./cmd/cactus-api";
4+
35
export {
46
ConfigService,
57
IPluginImport,
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
// tslint:disable-next-line: no-var-requires
2-
const tap = require("tap");
3-
import { ApiServer } from "../../../main/typescript/public-api";
1+
import test, { Test } from "tape";
42

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

7-
tap.test("Library can be loaded", (assert: any) => {
8-
assert.plan(1);
9-
assert.ok(ApiServer);
5+
test("Library can be loaded", (t: Test) => {
6+
t.ok(publicApi);
7+
t.end();
108
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import test, { Test } from "tape-promise/tape";
2+
import { v4 as uuidv4 } from "uuid";
3+
4+
import { LogLevelDesc } from "@hyperledger/cactus-common";
5+
import { PluginRegistry } from "@hyperledger/cactus-core-api";
6+
7+
import { ApiServer, ConfigService } from "../../../main/typescript/public-api";
8+
import { IPluginKeychainMemoryOptions } from "../../../../../cactus-plugin-keychain-memory/dist/types/main/typescript";
9+
10+
const logLevel: LogLevelDesc = "TRACE";
11+
12+
test("can import plugins at runtime (CLI)", async (t: Test) => {
13+
const pluginRegistry = new PluginRegistry({ plugins: [] });
14+
15+
const configService = new ConfigService();
16+
const apiServerOptions = configService.newExampleConfig();
17+
apiServerOptions.configFile = "";
18+
apiServerOptions.apiCorsDomainCsv = "*";
19+
apiServerOptions.apiPort = 0;
20+
apiServerOptions.cockpitPort = 0;
21+
apiServerOptions.apiTlsEnabled = false;
22+
apiServerOptions.plugins = [
23+
{
24+
packageName: "@hyperledger/cactus-plugin-keychain-memory",
25+
options: {
26+
instanceId: uuidv4(),
27+
keychainId: uuidv4(),
28+
logLevel,
29+
} as IPluginKeychainMemoryOptions,
30+
},
31+
];
32+
const config = configService.newExampleConfigConvict(apiServerOptions);
33+
34+
const apiServer = new ApiServer({
35+
config: config.getProperties(),
36+
});
37+
38+
await t.doesNotReject(
39+
apiServer.start(),
40+
"failed to start API server with dynamic plugin imports configured for it..."
41+
);
42+
test.onFinish(() => apiServer.shutdown());
43+
});
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
// tslint:disable-next-line: no-var-requires
2-
const tap = require("tap");
3-
import { ApiServer } from "../../../main/typescript/public-api";
1+
import test, { Test } from "tape";
42

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

7-
tap.test("Library can be loaded", (assert: any) => {
8-
assert.plan(1);
9-
assert.ok(ApiServer);
5+
test("Library can be loaded", (t: Test) => {
6+
t.ok(publicApi);
7+
t.end();
108
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# `@hyperledger/cactus-test-cmd-api-server`
2+
3+
This is the test package for the package that's called `cactus-cmd-api-server`
4+
5+
## Usage
6+
7+
```
8+
// TODO: DEMONSTRATE API
9+
```
10+
11+
## FAQ
12+
13+
### **What is a dedicated test package for?**
14+
15+
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.

packages/cactus-test-cmd-api-server/package-lock.json

+84
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"name": "@hyperledger/cactus-test-cmd-api-server",
3+
"version": "0.2.0",
4+
"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)",
5+
"main": "dist/cactus-test-cmd-api-server.node.umd.js",
6+
"mainMinified": "dist/cactus-test-cmd-api-server.node.umd.min.js",
7+
"browser": "dist/cactus-test-cmd-api-server.web.umd.js",
8+
"browserMinified": "dist/cactus-test-cmd-api-server.web.umd.min.js",
9+
"module": "dist/lib/main/typescript/index.js",
10+
"types": "dist/types/main/typescript/index.d.ts",
11+
"files": [
12+
"dist/*"
13+
],
14+
"scripts": {
15+
"tsc": "tsc --project ./tsconfig.json",
16+
"webpack": "npm-run-all webpack:dev webpack:prod",
17+
"webpack:dev": "npm-run-all webpack:dev:node webpack:dev:web",
18+
"webpack:dev:web": "webpack --env=dev --target=web --config ../../webpack.config.js",
19+
"webpack:dev:node": "webpack --env=dev --target=node --config ../../webpack.config.js",
20+
"webpack:prod": "npm-run-all webpack:prod:node webpack:prod:web",
21+
"webpack:prod:web": "webpack --env=prod --target=web --config ../../webpack.config.js",
22+
"webpack:prod:node": "webpack --env=prod --target=node --config ../../webpack.config.js"
23+
},
24+
"publishConfig": {
25+
"access": "public"
26+
},
27+
"engines": {
28+
"node": ">=10",
29+
"npm": ">=6"
30+
},
31+
"repository": {
32+
"type": "git",
33+
"url": "git+https://github.com/hyperledger/cactus.git"
34+
},
35+
"keywords": [
36+
"Hyperledger",
37+
"Cactus",
38+
"Integration",
39+
"Blockchain",
40+
"Distributed Ledger Technology"
41+
],
42+
"author": {
43+
"name": "Hyperledger Cactus Contributors",
44+
"email": "[email protected]",
45+
"url": "https://www.hyperledger.org/use/cactus"
46+
},
47+
"contributors": [
48+
{
49+
"name": "Please add yourself to the list of contributors",
50+
"email": "[email protected]",
51+
"url": "https://example.com"
52+
},
53+
{
54+
"name": "Peter Somogyvari",
55+
"email": "[email protected]",
56+
"url": "https://accenture.com"
57+
}
58+
],
59+
"license": "Apache-2.0",
60+
"bugs": {
61+
"url": "https://github.com/hyperledger/cactus/issues"
62+
},
63+
"homepage": "https://github.com/hyperledger/cactus#readme",
64+
"dependencies": {
65+
"@hyperledger/cactus-api-client": "^0.2.0",
66+
"@hyperledger/cactus-cmd-api-server": "^0.2.0",
67+
"@hyperledger/cactus-common": "0.2.0",
68+
"@hyperledger/cactus-core-api": "^0.2.0",
69+
"@hyperledger/cactus-plugin-consortium-manual": "^0.2.0",
70+
"@hyperledger/cactus-plugin-keychain-memory": "^0.2.0",
71+
"@hyperledger/cactus-plugin-ledger-connector-besu": "^0.2.0",
72+
"@hyperledger/cactus-plugin-ledger-connector-fabric": "^0.2.0",
73+
"@hyperledger/cactus-plugin-ledger-connector-quorum": "^0.2.0",
74+
"axios": "0.19.2",
75+
"joi": "14.3.1",
76+
"typescript-optional": "2.0.1"
77+
},
78+
"devDependencies": {
79+
"@hyperledger/cactus-test-tooling": "0.2.0",
80+
"@types/joi": "14.3.4"
81+
}
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./public-api";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import test, { Test } from "tape";
2+
import * as publicApi from "../../../main/typescript/public-api";
3+
4+
test("Library can be loaded", (t: Test) => {
5+
t.plan(1);
6+
t.ok(publicApi);
7+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import test, { Test } from "tape-promise/tape";
2+
import { v4 as uuidv4 } from "uuid";
3+
4+
import { LogLevelDesc } from "@hyperledger/cactus-common";
5+
import { PluginRegistry } from "@hyperledger/cactus-core-api";
6+
7+
import { ApiServer, ConfigService } from "@hyperledger/cactus-cmd-api-server";
8+
import { IPluginKeychainMemoryOptions } from "@hyperledger/cactus-plugin-keychain-memory";
9+
10+
const logLevel: LogLevelDesc = "TRACE";
11+
12+
test("can import plugins at runtime (CLI)", async (t: Test) => {
13+
// const pluginRegistry = new PluginRegistry({ plugins: [] });
14+
15+
const configService = new ConfigService();
16+
const apiServerOptions = configService.newExampleConfig();
17+
apiServerOptions.configFile = "";
18+
apiServerOptions.apiCorsDomainCsv = "*";
19+
apiServerOptions.apiPort = 0;
20+
apiServerOptions.cockpitPort = 0;
21+
apiServerOptions.apiTlsEnabled = false;
22+
apiServerOptions.plugins = [
23+
{
24+
packageName: "@hyperledger/cactus-plugin-keychain-memory",
25+
options: {
26+
instanceId: uuidv4(),
27+
keychainId: uuidv4(),
28+
logLevel,
29+
} as IPluginKeychainMemoryOptions,
30+
},
31+
];
32+
const config = configService.newExampleConfigConvict(apiServerOptions);
33+
34+
const apiServer = new ApiServer({
35+
config: config.getProperties(),
36+
});
37+
38+
await t.doesNotReject(
39+
apiServer.start(),
40+
"failed to start API server with dynamic plugin imports configured for it..."
41+
);
42+
test.onFinish(() => apiServer.shutdown());
43+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// tslint:disable-next-line: no-var-requires
2+
const tap = require("tap");
3+
import * as publicApi from "../../../main/typescript/public-api";
4+
5+
tap.pass("Test file can be executed");
6+
7+
tap.test("Library can be loaded", (assert: any) => {
8+
assert.plan(1);
9+
assert.ok(publicApi);
10+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "./dist/lib/", /* Redirect output structure to the directory. */
5+
"declarationDir": "dist/types",
6+
"resolveJsonModule": true,
7+
},
8+
"include": [
9+
"./src"
10+
]
11+
}

0 commit comments

Comments
 (0)