@selfage/service_handler
Version:
Http-based service handlers on top of expressjs.
81 lines • 12.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceHandler = exports.HandlerRegister = void 0;
const express = require("express");
const promClient = require("prom-client");
const base_remote_call_handler_1 = require("./base_remote_call_handler");
const cors_allowed_preflight_handler_1 = require("./cors_allowed_preflight_handler");
class HandlerRegister {
constructor(app, baseHandler, serviceDescriptor) {
this.baseHandler = baseHandler;
this.serviceDescriptor = serviceDescriptor;
this.router = express.Router();
this.addedPaths = new Set();
app.use(this.serviceDescriptor.path, this.router);
}
add(remoteCallHandler) {
if (remoteCallHandler.descriptor.service !== this.serviceDescriptor) {
throw new Error(`The remote call handler ${remoteCallHandler.descriptor.name} is defined in service ${remoteCallHandler.descriptor.service.name} but being added to service ${this.serviceDescriptor.name}.`);
}
if (this.addedPaths.has(remoteCallHandler.descriptor.path)) {
throw new Error(`The remote call handler ${remoteCallHandler.descriptor.name} is defined with a path path ${remoteCallHandler.descriptor.path} that's already registered.`);
}
this.addedPaths.add(remoteCallHandler.descriptor.path);
this.router.post(remoteCallHandler.descriptor.path, (req, res) => this.baseHandler.handle(remoteCallHandler, req, res));
return this;
}
}
exports.HandlerRegister = HandlerRegister;
class ServiceHandler {
static create(server, allowOrigin = "*") {
return new ServiceHandler(server, base_remote_call_handler_1.BaseRemoteCallHandler.create(allowOrigin), cors_allowed_preflight_handler_1.CorsAllowedPreflightHandler.create(allowOrigin));
}
constructor(server, baseHandler, corsAllowedPreflightHandler) {
this.server = server;
this.baseHandler = baseHandler;
this.corsAllowedPreflightHandler = corsAllowedPreflightHandler;
this.app = express();
this.server.on("request", this.app);
}
addCorsAllowedPreflightHandler() {
this.app.options("/*", (req, res) => this.corsAllowedPreflightHandler.handle(res));
return this;
}
addMetricsHandler() {
this.app.get("/metricsz", async (req, res) => {
res.setHeader("Content-Type", "text/plain");
res.end(await promClient.register.metrics());
});
return this;
}
addHealthCheckHandler() {
this.app.get("/healthz", (req, res) => {
res.end("OK");
});
return this;
}
addReadinessHandler() {
this.app.get("/readiness", (req, res) => {
res.end("OK");
});
return this;
}
addHandlerRegister(serviceDescriptor) {
return new HandlerRegister(this.app, this.baseHandler, serviceDescriptor);
}
async start(port) {
await new Promise((resolve) => {
this.server.listen(port, () => resolve());
});
console.log(`Server is listening on port ${port}.`);
return this;
}
async stop() {
await new Promise((resolve) => this.server.close(() => resolve()));
console.log(`Server has stopped.`);
// Wait for the server to close all connections.
await new Promise((resolve) => setTimeout(resolve, 1000));
}
}
exports.ServiceHandler = ServiceHandler;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZV9oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2VydmljZV9oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFvQztBQUdwQywwQ0FBMkM7QUFDM0MseUVBQW1FO0FBQ25FLHFGQUErRTtBQUkvRSxNQUFhLGVBQWU7SUFJMUIsWUFDRSxHQUF3QixFQUNoQixXQUFrQyxFQUNsQyxpQkFBb0M7UUFEcEMsZ0JBQVcsR0FBWCxXQUFXLENBQXVCO1FBQ2xDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFOdEMsV0FBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMxQixlQUFVLEdBQWdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFPMUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRU0sR0FBRyxDQUFDLGlCQUE2QztRQUN0RCxJQUFJLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxPQUFPLEtBQUssSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDcEUsTUFBTSxJQUFJLEtBQUssQ0FDYiwyQkFBMkIsaUJBQWlCLENBQUMsVUFBVSxDQUFDLElBQUksMEJBQTBCLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSwrQkFBK0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksR0FBRyxDQUM3TCxDQUFDO1FBQ0osQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDM0QsTUFBTSxJQUFJLEtBQUssQ0FDYiwyQkFBMkIsaUJBQWlCLENBQUMsVUFBVSxDQUFDLElBQUksZ0NBQWdDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxJQUFJLDZCQUE2QixDQUMz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RSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLENBQUMsR0FBRyxDQUFDLCtCQUErQixJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ3BELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJO1FBQ2YsTUFBTSxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNuQyxnREFBZ0Q7UUFDaEQsTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzVELENBQUM7Q0FDRjtBQXZFRCx3Q0F1RUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZXhwcmVzcyA9IHJlcXVpcmUoXCJleHByZXNzXCIpO1xuaW1wb3J0IGh0dHAgPSByZXF1aXJlKFwiaHR0cFwiKTtcbmltcG9ydCBodHRwcyA9IHJlcXVpcmUoXCJodHRwc1wiKTtcbmltcG9ydCBwcm9tQ2xpZW50ID0gcmVxdWlyZShcInByb20tY2xpZW50XCIpO1xuaW1wb3J0IHsgQmFzZVJlbW90ZUNhbGxIYW5kbGVyIH0gZnJvbSBcIi4vYmFzZV9yZW1vdGVfY2FsbF9oYW5kbGVyXCI7XG5pbXBvcnQgeyBDb3JzQWxsb3dlZFByZWZsaWdodEhhbmRsZXIgfSBmcm9tIFwiLi9jb3JzX2FsbG93ZWRfcHJlZmxpZ2h0X2hhbmRsZXJcIjtcbmltcG9ydCB7IFNlcnZpY2VEZXNjcmlwdG9yIH0gZnJvbSBcIkBzZWxmYWdlL3NlcnZpY2VfZGVzY3JpcHRvclwiO1xuaW1wb3J0IHsgUmVtb3RlQ2FsbEhhbmRsZXJJbnRlcmZhY2UgfSBmcm9tIFwiQHNlbGZhZ2Uvc2VydmljZV9kZXNjcmlwdG9yL3JlbW90ZV9jYWxsX2hhbmRsZXJfaW50ZXJmYWNlXCI7XG5cbmV4cG9ydCBjbGFzcyBIYW5kbGVyUmVnaXN0ZXIge1xuICBwcml2YXRlIHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gIHByaXZhdGUgYWRkZWRQYXRoczogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgIGFwcDogZXhwcmVzcy5BcHBsaWNhdGlvbixcbiAgICBwcml2YXRlIGJhc2VIYW5kbGVyOiBCYXNlUmVtb3RlQ2FsbEhhbmRsZXIsXG4gICAgcHJpdmF0ZSBzZXJ2aWNlRGVzY3JpcHRvcjogU2VydmljZURlc2NyaXB0b3IsXG4gICkge1xuICAgIGFwcC51c2UodGhpcy5zZXJ2aWNlRGVzY3JpcHRvci5wYXRoLCB0aGlzLnJvdXRlcik7XG4gIH1cblxuICBwdWJsaWMgYWRkKHJlbW90ZUNhbGxIYW5kbGVyOiBSZW1vdGVDYWxsSGFuZGxlckludGVyZmFjZSk6IHRoaXMge1xuICAgIGlmIChyZW1vdGVDYWxsSGFuZGxlci5kZXNjcmlwdG9yLnNlcnZpY2UgIT09IHRoaXMuc2VydmljZURlc2NyaXB0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFRoZSByZW1vdGUgY2FsbCBoYW5kbGVyICR7cmVtb3RlQ2FsbEhhbmRsZXIuZGVzY3JpcHRvci5uYW1lfSBpcyBkZWZpbmVkIGluIHNlcnZpY2UgJHtyZW1vdGVDYWxsSGFuZGxlci5kZXNjcmlwdG9yLnNlcnZpY2UubmFtZX0gYnV0IGJlaW5nIGFkZGVkIHRvIHNlcnZpY2UgJHt0aGlzLnNlcnZpY2VEZXNjcmlwdG9yLm5hbWV9LmAsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAodGhpcy5hZGRlZFBhdGhzLmhhcyhyZW1vdGVDYWxsSGFuZGxlci5kZXNjcmlwdG9yLnBhdGgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBUaGUgcmVtb3RlIGNhbGwgaGFuZGxlciAke3JlbW90ZUNhbGxIYW5kbGVyLmRlc2NyaXB0b3IubmFtZX0gaXMgZGVmaW5lZCB3aXRoIGEgcGF0aCBwYXRoICR7cmVtb3RlQ2FsbEhhbmRsZXIuZGVzY3JpcHRvci5wYXRofSB0aGF0J3MgYWxyZWFkeSByZWdpc3RlcmVkLmAsXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmFkZGVkUGF0aHMuYWRkKHJlbW90ZUNhbGxIYW5kbGVyLmRlc2NyaXB0b3IucGF0aCk7XG5cbiAgICB0aGlzLnJvdXRlci5wb3N0KHJlbW90ZUNhbGxIYW5kbGVyLmRlc2NyaXB0b3IucGF0aCwgKHJlcSwgcmVzKSA9PlxuICAgICAgdGhpcy5iYXNlSGFuZGxlci5oYW5kbGUocmVtb3RlQ2FsbEhhbmRsZXIsIHJlcSwgcmVzKSxcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTZXJ2aWNlSGFuZGxlciB7XG4gIHB1YmxpYyBzdGF0aWMgY3JlYXRlKFxuICAgIHNlcnZlcjogaHR0cC5TZXJ2ZXIgfCBodHRwcy5TZXJ2ZXIsXG4gICAgYWxsb3dPcmlnaW46IHN0cmluZyA9IFwiKlwiLFxuICApOiBTZXJ2aWNlSGFuZGxlciB7XG4gICAgcmV0dXJuIG5ldyBTZXJ2aWNlSGFuZGxlcihcbiAgICAgIHNlcnZlcixcbiAgICAgIEJhc2VSZW1vdGVDYWxsSGFuZGxlci5jcmVhdGUoYWxsb3dPcmlnaW4pLFxuICAgICAgQ29yc0FsbG93ZWRQcmVmbGlnaHRIYW5kbGVyLmNyZWF0ZShhbGxvd09yaWdpbiksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwID0gZXhwcmVzcygpO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHNlcnZlcjogaHR0cC5TZXJ2ZXIgfCBodHRwcy5TZXJ2ZXIsXG4gICAgcHJpdmF0ZSBiYXNlSGFuZGxlcjogQmFzZVJlbW90ZUNhbGxIYW5kbGVyLFxuICAgIHByaXZhdGUgY29yc0FsbG93ZWRQcmVmbGlnaHRIYW5kbGVyOiBDb3JzQWxsb3dlZFByZWZsaWdodEhhbmRsZXIsXG4gICkge1xuICAgIHRoaXMuc2VydmVyLm9uKFwicmVxdWVzdFwiLCB0aGlzLmFwcCk7XG4gIH1cblxuICBwdWJsaWMgYWRkQ29yc0FsbG93ZWRQcmVmbGlnaHRIYW5kbGVyKCk6IHRoaXMge1xuICAgIHRoaXMuYXBwLm9wdGlvbnMoXCIvKlwiLCAocmVxLCByZXMpID0+XG4gICAgICB0aGlzLmNvcnNBbGxvd2VkUHJlZmxpZ2h0SGFuZGxlci5oYW5kbGUocmVzKSxcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGFkZE1ldHJpY3NIYW5kbGVyKCk6IHRoaXMge1xuICAgIHRoaXMuYXBwLmdldChcIi9tZXRyaWNzelwiLCBhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICAgIHJlcy5zZXRIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJ0ZXh0L3BsYWluXCIpO1xuICAgICAgcmVzLmVuZChhd2FpdCBwcm9tQ2xpZW50LnJlZ2lzdGVyLm1ldHJpY3MoKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBwdWJsaWMgYWRkSGVhbHRoQ2hlY2tIYW5kbGVyKCk6IHRoaXMge1xuICAgIHRoaXMuYXBwLmdldChcIi9oZWFsdGh6XCIsIChyZXEsIHJlcykgPT4ge1xuICAgICAgcmVzLmVuZChcIk9LXCIpO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGFkZFJlYWRpbmVzc0hhbmRsZXIoKTogdGhpcyB7XG4gICAgdGhpcy5hcHAuZ2V0KFwiL3JlYWRpbmVzc1wiLCAocmVxLCByZXMpID0+IHtcbiAgICAgIHJlcy5lbmQoXCJPS1wiKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBhZGRIYW5kbGVyUmVnaXN0ZXIoXG4gICAgc2VydmljZURlc2NyaXB0b3I6IFNlcnZpY2VEZXNjcmlwdG9yLFxuICApOiBIYW5kbGVyUmVnaXN0ZXIge1xuICAgIHJldHVybiBuZXcgSGFuZGxlclJlZ2lzdGVyKHRoaXMuYXBwLCB0aGlzLmJhc2VIYW5kbGVyLCBzZXJ2aWNlRGVzY3JpcHRvcik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc3RhcnQocG9ydDogbnVtYmVyKTogUHJvbWlzZTx0aGlzPiB7XG4gICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgIHRoaXMuc2VydmVyLmxpc3Rlbihwb3J0LCAoKSA9PiByZXNvbHZlKCkpO1xuICAgIH0pO1xuICAgIGNvbnNvbGUubG9nKGBTZXJ2ZXIgaXMgbGlzdGVuaW5nIG9uIHBvcnQgJHtwb3J0fS5gKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB0aGlzLnNlcnZlci5jbG9zZSgoKSA9PiByZXNvbHZlKCkpKTtcbiAgICBjb25zb2xlLmxvZyhgU2VydmVyIGhhcyBzdG9wcGVkLmApO1xuICAgIC8vIFdhaXQgZm9yIHRoZSBzZXJ2ZXIgdG8gY2xvc2UgYWxsIGNvbm5lY3Rpb25zLlxuICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDEwMDApKTtcbiAgfVxufVxuIl19