openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
283 lines (225 loc) • 9.46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.saveEvents = saveEvents;
exports.createSecondaryRouteEvents = createSecondaryRouteEvents;
exports.createTransactionEvents = createTransactionEvents;
exports.koaMiddleware = koaMiddleware;
var _moment = _interopRequireDefault(require("moment"));
var _winston = _interopRequireDefault(require("winston"));
var events = _interopRequireWildcard(require("../model/events"));
var _config = require("../config");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_config.config.events = _config.config.get('events');
let normalizationBuffer;
if (!_config.config.events) {
// maybe we're using outdated config
_config.config.events = _config.config.get('visualizer');
_config.config.events.normalizationBuffer = _config.config.events.orchestrationTsBufferMillis;
}
const enableTSNormalization = _config.config.events.enableTSNormalization != null ? _config.config.events.enableTSNormalization : false;
if (enableTSNormalization === true) {
normalizationBuffer = 100;
} else {
normalizationBuffer = 0;
}
const timestampAsMillis = ts => (0, _moment.default)(new Date(ts)).valueOf(); // Determine the difference between baseTS and the earliest timestamp
// present in a collection of routes (buffered for normalization)
function calculateEarliestRouteDiff(baseTS, routes) {
let earliestTS = 0;
for (const route of Array.from(routes)) {
const ts = timestampAsMillis(route.request.timestamp);
if (earliestTS < ts) {
earliestTS = ts;
}
}
let tsDiff = baseTS - earliestTS;
tsDiff += normalizationBuffer;
return tsDiff;
}
function determineStatusType(statusCode) {
let status = 'success';
if (statusCode >= 500 && statusCode <= 599) {
status = 'error';
}
return status;
}
function saveEvents(trxEvents, callback) {
const now = new Date();
for (const event of Array.from(trxEvents)) {
event.created = now;
} // bypass mongoose for quick batch inserts
return events.EventModel.collection.insertMany(trxEvents, err => callback(err));
}
function createRouteEvents(dst, transactionId, channel, route, type, tsAdjustment, autoRetryAttempt) {
if (route != null && route.request != null && route.request.timestamp != null && route.response != null && route.response.timestamp != null) {
let startTS = timestampAsMillis(route.request.timestamp);
let endTS = timestampAsMillis(route.response.timestamp);
if (enableTSNormalization === true) {
startTS += tsAdjustment;
endTS += tsAdjustment;
}
if (startTS > endTS) {
startTS = endTS;
}
dst.push({
channelID: channel._id,
transactionID: transactionId,
normalizedTimestamp: startTS,
type,
event: 'start',
name: route.name,
mediator: route.mediatorURN,
autoRetryAttempt
});
return dst.push({
channelID: channel._id,
transactionID: transactionId,
normalizedTimestamp: endTS,
type,
event: 'end',
name: route.name,
mediator: route.mediatorURN,
status: route.response.status,
statusType: determineStatusType(route.response.status),
autoRetryAttempt
});
}
}
function createChannelStartEvent(dst, transactionId, requestTimestamp, channel, autoRetryAttempt) {
return dst.push({
channelID: channel._id,
transactionID: transactionId,
normalizedTimestamp: timestampAsMillis(requestTimestamp),
type: 'channel',
event: 'start',
name: channel.name,
autoRetryAttempt
});
}
function createChannelEndEvent(dst, transactionId, requestTimestamp, channel, response, autoRetryAttempt) {
const startTS = timestampAsMillis(requestTimestamp);
let endTS = timestampAsMillis(response.timestamp);
if (endTS < startTS) {
endTS = startTS;
}
return dst.push({
channelID: channel._id,
transactionID: transactionId,
normalizedTimestamp: endTS + normalizationBuffer,
type: 'channel',
event: 'end',
name: channel.name,
status: response.status,
statusType: determineStatusType(response.status),
autoRetryAttempt
});
}
function createPrimaryRouteEvents(dst, transactionId, requestTimestamp, channel, routeName, mediatorURN, response, autoRetryAttempt) {
const startTS = timestampAsMillis(requestTimestamp);
dst.push({
channelID: channel._id,
transactionID: transactionId,
normalizedTimestamp: startTS,
type: 'primary',
event: 'start',
name: routeName,
mediator: mediatorURN,
autoRetryAttempt
});
let endTS = timestampAsMillis(response.timestamp);
if (endTS < startTS) {
endTS = startTS;
}
return dst.push({
channelID: channel._id,
transactionID: transactionId,
normalizedTimestamp: endTS + normalizationBuffer,
type: 'primary',
event: 'end',
name: routeName,
status: response.status,
statusType: determineStatusType(response.status),
mediator: mediatorURN,
autoRetryAttempt
});
}
function createOrchestrationEvents(dst, transactionId, requestTimestamp, channel, orchestrations) {
let tsDiff;
if (requestTimestamp) {
const startTS = timestampAsMillis(requestTimestamp);
tsDiff = calculateEarliestRouteDiff(startTS, orchestrations);
}
return Array.from(orchestrations).map(orch => createRouteEvents(dst, transactionId, channel, orch, 'orchestration', tsDiff));
}
function createSecondaryRouteEvents(dst, transactionId, requestTimestamp, channel, routes) {
const startTS = timestampAsMillis(requestTimestamp);
let tsDiff = calculateEarliestRouteDiff(startTS, routes);
const result = [];
for (const route of Array.from(routes)) {
let item;
createRouteEvents(dst, transactionId, channel, route, 'route', tsDiff);
if (route.orchestrations) {
// find TS difference
tsDiff = calculateEarliestRouteDiff(startTS, route.orchestrations);
item = Array.from(route.orchestrations).map(orch => createRouteEvents(dst, transactionId, channel, orch, 'orchestration', tsDiff));
}
result.push(item);
}
return result;
}
function createTransactionEvents(dst, transaction, channel) {
function getPrimaryRouteName() {
for (const r of Array.from(channel.routes)) {
if (r.primary) {
return r.name;
}
}
return null;
}
const timestamp = (transaction.request != null ? transaction.request.timestamp : undefined) ? transaction.request.timestamp : new Date();
if (transaction.request && transaction.response) {
createPrimaryRouteEvents(dst, transaction._id, timestamp, channel, getPrimaryRouteName(), null, transaction.response);
}
if (transaction.orchestrations) {
createOrchestrationEvents(dst, transaction._id, timestamp, channel, transaction.orchestrations);
}
if (transaction.routes) {
return createSecondaryRouteEvents(dst, transaction._id, timestamp, channel, transaction.routes);
}
}
async function koaMiddleware(ctx, next) {
const runAsync = method => {
const f = () => method(ctx, err => {
if (err) {
return _winston.default.error(err);
}
});
return setTimeout(f, 0);
};
runAsync((ctx, done) => {
_winston.default.debug(`Storing channel start event for transaction: ${ctx.transactionId}`);
const trxEvents = [];
createChannelStartEvent(trxEvents, ctx.transactionId, ctx.requestTimestamp, ctx.authorisedChannel, ctx.currentAttempt);
return saveEvents(trxEvents, done);
});
await next();
runAsync((ctx, done) => {
_winston.default.debug(`Storing channel end and primary routes events for transaction: ${ctx.transactionId}`);
const trxEvents = [];
const mediatorURN = ctx.mediatorResponse != null ? ctx.mediatorResponse['x-mediator-urn'] : undefined;
const orchestrations = ctx.mediatorResponse != null ? ctx.mediatorResponse.orchestrations : undefined;
if (ctx.primaryRoute != null) {
createPrimaryRouteEvents(trxEvents, ctx.transactionId, ctx.requestTimestamp, ctx.authorisedChannel, ctx.primaryRoute.name, mediatorURN, ctx.response, ctx.currentAttempt);
}
if (orchestrations) {
createOrchestrationEvents(trxEvents, ctx.transactionId, ctx.requestTimestamp, ctx.authorisedChannel, orchestrations, ctx.currentAttempt);
}
createChannelEndEvent(trxEvents, ctx.transactionId, ctx.requestTimestamp, ctx.authorisedChannel, ctx.response, ctx.currentAttempt);
return saveEvents(trxEvents, done);
});
}
//# sourceMappingURL=events.js.map