UNPKG

trade360-nodejs-sdk

Version:

LSports Trade360 SDK for Node.js

175 lines 7.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MessageConsumer = void 0; const lodash_1 = require("lodash"); const _entities_1 = require("../../../entities/core-entities/index.js"); const _utilities_1 = require("../../../utilities"); const handler_1 = require("./handler"); /** * Convert json string to WrappedMessage instance * @param rawJson json string to be converted to * WrappedMessage instance * @returns WrappedMessage instance from the json * string provided */ function ConvertJsonToMessage(rawJson) { try { const message = _utilities_1.TransformerUtil.transform(JSON.parse(rawJson), _entities_1.WrappedMessage); return message; } catch (err) { throw new _entities_1.ConversionError(_entities_1.WrappedMessage.name, err); } } /** * Class that represent message consumption process * and handle them with all the configured desired * handlers for entities types and process them with * the entityHandler call-back function for the * entityConstructor class type entity type and process * them with the entityHandler call-back function for * the entityConstructor class type entity type and * check message consumption latency and log warning * if it exceeds the threshold value in seconds or log * info if it's within the threshold value in seconds */ class MessageConsumer { constructor(logger) { this.logger = logger; this.bodyHandlers = new Map(); } /** * Handle basic message consumption process and handle * them with all the configured desired handlers for * entities types and process them with the entityHandler * call-back function for the entityConstructor class type * entity type and check message consumption latency and * log warning if it exceeds the threshold value in seconds * or log info if it's within the threshold value in seconds * @param messageContent message content to be consumed and * processed by the configured entity handlers for the entity * type and entity handler call-back function for the entity * constructor class type entity type * @param messageMqTimestamp message timestamp in milliseconds * to calculate the message consumption latency in seconds * @param consumptionLatencyThreshold consumption latency * threshold in seconds to check if the message consumption * latency exceeds the threshold value in seconds or not * @returns void */ async handleBasicMessage(messageContent, { messageMqTimestamp, consumptionLatencyThreshold }) { try { if (this.bodyHandlers.size == 0) { this.logger?.warn('there is no configured entities handler, please config at least one'); return; } const rawMessage = messageContent.toString(); const { header, body } = ConvertJsonToMessage(rawMessage); if ((0, lodash_1.isNil)(messageMqTimestamp)) { this.logger?.warn('message property timestamp_in_ms was not provided by message broker'); } else { header.messageBrokerTimestamp = messageMqTimestamp; } if ((0, lodash_1.isNil)(header)) { this.logger?.warn('invalid message format'); return; } const { type: entityType, msgGuid } = header; const bodyHandler = this.bodyHandlers.get(entityType); if (!(0, lodash_1.isNil)(bodyHandler)) { await bodyHandler.processAsync({ header, body }); this.checkConsumptionLatency({ messageMqTimestamp, consumptionLatencyThreshold, msgGuid, }); } else { const missedEntityType = _entities_1.knownEntityKeys.get(entityType); if (!(0, lodash_1.isNil)(missedEntityType)) { this.logger?.warn(`entity handler for ${missedEntityType} is not configured`); } else { this.logger?.warn(`received unknown entity type ${entityType}`); } return; } } catch (err) { if (err instanceof _entities_1.ConversionError) { this.logger?.warn(`Failed to deserialise message: ${err}`); return; } this.logger?.error(`Error handling message consumption, error: ${err}`); throw err; } } /** * Check message consumption latency and log warning if it * exceeds the threshold value in seconds or log info if * it's within the threshold value in seconds. If message or * threshold is missing, log warning message with the message * guid provided in the input object parameter and return void * @param messageMqTimestamp message timestamp in milliseconds * to calculate the message consumption latency in seconds * @param consumptionLatencyThreshold consumption latency * threshold in seconds to check if the message consumption * latency exceeds the threshold value in seconds or not * @param msgGuid message guid to be logged in the warning * message if the message or threshold is missing * @returns void */ checkConsumptionLatency({ messageMqTimestamp, consumptionLatencyThreshold: thresholdInSeconds, msgGuid, }) { if ((0, lodash_1.isNil)(messageMqTimestamp) || (0, lodash_1.isNil)(thresholdInSeconds)) { this.logger.warn('Unable to check message consumption delay: missing message timestamp or threshold', { msgGuid }); } else { const consumptionTimestamp = Date.now(); const delayInSeconds = (consumptionTimestamp - messageMqTimestamp) / 1000; if (delayInSeconds > thresholdInSeconds) { this.logger.warn('Message consumption delay exceeded threshold', { delayInSeconds, thresholdInSeconds, messageMqTimestamp, consumptionTimestamp, msgGuid, }); } else { this.logger.info('Message consumed within threshold', { delayInSeconds, thresholdInSeconds, msgGuid, }); } } } /** * Register new entity handler for specific entity type * @param entityHandler entity handler instance that implement * IEntityHandler interface * @param entityConstructor entity constructor that extends * BaseEntity class and has entityKey property in its prototype * @throws Error if entityConstructor is not a trade360 entity * or if there is an error setting registration for new entity * handler * @returns void */ RegisterEntityHandler(entityHandler, entityConstructor) { try { const { name, prototype: { entityKey }, } = entityConstructor; if (!entityKey) { throw new Error(`${name} isn't trade360 entity. You should use only entities from Trade360SDK!`); } const newBodyHandler = new handler_1.BodyHandler(entityHandler, entityConstructor, this.logger); this.bodyHandlers.set(entityKey, newBodyHandler); } catch (err) { this.logger?.error(`Error setting registration for new entity handler, error: ${err}`); throw err; } } } exports.MessageConsumer = MessageConsumer; //# sourceMappingURL=message-consumer.js.map