@coolgk/utils
Version:
javascript, typescript utility and wrapper functions and classes: array, string, base64, ampq, bcrypt, cache, captcha, csv, email, jwt, number, pdf, tmp, token, unit conversion, url params, session, form data, google sign in, facebook sign in
123 lines (121 loc) • 5.57 kB
JavaScript
/*!
* @package @coolgk/utils
* @version 3.1.4
* @link https://github.com/coolgk/node-utils
* @license MIT
* @author Daniel Gong <daniel.k.gong@gmail.com>
*
* Copyright (c) 2017 Daniel Gong <daniel.k.gong@gmail.com>. All rights reserved.
* Licensed under the MIT License.
*/
;
/*!
* Copyright (c) 2017 Daniel Gong <daniel.k.gong@gmail.com>. All rights reserved.
* Licensed under the MIT License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const amqplib_1 = require("amqplib");
const uuid_1 = require("uuid");
const fs_1 = require("fs");
const array_1 = require("@coolgk/array");
class Amqp {
constructor(options) {
this._url = options.url;
this._sslPem = options.sslPem || '';
this._sslCa = options.sslCa || '';
this._sslPass = options.sslPass || '';
this._connect = options.connect || amqplib_1.connect;
this._uuid = options.uuid || uuid_1.v1;
}
closeConnection() {
this._connection && this._connection.close();
}
publish(message, callback, { routes = '#', exchangeName = 'defaultExchange' } = {}) {
return this.getChannel().then((channel) => {
if (callback) {
const messageId = this._uuid();
return channel.assertQueue('response' + messageId, { durable: false, autoDelete: true }).then((queue) => {
channel.consume(queue.queue, (rawResponseMessage) => {
if (rawResponseMessage && rawResponseMessage.properties.correlationId === messageId) {
callback({
rawResponseMessage,
responseMessage: JSON.parse(rawResponseMessage.content.toString())
});
channel.ack(rawResponseMessage);
}
});
return this._publish(channel, exchangeName, routes, message, {
persistent: true,
correlationId: messageId,
replyTo: queue.queue
});
});
}
return this._publish(channel, exchangeName, routes, message, {
persistent: true
});
});
}
consume(callback, { routes = ['#'], queueName = '', exchangeName = 'defaultExchange', exchangeType = 'topic', priority = 0, prefetch = 1, fallbackExchange = '' } = {}) {
return this.getChannel().then((channel) => {
return channel.prefetch(prefetch).then(() => {
return channel.assertExchange(exchangeName, exchangeType, {
durable: false,
arguments: fallbackExchange ? { 'alternate-exchange': fallbackExchange } : {}
});
}).then(() => {
return channel.assertQueue(queueName, { durable: false, exclusive: !queueName });
}).then((queue) => {
const promises = [];
for (const route of array_1.toArray(routes)) {
promises.push(channel.bindQueue(queue.queue, exchangeName, String(route)));
}
return Promise.all(promises).then(() => {
return channel.consume(queue.queue, (rawMessage) => {
Promise.resolve(callback({
rawMessage,
message: JSON.parse(rawMessage.content.toString())
})).then((response = '') => {
if (rawMessage
&& rawMessage.properties.replyTo && rawMessage.properties.correlationId) {
channel.sendToQueue(rawMessage.properties.replyTo, Buffer.from(JSON.stringify(response)), {
persistent: true,
correlationId: rawMessage.properties.correlationId
});
}
channel.ack(rawMessage);
});
}, { priority });
});
});
});
}
getChannel() {
if (!this._channel) {
if (this._sslPem) {
return this._channel = new Promise((resolve, reject) => {
fs_1.readFile(this._sslPem, (error, sslPem) => error ? reject(error) : resolve({
key: sslPem,
cert: sslPem,
passphrase: this._sslPass
}));
}).then((options) => new Promise((resolve, reject) => {
fs_1.readFile(this._sslCa, (error, sslCA) => error ? reject(error) : Object.assign({}, options, { ca: [sslCA] }));
})).then((options) => this._connect(this._url, options).then((connection) => (this._connection = connection).createChannel()));
}
else {
return this._channel = this._connect(this._url).then((connection) => (this._connection = connection).createChannel());
}
}
return this._channel;
}
_publish(channel, exchangeName, routes, message, options) {
const promises = [];
for (const route of array_1.toArray(routes)) {
promises.push(channel.publish(exchangeName, String(route), Buffer.from(JSON.stringify(message)), options));
}
return Promise.all(promises);
}
}
exports.Amqp = Amqp;
exports.default = Amqp;