UNPKG

iotagent-node-lib

Version:

IoT Agent library to interface with NGSI Context Broker

207 lines (184 loc) 7.17 kB
/* * Copyright 2014 Telefonica Investigación y Desarrollo, S.A.U * * This file is part of fiware-iotagent-lib * * fiware-iotagent-lib is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * fiware-iotagent-lib 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with fiware-iotagent-lib. * If not, see http://www.gnu.org/licenses/. * * For those usages not covered by the GNU Affero General Public License * please contact with::[contacto@tid.es] */ /* eslint-disable no-unused-vars */ const async = require('async'); const errors = require('../../errors'); const logger = require('logops'); const intoTrans = require('../common/domain').intoTrans; const context = { op: 'IoTAgentNGSI.NGSIUtils' }; const _ = require('underscore'); const config = require('../../commonConfig'); const updateMiddleware = []; const queryMiddleware = []; /** * @param {String/Array} value Comma separated list or array of values * @return {Array} Array of Lat/Lngs for use as GeoJSON */ function splitLngLat(value) { const lngLats = typeof value === 'string' || value instanceof String ? value.split(',') : value; lngLats.forEach((element, index, lngLats) => { if (Array.isArray(element)) { lngLats[index] = splitLngLat(element); } else if ((typeof element === 'string' || element instanceof String) && element.includes(',')) { lngLats[index] = splitLngLat(element); } else { lngLats[index] = Number.parseFloat(element); } }); return lngLats; } /** * @param {String} type GeoJSON * @param {String} value Value to be analyzed * @return {Array} split pairs of GeoJSON coordinates */ function getLngLats(type, value) { if (typeof value !== 'string' && Array.isArray(value) === false) { return value; } const lngLats = _.flatten(splitLngLat(value)); if (lngLats.length === 2) { return { type, coordinates: lngLats }; } if (lngLats.length % 2 !== 0) { logger.error(context, 'Bad attribute value type. Expecting geo-coordinates. Received:%s', value); throw Error(); } const arr = []; for (let i = 0, len = lngLats.length; i < len; i = i + 2) { arr.push([lngLats[i], lngLats[i + 1]]); } return { type, coordinates: arr }; } /** * Determines if a value is of type float * * @param {String} value Value to be analyzed * @return {boolean} True if float, False otherwise. */ function isFloat(value) { return !isNaN(value) && value.toString().indexOf('.') !== -1; } /** * Create the request object used to communicate with the Context Broker, adding security and service information. * * @param {String} url Path for the Context Broker operation. * @param {Object} typeInformation Object containing information about the device: service, security, etc. * @param {String} token If present, security information needed to access the CB. * @return {Object} Containing all the information of the request but the payload.c */ function createRequestObject(url, typeInformation, token) { let cbHost = config.getConfig().contextBroker.url; const serviceContext = {}; const headers = { 'fiware-service': config.getConfig().service, 'fiware-servicepath': config.getConfig().subservice }; if (config.getConfig().authentication && config.getConfig().authentication.enabled) { headers[config.getConfig().authentication.header] = token; } logger.debug(context, 'typeInformation %j', typeInformation); if (typeInformation) { if (typeInformation.service) { headers['fiware-service'] = typeInformation.service; serviceContext.service = typeInformation.service; } if (typeInformation.subservice) { headers['fiware-servicepath'] = typeInformation.subservice; serviceContext.subservice = typeInformation.subservice; } if (typeInformation.cbHost && typeInformation.cbHost.indexOf('://') !== -1) { cbHost = typeInformation.cbHost; } else if (typeInformation.cbHost && typeInformation.cbHost.indexOf('://') === -1) { cbHost = 'http://' + typeInformation.cbHost; } } if (config.checkNgsiLD(typeInformation)) { headers['Content-Type'] = 'application/ld+json'; headers['NGSILD-Tenant'] = headers['fiware-service']; headers['NGSILD-Path'] = headers['fiware-servicepath']; } const options = { url: cbHost + url, method: 'POST', headers }; return intoTrans(serviceContext, function () { return options; })(); } function applyMiddlewares(middlewareCollection, entity, typeInformation, callback) { function emptyMiddleware(callback) { callback(null, entity, typeInformation); } function endMiddleware(entity, typeInformation, callback) { callback(null, entity); } if (middlewareCollection && middlewareCollection.length > 0) { const middlewareList = _.clone(middlewareCollection); middlewareList.unshift(emptyMiddleware); middlewareList.push(endMiddleware); async.waterfall(middlewareList, callback); } else { callback(null, entity); } } function getMetaData(typeInformation, name, metadata) { if (metadata) { return metadata; } let i; if (typeInformation.active) { for (i = 0; i < typeInformation.active.length; i++) { /* jshint camelcase: false */ if (name === typeInformation.active[i].object_id) { return typeInformation.active[i].metadata; } } } if (typeInformation.lazy) { for (i = 0; i < typeInformation.lazy.length; i++) { /* jshint camelcase: false */ if (name === typeInformation.lazy[i].object_id) { return typeInformation.lazy[i].metadata; } } } if (typeInformation.staticAttributes) { for (i = 0; i < typeInformation.staticAttributes.length; i++) { if (name === typeInformation.staticAttributes[i].name) { return typeInformation.staticAttributes[i].metadata; } } } return undefined; } exports.createRequestObject = createRequestObject; exports.applyMiddlewares = applyMiddlewares; exports.getMetaData = getMetaData; exports.getLngLats = getLngLats; exports.isFloat = isFloat; exports.updateMiddleware = updateMiddleware; exports.queryMiddleware = queryMiddleware;