UNPKG

@mediarithmics/plugins-nodejs-sdk

Version:

This is the mediarithmics nodejs to help plugin developers bootstrapping their plugin without having to deal with most of the plugin boilerplate

173 lines (172 loc) 7.45 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const express = require("express"); const rp = require("request-promise-native"); const winston = require("winston"); const bodyParser = require("body-parser"); const cache = require("memory-cache"); // Helper request function class BasePlugin { constructor() { this.INSTANCE_CONTEXT_CACHE_EXPIRATION = 30000; this._transport = rp; this.asyncMiddleware = (fn) => (req, res, next) => { Promise.resolve(fn(req, res, next)).catch(next); }; const gatewayHost = process.env.GATEWAY_HOST; if (gatewayHost) { this.gatewayHost = gatewayHost; } else { this.gatewayHost = "plugin-gateway.platform"; } const gatewayPort = process.env.GATEWAY_PORT; if (gatewayPort) { this.gatewayPort = parseInt(gatewayPort); } else { this.gatewayPort = 8080; } this.outboundPlatformUrl = `http://${this.gatewayHost}:${this.gatewayPort}`; this.app = express(); this.app.use(bodyParser.json({ type: "*/*" })); this.logger = new winston.Logger({ transports: [new winston.transports.Console()], level: "info" }); this.pluginCache = cache; this.pluginCache.clear(); this.initInitRoute(); this.initStatusRoute(); this.initLogLevelUpdateRoute(); this.initLogLevelGetRoute(); } // Log level update implementation // This method can be overridden by any subclass onLogLevelUpdate(req, res) { if (req.body && req.body.level) { // Lowering case const logLevel = req.body.level.toLowerCase(); this.logger.info("Setting log level to " + req.body.level); this.logger.level = logLevel; res.status(200).end(); } else { this.logger.error("Incorrect body : Cannot change log level, actual: " + this.logger.level); res.status(400).end(); } } initLogLevelUpdateRoute() { //Route used by the plugin manager to check if the plugin is UP and running this.app.put("/v1/log_level", this.asyncMiddleware((req, res) => __awaiter(this, void 0, void 0, function* () { this.onLogLevelUpdate(req, res); }))); } // Log level update implementation // This method can be overridden by any subclass onLogLevelRequest(req, res) { res.send({ level: this.logger.level.toUpperCase() }); } initLogLevelGetRoute() { this.app.get("/v1/log_level", this.asyncMiddleware((req, res) => __awaiter(this, void 0, void 0, function* () { this.onLogLevelRequest(req, res); }))); } // Health Status implementation // This method can be overridden by any subclass onStatusRequest(req, res) { //Route used by the plugin manager to check if the plugin is UP and running this.logger.silly("GET /v1/status"); if (this.worker_id && this.authentication_token) { res.status(200).end(); } else { this.logger.error(`Plugin is not inialized yet, we don't have any worker_id & authentification_token`); res.status(503).end(); } } initStatusRoute() { this.app.get("/v1/status", this.asyncMiddleware((req, res) => __awaiter(this, void 0, void 0, function* () { this.onStatusRequest(req, res); }))); } fetchDataFile(uri) { return this.requestGatewayHelper("GET", `${this.outboundPlatformUrl}/v1/data_file/data`, undefined, { uri: uri }, false, true); } fetchConfigurationFile(fileName) { return this.requestGatewayHelper("GET", `${this.outboundPlatformUrl}/v1/configuration/technical_name=${fileName}`, undefined, undefined, false, true); } requestGatewayHelper(method, uri, body, qs, isJson, isBinary) { return __awaiter(this, void 0, void 0, function* () { let options = { method: method, uri: uri, auth: { user: this.worker_id, pass: this.authentication_token, sendImmediately: true } }; // Set the body if provided options.body = body !== undefined ? body : undefined; // Set the querystring if provided options.qs = qs !== undefined ? qs : undefined; // Set the json flag if provided options.json = isJson !== undefined ? isJson : true; // Set the encoding to null if it is binary options.encoding = (isBinary !== undefined && isBinary) ? null : undefined; this.logger.silly(`Doing gateway call with ${JSON.stringify(options)}`); try { return yield this._transport(options); } catch (e) { if (e.name === "StatusCodeError") { const bodyString = isJson !== undefined && !isJson ? body : JSON.stringify(body); throw new Error(`Error while calling ${method} '${uri}' with the request body '${bodyString || ""}': got a ${e.response.statusCode} ${e.response.statusMessage} with the response body ${JSON.stringify(e.response.body)}`); } else { this.logger.error(`Got an issue while doind a Gateway call: ${e.message} - ${e.stack}`); throw e; } } }); } // Plugin Init implementation // This method can be overridden by any subclass onInitRequest(req, res) { this.logger.debug("POST /v1/init ", req.body); if (req.body.authentication_token && req.body.worker_id) { this.authentication_token = req.body.authentication_token; this.worker_id = req.body.worker_id; this.logger.info("Update authentication_token with %s", this.authentication_token); res.status(200).end(); } else { this.logger.error(`Received /v1/init call without authentification_token or worker_id`); res.status(400).end(); } } initInitRoute() { this.app.post("/v1/init", this.asyncMiddleware((req, res) => __awaiter(this, void 0, void 0, function* () { this.onInitRequest(req, res); }))); } setErrorHandler() { this.app.use((err, req, res, next) => { this.logger.error(`Something bad happened : ${err.message} - ${err.stack}`); return res.status(500).send(err.message + "\n" + err.stack); }); } // Method to start the plugin start() { } } exports.BasePlugin = BasePlugin;