Skip to content

Commit ad01dee

Browse files
committed
feat(common): Servers utility class
Useful when working with HTTP servers especially for test case authoring where there's a lot of server creation for the purpose of allocating random ports prior to launching an API server instance. Fixes hyperledger-cacti#260 Fixes hyperledger-cacti#267 Signed-off-by: Peter Somogyvari <[email protected]>
1 parent c65baf8 commit ad01dee

File tree

4 files changed

+69
-34
lines changed

4 files changed

+69
-34
lines changed

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ import {
2626
} from "@hyperledger/cactus-core-api";
2727
import { ICactusApiServerOptions } from "./config/config-service";
2828
import { CACTUS_OPEN_API_JSON } from "./openapi-spec";
29-
import { Logger, LoggerProvider } from "@hyperledger/cactus-common";
30-
import { Servers } from "./common/servers";
29+
import { Logger, LoggerProvider, Servers } from "@hyperledger/cactus-common";
3130

3231
export interface IApiServerConstructorOptions {
3332
pluginRegistry?: PluginRegistry;

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

-32
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from "./public-api";
2+
export { IListenOptions, Servers } from "./servers";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { AddressInfo, ListenOptions } from "net";
2+
import { Server } from "http";
3+
import { Server as SecureServer } from "https";
4+
import { Checks } from "./checks";
5+
6+
export interface IListenOptions {
7+
server: Server | SecureServer;
8+
port: number;
9+
hostname: string;
10+
}
11+
12+
/**
13+
* Utility class for handling common tasks for NodeJS HTTP/S server objects.
14+
*/
15+
export class Servers {
16+
/**
17+
* Returns with a promise that resolves when the server has been shut down. Rejects if anything goes wrong of if the
18+
* parameters are invalid.
19+
*
20+
* @param server The server object that will be shut down.
21+
*/
22+
public static async shutdown(server: Server | SecureServer): Promise<void> {
23+
if (!server) {
24+
throw new TypeError(`Servers#shutdown() server was falsy. Need object.`);
25+
}
26+
return new Promise<void>((resolve, reject) => {
27+
server.close((err: any) => {
28+
if (err) {
29+
reject(
30+
new Error(
31+
`Servers#shutdown() Failed to shut down server: ${err.stack}`
32+
)
33+
);
34+
} else {
35+
resolve();
36+
}
37+
});
38+
});
39+
}
40+
41+
public static async listen(options: IListenOptions): Promise<any> {
42+
const fnTag = "Servers#listen()";
43+
44+
Checks.truthy(options, `${fnTag} arg options`);
45+
Checks.truthy(options.server, `${fnTag} arg options.server`);
46+
Checks.truthy(options.port, `${fnTag} arg options.port`);
47+
Checks.truthy(options.hostname, `${fnTag} arg options.hostname`);
48+
const { server, port, hostname } = options;
49+
50+
return new Promise((resolve, reject) => {
51+
server.on("error", (ex) => reject(ex));
52+
53+
const listenOptions: ListenOptions = {
54+
host: hostname,
55+
port,
56+
};
57+
58+
// called when the `listening` event is fired
59+
const onListeningHandler = () => {
60+
const addressInfo = options.server.address() as AddressInfo;
61+
resolve(addressInfo);
62+
};
63+
64+
server.listen(listenOptions, onListeningHandler);
65+
});
66+
}
67+
}

0 commit comments

Comments
 (0)