UNPKG

domotz-remote-pawn

Version:

Domotz Agent

136 lines (114 loc) 5.24 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/>. * * * This module has the responsibility to send the discovered IP devices to the engine, choosing between a full or * a delta report following an internal logic * * Created by Iacopo Papalini <iacopo@domotz.com> on 19/05/16. */ var engineIpDiscoveryReportStrategyFactory = function (q, engineRequest, interfacesBindingStorage, configuration) { "use strict"; var discovery = configuration.discovery; var fullDiscoveryPeriod = (discovery && discovery.refresh) ? discovery.refresh : 30; return function () { var counter = 0; var ret = { reportDiscovery: function () { var seq = getNextSequenceNumber(); var payload = (seq !== 0) ? ret.createDeltaPayload() : ret.createFullPayload(); console.debug("Sending IP Network device discovery report " + "to engine. Sequence number: " + seq); console.verbose(JSON.stringify(payload, null, 2)); var deferred = q.defer(); if (isToSend(payload, seq)) { engineRequest.send('/device/ip?seq=' + seq, 'PUT', payload, function () { console.verbose("Report successfully sent to " + "engine. Sequence number: " + seq); return deferred.resolve(); }, function (err) { console.warn("Error reporting IP network devices " + "to engine. Sequence number: " + seq + " - Rolling back sequence number"); counter --; return deferred.reject(err); }); } else { console.debug("No changes in IP network - no report will " + "be sent to the agent"); deferred.resolve(); } function isToSend(payload, seq){ return seq === 0 || isNotEmpty(payload) ; } function isNotEmpty(payload){ // http://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object return (!( Object.keys(payload).length === 0 && payload.constructor === Object )); } return deferred.promise; }, createFullPayload: function () { return bindingListToDictionary(interfacesBindingStorage.listFresh()); }, createDeltaPayload: function () { var payload = {}; var fresh = bindingListToDictionary(interfacesBindingStorage.listFresh()); var add_stale_info = function (stale) { var mac = stale.mac; if (fresh[mac]) { if (payload[mac] === undefined) { payload[mac] = []; } payload[mac] = payload[mac].concat(fresh[mac]); } if (payload[mac] !== undefined) { return; } payload[mac] = null; }; var add_new_info = function (new_one) { var mac = new_one.mac; // new device is always fresh - add it with all the fresh IP addresses payload[mac] = fresh[mac]; }; interfacesBindingStorage.listStale().forEach(add_stale_info); interfacesBindingStorage.listNew().forEach(add_new_info); return payload; } }; function getNextSequenceNumber() { var ret = (counter % fullDiscoveryPeriod) ? counter : 0; counter++; return ret; } function bindingListToDictionary(list) { var ret = {}; list.forEach(function (binding) { if (ret[binding.mac] === undefined) { ret[binding.mac] = []; } ret[binding.mac].push({ip: binding.ip, host_name: binding.hostname}); }); return ret; } return ret; }(); }; module.exports.engineIpDiscoveryReportStrategyFactory = engineIpDiscoveryReportStrategyFactory;