UNPKG

@universis/jrs-worker

Version:

JasperReports Server Worker for Universis Platform

156 lines (144 loc) 6.58 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var express = require('express'); var httpProxyMiddleware = require('http-proxy-middleware'); var genericPool = require('generic-pool'); var common = require('@themost/common'); var url = require('url'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var express__default = /*#__PURE__*/_interopDefaultLegacy(express); var genericPool__default = /*#__PURE__*/_interopDefaultLegacy(genericPool); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 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) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; class JrsWorker { constructor() { this.active = false; } // eslint-disable-next-line @typescript-eslint/require-await connect() { return __awaiter(this, void 0, void 0, function* () { this.active = true; return this; }); } // eslint-disable-next-line @typescript-eslint/require-await disconnect() { return __awaiter(this, void 0, void 0, function* () { if (this.active) { this.active = false; } }); } } const factory = { create: () => { return new JrsWorker().connect(); }, destroy: (worker) => { return worker.disconnect(); } }; function jrsWorkerRouter(configuration) { // prepare router const router = express__default["default"].Router(); // create worker pool (limit to 1 worker) /** * get jasper server configuration */ const jasperServer = configuration.getSourceAt('settings/jrsWorker'); // get worker pool options // read more about generic pool options at https://github.com/coopernurse/node-pool?tab=readme-ov-file#createpool const opts = Object.assign({}, { "max": 1, "min": 0, // minimum size of the pool }, jasperServer.workerPool); // create worker pool const pool = genericPool__default["default"].createPool(factory, opts); // check if jasper server configuration is valid common.Args.check(jasperServer && jasperServer.target, 'Jasper Server configuration is not valid. Expected target server.'); // use jasper server target as proxy target const { pathname } = new url.URL(jasperServer.target); const target = new url.URL('/', jasperServer.target).toString(); router.use(pathname, (req, res, next) => { void pool.acquire().then((worker) => { req.worker = worker; next(); }).catch((err) => { return next(err); }); }, httpProxyMiddleware.createProxyMiddleware({ target, logLevel: configuration.getSourceAt('settings/jrsWorker/logLevel') || 'info', changeOrigin: true, selfHandleResponse: true, onError: (err, req, res) => { // get request as url object const requestURL = new url.URL(req.url, jasperServer.target); // remove client access token (for security reasons) requestURL.searchParams.delete('REPORT_CLIENT_TOKEN'); // log error common.TraceUtils.error(`Proxy error on ${requestURL.toString()}`); common.TraceUtils.error(err); // release worker // eslint-disable-next-line @typescript-eslint/no-floating-promises pool.release(req.worker).then(() => { // and send error to client res.writeHead(500); res.end('An error has occurred while proxying request to report server.'); }).catch((error) => { // log error unhandled error while finalizing request common.TraceUtils.error(error); // write error res.writeHead(500); res.end('An error has occurred while finalizing request.'); }).finally(() => { // remove worker from request delete req.worker; }); }, // eslint-disable-next-line @typescript-eslint/no-unused-vars onClose: (res, socket, head) => { const worker = res.req && res.req.worker; if (worker == null) { return; } // eslint-disable-next-line @typescript-eslint/no-floating-promises pool.release(res.req.worker).then(() => { delete res.req.worker; }); }, // eslint-disable-next-line @typescript-eslint/no-misused-promises, @typescript-eslint/no-unused-vars onProxyRes: httpProxyMiddleware.responseInterceptor((responseBuffer, proxyRes, req, res) => __awaiter(this, void 0, void 0, function* () { yield pool.release(req.worker); // remove worker from request delete req.worker; return responseBuffer; })) })); return router; } exports.jrsWorkerRouter = jrsWorkerRouter; //# sourceMappingURL=index.js.map