@universis/jrs-worker
Version:
JasperReports Server Worker for Universis Platform
156 lines (144 loc) • 6.58 kB
JavaScript
;
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