UNPKG

regard

Version:

Sugar-interface to access multiple data sources.

141 lines (110 loc) 3.23 kB
var _ = require('lodash'), Amqp = require('amqplib'), Connector = require('../connector'); exports = module.exports = RabbitmqConnector; var Methods = exports.Methods = [ 'consume', 'produce' ]; var KEY = exports.KEY = Connector.generateKey(__filename); var SETTINGS = exports.SETTINGS = { method: 'consume' }; var brokers = {}; function RabbitmqConnector() { if (!(this instanceof RabbitmqConnector)) { return new RabbitmqConnector(); } Connector.call(this, KEY, SETTINGS); bindHandlers(this); } RabbitmqConnector.prototype = _.create(Connector.prototype); RabbitmqConnector.prototype.checkPath = canAcceptPath; RabbitmqConnector.prototype.checkMethod = canAcceptMethod; RabbitmqConnector.prototype.onCreateEndpoint = createClient; function bindHandlers($this) { $this.handler(Connector.DEFAULT_HANDLER, handleRequest, beforeRequest); _.forEach(Methods, function bindHandler(method) { $this.handler(method, handleRequest, function beforeHandler(request) { return _.partial(beforeRequest, request, method).apply($this, _.slice(arguments, 1)); }); }); } function canAcceptPath(path) { return _.startsWith(path, 'amqp://'); } function canAcceptMethod(method) { return _.isString(method) && _.includes(Methods, method); } function createClient(endpoint) { var uri = endpoint.path, opts = endpoint.context; if (endpoint.root) { brokers[endpoint.name] = Amqp.connect(uri); } else { endpoint.context.queue = queueNameFromUri(uri); brokers[endpoint.name] = brokers[endpoint.parent.name]; } } function beforeRequest(request) { var args = _.cloneDeep(_.slice(arguments, 1)), method = args.shift(), queue; if (_.isString(method) && !canAcceptMethod(method)) { queue = method; method = undefined; } else { if (_.isString(args[0])) { queue = args.shift(); } } if (!_.isUndefined(method)) { request.context.method = method; request.handler = method; } if (_.isString(queue) && !_.isEmpty(queue)) { request.context.queue = queue; } request.args = args; return request; } function queueNameFromUri(uri) { return _(uri).split('/').pop(); } function handleRequest(request, resolve, reject) { var broker = brokers[request.endpoint.name], queue = request.context.queue, method = request.handler, args = request.args, processing; broker .then(function (conn) { return conn.createChannel(); }) .then(function (ch) { var ok = ch.assertQueue(queue, request.context.options); if (method === 'produce') { var msg = args.shift(); if (_.isPlainObject(msg)) { msg = JSON.stringify(msg); } var result = ch.sendToQueue(queue, new Buffer(msg.toString())); resolve(result); } else { ok.then(function () { var cb = args.shift(); return ch.consume(queue, function (msg) { if (_.isFunction(cb)) { cb(msg); } if (msg === null) { reject(); } else { resolve(msg); ch.ack(msg); } }) }); } }) .catch(reject); }