UNPKG

domotz-remote-pawn

Version:

Domotz Agent

187 lines (164 loc) 6.84 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 <ipapalini@domotz.com> on 16/09/15. */ const COORDINATE_REGEXP = new RegExp('^([-+]?[0-9]+(\.[0-9]+)?)([NSWE])?$'); const CACHE_SCOPE = 'ndt-servers'; var factory = function (q, cacheUtils, configuration, request, random, distanceCalculator, resetCache) { resetCache = typeof resetCache !== 'undefined' ? resetCache : true; if (resetCache) { console.info("NDT - Resetting cache, scope = " + CACHE_SCOPE); cacheUtils.createCache(CACHE_SCOPE).reset(); } function parseServers(serversList) { var servers = []; serversList.forEach(function (item) { try { var server = fromAPIItem(item); servers.push(server); } catch (exception) { console.warn("NDT - Cannot parse NDT server item: " + JSON.stringify(item)); } }); servers.sort(function (a, b) { return a.location.distance - b.location.distance; }); return servers; } function handleError(err, response, body) { if (err) { console.error("NDT - Cannot fetch servers list: " + JSON.stringify(err)); throw err; } if (response.statusCode !== 200) { const error = {message: body, code: response.statusCode}; console.error("NDT - Cannot fetch servers list: " + JSON.stringify(error)); throw error; } } var fetch = function () { var cache = cacheUtils.createCache(CACHE_SCOPE); const CACHE_KEY = 'fetch'; var deferred = q.defer(); cache.get(CACHE_KEY, function () { var queryUrl = configuration.external_scripts.ndt.servers_query_url; console.info("NDT - Fetching NDT Server list from: " + queryUrl); request.get({uri: queryUrl}, function (err, response, body) { console.info("NDT - Server list response arrived"); try { handleError(err, response, body); var rawData = JSON.parse(body); console.log('2ciao'); const servers = parseServers(rawData); console.log(servers) deferred.resolve(servers); cache.set(CACHE_KEY, servers); } catch (err) { return deferred.reject(err); } }); }, function (servers) { deferred.resolve(servers); }); return deferred.promise; }; var findById = function (serverId) { var deferred = q.defer(); fetch().then(function (servers) { servers.every(function (server) { if (server.id === serverId) { deferred.resolve(server); return false; } return true; }); console.warn("NDT - No server found"); deferred.reject({status: 404, message: 'NOT FOUND'}); }); return deferred.promise; }; var findNearestResponding = function (servers, timeout, maxAttempts) { var deferred = q.defer(); var commonUrl = "http://%s:7123"; servers = servers.slice(0, maxAttempts); var testServer = function () { if (servers.length === 0) { const message = "No responsive server found"; console.error(message); return deferred.reject({message: message, status: 404}); } var server = servers.shift(); var hostname = server.service.hostname; console.info("NDT - Connecting to server %s with timeout of %ss ", hostname, timeout); request.get({timeout: timeout * 1000, uri: require('util').format(commonUrl, hostname)}, function (error, response, body) { if (!error && response.statusCode === 200) { return deferred.resolve(server); } return testServer(); }); }; testServer(); return deferred.promise; }; var fromAPIItem = function fromAPIItem(item) { if (!item['service-hostname']) { console.error("Replacing hostname with ip address for host:" + item['service-locator'][0]); try { item['service-hostname'] = item['service-locator'][0].split('//')[1].split(':')[0]; } catch (error) { throw error; } } var server = { id: random.md5(JSON.stringify(item)), service: { type: item['service-type'][0], locator: item['service-locator'], host: item['service-host'][0], hostname: item['service-hostname'] }, location: { siteName: item['location-sitename'] ? item['location-sitename'][0] : null, latitude: NaN, longitude: NaN, state: item["location-state"] ? item["location-state"][0] : null, zipcode: item["location-code"] ? item["location-code"][0] : null } }; if (item["location-latitude"] && COORDINATE_REGEXP.test(item["location-latitude"]) && item["location-longitude"] && COORDINATE_REGEXP.test(item["location-longitude"]) ) { server.location.latitude = parseFloat([item["location-latitude"][0].match(COORDINATE_REGEXP)[1]][0]); server.location.longitude = parseFloat([item["location-longitude"][0].match(COORDINATE_REGEXP)[1]][0]); } server.location.distance = distanceCalculator.distanceTo(server.location.latitude, server.location.longitude); return server; } return { fetch: fetch, findNearestResponding: findNearestResponding, findById: findById, fromAPIItem: fromAPIItem }; }; module.exports.factory = factory;