UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

279 lines (229 loc) 8.87 kB
'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