UNPKG

vulcain-corejs

Version:
138 lines (136 loc) 5.21 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments)).next()); }); }; const amqp = require("amqplib"); const system_1 = require("./../configurations/globals/system"); class RabbitAdapter { constructor(address) { this.address = address; this.domainHandlers = new Map(); this.initialized = false; if (!this.address) throw new Error("Address is required for RabbitAdapter"); if (!address.startsWith("amqp://")) this.address = "amqp://" + address; this.address += "/" + system_1.System.environment; } startAsync() { let self = this; return new Promise((resolve, reject) => { if (self.initialized) { return resolve(self); } // TODO connection error self.initialized = true; system_1.System.log.info(null, "Open rabbitmq connexion on " + system_1.System.removePasswordFromUrl(this.address)); // TODO remove password amqp.connect(this.address).then((conn) => { conn.createChannel().then((ch) => { self.channel = ch; resolve(self); }); }) .catch(err => { system_1.System.log.error(null, err, "Unable to open rabbit connexion"); resolve(self); }); }); } /** * Send domain event (event raises by an action) * Domain events are shared by all services of any domains * * @param {string} domain * @param {EventData} event * * @memberOf RabbitAdapter */ sendEvent(domain, event) { if (!this.channel) return; domain = domain.toLowerCase() + "_events"; this.channel.assertExchange(domain, 'fanout', { durable: false }); this.channel.publish(domain, '', new Buffer(JSON.stringify(event))); } /** * Listening for domain events * * @param {string} domain * @param {Function} handler * * @memberOf RabbitAdapter */ consumeEvents(domain, handler) { if (!this.channel) return; let self = this; // Since this method can be called many times for a same domain // all handlers are aggragated on only one binding domain = domain.toLowerCase() + "_events"; let handlers = this.domainHandlers.get[domain]; if (handlers) { handlers.push(handler); return; } // First time for this domain, create the binding handlers = [handler]; this.domainHandlers.set(domain, handlers); this.channel.assertExchange(domain, 'fanout', { durable: false }); this.channel.assertQueue('', { exclusive: true }).then(queue => { self.channel.bindQueue(queue.queue, domain, ''); self.channel.consume(queue.queue, (msg) => __awaiter(this, void 0, void 0, function* () { let obj = JSON.parse(msg.content.toString()); handlers.forEach(h => h(obj)); }), { noAck: true }); }); } /** * Task = asynchronous action * Shared by service instances * * @param {string} domain * @param {string} serviceId * @param {ActionData} command * * @memberOf RabbitAdapter */ publishTask(domain, serviceId, command) { if (!this.channel) return; domain = domain.toLowerCase(); this.channel.assertExchange(domain, 'direct', { durable: false }); this.channel.publish(domain, serviceId, new Buffer(JSON.stringify(command)), { persistent: true }); } /** * Listening for asynchronous task * * @param {string} domain * @param {string} serviceId * @param {Function} handler * * @memberOf RabbitAdapter */ consumeTask(domain, serviceId, handler) { if (!this.channel) return; let self = this; domain = domain.toLowerCase(); this.channel.assertExchange(domain, 'direct', { durable: false }); this.channel.assertQueue(domain, { durable: true }).then(queue => { // Channel name = serviceId self.channel.bindQueue(queue.queue, domain, serviceId); self.channel.prefetch(1); self.channel.consume(queue.queue, (msg) => __awaiter(this, void 0, void 0, function* () { yield handler(JSON.parse(msg.content.toString())); self.channel.ack(msg); }), { noAck: false }); }); } } exports.RabbitAdapter = RabbitAdapter; //# sourceMappingURL=rabbitAdapter.js.map