openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
279 lines (229 loc) • 8.87 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.saveEvents = saveEvents;
exports.createSecondaryRouteEvents = createSecondaryRouteEvents;
exports.createTransactionEvents = createTransactionEvents;
exports.koaMiddleware = koaMiddleware;
var _moment = require('moment');
var _moment2 = _interopRequireDefault(_moment);
var _winston = require('winston');
var _winston2 = _interopRequireDefault(_winston);
var _events = require('../model/events');
var events = _interopRequireWildcard(_events);
var _config = require('../config');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; 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, _moment2.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.insert(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 _winston2.default.error(err);
}
});
return setTimeout(f, 0);
};
runAsync((ctx, done) => {
_winston2.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) => {
_winston2.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