@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
JavaScript
;
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;