UNPKG

@haku-sci/utils

Version:

utils from haku-sci. Library only

120 lines 5.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RabbitMqService = void 0; exports.HakuSubscribe = HakuSubscribe; const nestjs_rabbitmq_1 = require("@golevelup/nestjs-rabbitmq"); const rabbitMQutils = require("./constants"); const utils = require("../utils"); const axios_1 = require("axios"); const rabbitMqApiAuth = { username: process.env.RABBITMQ_USERNAME, password: process.env.RABBITMQ_PASSWORD, }; class RabbitMqService { static async get() { if (!this.instance) { this.instance = new RabbitMqService(); await this.instance.init(); } return this.instance; } constructor() { this.waitAckownledge = {}; this.ackAttached = false; } async init() { this.microServiceName = await utils.microServiceName(); this.amqpConnection = new nestjs_rabbitmq_1.AmqpConnection({ exchanges: [ { name: rabbitMQutils.HAKU_SCI_EXCHANGE, type: 'topic', } ], uri: process.env.RABBITMQ_URL, }); await this.amqpConnection.init(); } get ackQueueName() { return `${this.microServiceName}_${rabbitMQutils.ACK_QUEUE}`; } async dispatchMessage(messagePattern, userId, id, payload = {}, requireAck = false) { const options = { headers: { userId: userId, id: id }, correlationId: null }; let p; if (requireAck) { if (!this.ackAttached) { this.ackAttached = true; await this.amqpConnection.channel.assertQueue(this.ackQueueName, { durable: true }); this.amqpConnection.channel.consume(this.ackQueueName, async (message) => { const ackMessage = JSON.parse(message.content.toString()); this.handleAckResponse(ackMessage); this.amqpConnection.channel.ack(message); }); } options.headers["replyTo"] = this.ackQueueName; options.correlationId = Date.now().toString(); const response = await axios_1.default.get(`${process.env.RABBITMQ_API_URL}/bindings`, { auth: rabbitMqApiAuth }); let countExpectedAcknowledged = response.data.filter((binding) => binding.source === rabbitMQutils.HAKU_SCI_EXCHANGE && binding.routing_key === messagePattern).length; p = new Promise((resolve, reject) => { this.waitAckownledge[options.correlationId] = { count: countExpectedAcknowledged, responses: {}, resolve, reject }; }); } await this.amqpConnection.publish(rabbitMQutils.HAKU_SCI_EXCHANGE, messagePattern, payload, options); return p || Promise.resolve({}); } handleAckResponse(ackMessage) { const { correlationId, microServiceName, response, error } = ackMessage; if (!this.waitAckownledge[correlationId]) return; if (error) { this.waitAckownledge[correlationId].reject(error); delete this.waitAckownledge[correlationId]; } this.waitAckownledge[correlationId].responses[microServiceName] = response; this.waitAckownledge[correlationId].count--; if (this.waitAckownledge[correlationId].count === 0) { this.waitAckownledge[correlationId].resolve(this.waitAckownledge[correlationId].responses); delete this.waitAckownledge[correlationId]; } } sendAck(message) { this.amqpConnection.publish('', message.properties.headers.replyTo, message); } } exports.RabbitMqService = RabbitMqService; function HakuSubscribe(options) { return function (target, key, descriptor) { const originalMethod = descriptor.value; descriptor.value = async function (...args) { const message = args[1]; try { message.response = await originalMethod.apply(this, args); message.properties.headers["microService"] = await utils.microServiceName(); } catch (error) { message.properties.headers["error"] = error; } finally { if (message.properties.headers.replyTo) { try { await RabbitMqService.get().then((rabbitMqService) => { rabbitMqService.sendAck(message); }); } catch (e) { console.log(e); } } ; } }; utils.microServiceName().then((microServiceName) => { (0, nestjs_rabbitmq_1.RabbitSubscribe)({ routingKey: options.routingKey, exchange: rabbitMQutils.HAKU_SCI_EXCHANGE, queue: microServiceName, })(target, key, descriptor); }); }; } //# sourceMappingURL=_rabbit-mq.service.js.map