UNPKG

domotz-remote-pawn

Version:

Domotz Agent

121 lines (112 loc) 4.92 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 Domotz Ltd * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. * * Created by Iacopo Papalini <iacopo@domotz.com> on 17/09/15. * * Process Messages incoming from the RabbitMQ command queue, instantiating the right class and calling the `execute` * method. * * If the message contains the `reply-to` property, a reply message is sent back, containing the result of the `execute` * call. By default it is JSON-encoded but other content types are supported * */ var factory = function (resourceLocator) { var myConsole = resourceLocator.log.decorateLogs(); function parse(message) { var command = message.command; var tokens = command.toLowerCase().split('_'); command = tokens.shift(); for (var i = 0; i < tokens.length; i++) { command += tokens[i].charAt(0).toUpperCase() + tokens[i].slice(1); } myConsole.verbose('Parsed command: %s', command); return command; } function createCommandFromMessage(message) { var command = parse(message); if (command.indexOf('ssh') !== -1) { command = 'ssh/' + command; } if (!resourceLocator.settingsManager.isCommandHandlerEnabled(command)) { myConsole.warn('(%s) command disabled from settings', command); return null; } var commandModule = require('../commands/' + command + '.js'); return commandModule.command(message, resourceLocator); } function callback(payload, options) { if (options === undefined) { options = {}; } if (payload === undefined || payload === null) { myConsole.debug('Sending empty message as ack'); return new Buffer(JSON.stringify({})); } if (payload instanceof Object && !options.asBinary) { return new Buffer(JSON.stringify(payload)); } myConsole.debug('handling returned payload as binary - no transformation'); return new Buffer(payload, 'binary'); } function processMessage(channel, exchange, amqpMessage) { var message, cid, replyTo; var command; if (!amqpMessage) { throw new Error('MESSAGE - Received an empty message'); } message = JSON.parse(amqpMessage.content.toString()); cid = amqpMessage.properties.correlationId; replyTo = amqpMessage.properties.replyTo; myConsole.debug('MESSAGE - (%s): Received', cid); message.correlationId = cid; myConsole.debug('MESSAGE row ' + JSON.stringify(message)); command = createCommandFromMessage(message); if (command === null) { var buffer = callback({ error: 'COMMAND_DISABLED_BY_SETTINGS' }, {}); var properties = { correlationId: cid }; channel.publish(exchange, replyTo, buffer, properties); return; } myConsole.info('MESSAGE - (%s): %s', cid, command.describe()); command.execute(buildExecutionResponseHandler(cid, replyTo, channel, exchange)); } function buildExecutionResponseHandler(cid, replyTo, channel, exchange) { return function (payload, error, options) { if (replyTo === null || replyTo === undefined) { myConsole.info('MESSAGE - (%s): without reply-to - not sending reply', cid); return; } var buffer = callback(payload, options); // TODO Handler error myConsole.info('MESSAGE - (%s): Sending reply on queue %s - size in bytes: %d', cid, replyTo, buffer.length); var properties = { correlationId: cid }; if (options && options.asBinary) { myConsole.info('MESSAGE - (%s): content-type: %s', cid, options['content-type']); properties.contentType = options['content-type']; } channel.publish(exchange, replyTo, buffer, properties); }; } return { processMessage: processMessage, // For testing _createCommandFromMessage: createCommandFromMessage, _callback: callback, _parse: parse, _buildExecutionResponseHandler: buildExecutionResponseHandler, }; }; module.exports.factory = factory;