From a2ac2b0773a4f35177e1479f951c516c913d92b4 Mon Sep 17 00:00:00 2001 From: KeshavSoni2511 Date: Fri, 16 Feb 2024 08:24:55 +0000 Subject: [PATCH 01/23] Fix for 1515 --- CHANGES_NEXT_RELEASE | 3 ++- lib/services/ngsi/ngsiService.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 8974767ef..706a56170 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1 +1,2 @@ -- Fix: store device subscriptions updates (#1086) \ No newline at end of file +- Fix: typeInformation contain global config values (#1515) +- Fix: store device subscriptions updates (#1086) diff --git a/lib/services/ngsi/ngsiService.js b/lib/services/ngsi/ngsiService.js index aea6ef802..e1b9286c5 100644 --- a/lib/services/ngsi/ngsiService.js +++ b/lib/services/ngsi/ngsiService.js @@ -144,9 +144,9 @@ function executeWithDeviceInformation(operationFunction) { // For preregistered devices, augment the existing deviceInformation with selected attributes. if (!callback) { callback = deviceInformation; - typeInformation = deviceGroup || configDeviceInfo; + typeInformation = deviceGroup || { ...config.getConfig(), ...configDeviceInfo }; } else { - typeInformation = deviceInformation; + typeInformation = { ...config.getConfig(), ...deviceInformation }; attributeList.forEach((key) => { typeInformation[key] = typeInformation[key] || (deviceGroup || {})[key] || (configDeviceInfo || {})[key]; From 353853cc1f29a9941393755cb2180a1930618161 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Wed, 21 Feb 2024 15:56:26 +0100 Subject: [PATCH 02/23] add TypeInformation to error log about EntityGenericError and BadTimestamp --- lib/errors.js | 20 +++++++++++++++---- lib/services/devices/devices-NGSI-LD.js | 2 +- lib/services/devices/devices-NGSI-v2.js | 8 +++++++- lib/services/ngsi/entities-NGSI-LD.js | 22 ++++++++++++++++++--- lib/services/ngsi/entities-NGSI-v2.js | 24 ++++++++++++++++++++--- lib/services/ngsi/subscription-NGSI-LD.js | 2 ++ lib/services/ngsi/subscription-NGSI-v2.js | 2 ++ 7 files changed, 68 insertions(+), 12 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index 6eb23e5e7..5bfcce7a2 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -36,9 +36,15 @@ class UnregistrationError { } } class EntityGenericError { - constructor(id, type, details, code) { + constructor(id, type, typeInformation, details, code) { this.name = 'ENTITY_GENERIC_ERROR'; - this.message = 'Error accesing entity data for device: ' + id + ' of type: ' + type; + this.message = + 'Error accesing entity data for device: ' + + id + + ' of type: ' + + type + + ' and ' + + JSON.stringify(typeInformation); this.details = details || {}; this.code = code || 200; } @@ -229,9 +235,15 @@ class BadAnswer { } } class BadTimestamp { - constructor(payload, entityName) { + constructor(payload, entityName, typeInformation) { this.name = 'BAD_TIMESTAMP'; - this.message = 'Invalid ISO8601 timestamp [' + payload + '] in [' + entityName + ']'; + this.message = + 'Invalid ISO8601 timestamp [' + + payload + + '] in [' + + entityName + + '] with: ' + + JSON.stringify(typeInformation); this.code = 400; } } diff --git a/lib/services/devices/devices-NGSI-LD.js b/lib/services/devices/devices-NGSI-LD.js index 66c6f14c9..54d15f6f0 100644 --- a/lib/services/devices/devices-NGSI-LD.js +++ b/lib/services/devices/devices-NGSI-LD.js @@ -93,7 +93,7 @@ function updateEntityHandlerNgsiLD(deviceData, updatedDevice, callback) { body ); - const errorObj = new errors.EntityGenericError(deviceData.id, deviceData.type, body); + const errorObj = new errors.EntityGenericError(deviceData.id, deviceData.type, deviceData, body); callback(errorObj); } diff --git a/lib/services/devices/devices-NGSI-v2.js b/lib/services/devices/devices-NGSI-v2.js index acddbe083..6c214414f 100644 --- a/lib/services/devices/devices-NGSI-v2.js +++ b/lib/services/devices/devices-NGSI-v2.js @@ -89,7 +89,13 @@ function updateEntityHandlerNgsi2(deviceData, updatedDevice, callback) { body ); - const errorObj = new errors.EntityGenericError(deviceData.id, deviceData.type, body, response.statusCode); + const errorObj = new errors.EntityGenericError( + deviceData.id, + deviceData.type, + deviceData, + body, + response.statusCode + ); callback(errorObj); } diff --git a/lib/services/ngsi/entities-NGSI-LD.js b/lib/services/ngsi/entities-NGSI-LD.js index 79c20a535..2b32bf245 100644 --- a/lib/services/ngsi/entities-NGSI-LD.js +++ b/lib/services/ngsi/entities-NGSI-LD.js @@ -383,7 +383,15 @@ function generateNGSILDOperationHandler(operationName, entityName, typeInformati if (errorField !== undefined) { callback(new errors.DeviceNotFound(entityName)); } else { - callback(new errors.EntityGenericError(entityName, typeInformation.type, body)); + callback( + new errors.EntityGenericError( + entityName, + typeInformation.type, + typeInformation, + body, + response.statusCode + ) + ); } } else { logger.debug(context, 'Unknown error executing ' + operationName + ' operation'); @@ -391,7 +399,15 @@ function generateNGSILDOperationHandler(operationName, entityName, typeInformati body = JSON.parse(body); } - callback(new errors.EntityGenericError(entityName, typeInformation.type, body, response.statusCode)); + callback( + new errors.EntityGenericError( + entityName, + typeInformation.type, + typeInformation, + body, + response.statusCode + ) + ); } }; } @@ -1015,7 +1031,7 @@ function sendUpdateValueNgsiLD(entityName, attributes, typeInformation, token, c } else if (!utils.IsValidTimestampedNgsi2(payload[n])) { // legacy check needed? logger.error(context, 'Invalid timestamp:%s', JSON.stringify(payload[0])); - callback(new errors.BadTimestamp(payload, entityName)); + callback(new errors.BadTimestamp(payload, entityName, typeInformation)); return; } } diff --git a/lib/services/ngsi/entities-NGSI-v2.js b/lib/services/ngsi/entities-NGSI-v2.js index 2238a4ed2..19a93074e 100644 --- a/lib/services/ngsi/entities-NGSI-v2.js +++ b/lib/services/ngsi/entities-NGSI-v2.js @@ -175,7 +175,15 @@ function generateNGSI2OperationHandler(operationName, entityName, typeInformatio if (errorField !== undefined) { callback(new errors.DeviceNotFound(entityName)); } else { - callback(new errors.EntityGenericError(entityName, typeInformation.type, body)); + callback( + new errors.EntityGenericError( + entityName, + typeInformation.type, + typeInformation, + body, + response.statusCode + ) + ); } } else { logger.debug(context, 'Unknown error executing ' + operationName + ' operation'); @@ -183,7 +191,15 @@ function generateNGSI2OperationHandler(operationName, entityName, typeInformatio body = JSON.parse(body); } - callback(new errors.EntityGenericError(entityName, typeInformation.type, body, response.statusCode)); + callback( + new errors.EntityGenericError( + entityName, + typeInformation.type, + typeInformation, + body, + response.statusCode + ) + ); } }; } @@ -317,7 +333,9 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call if (moment(plainMeasures[constants.TIMESTAMP_ATTRIBUTE], moment.ISO_8601, true).isValid()) { timestamp.value = plainMeasures[constants.TIMESTAMP_ATTRIBUTE]; } else { - callback(new errors.BadTimestamp(plainMeasures[constants.TIMESTAMP_ATTRIBUTE], entityName)); + callback( + new errors.BadTimestamp(plainMeasures[constants.TIMESTAMP_ATTRIBUTE], entityName, typeInformation) + ); } } else if (!typeInformation.timezone) { timestamp.value = new Date().toISOString(); diff --git a/lib/services/ngsi/subscription-NGSI-LD.js b/lib/services/ngsi/subscription-NGSI-LD.js index 5ba7f71d1..4eb0f2129 100644 --- a/lib/services/ngsi/subscription-NGSI-LD.js +++ b/lib/services/ngsi/subscription-NGSI-LD.js @@ -62,6 +62,7 @@ function createSubscriptionHandlerNgsiLD(device, triggers, store, callback) { new errors.EntityGenericError( device.name, device.type, + device, { details: body }, @@ -183,6 +184,7 @@ function createUnsubscribeHandlerNgsiLD(device, id, callback) { new errors.EntityGenericError( device.name, device.type, + device, { details: body }, diff --git a/lib/services/ngsi/subscription-NGSI-v2.js b/lib/services/ngsi/subscription-NGSI-v2.js index aa31bede2..ccaf64f0c 100644 --- a/lib/services/ngsi/subscription-NGSI-v2.js +++ b/lib/services/ngsi/subscription-NGSI-v2.js @@ -64,6 +64,7 @@ function createSubscriptionHandlerNgsi2(device, triggers, store, callback) { new errors.EntityGenericError( device.name, device.type, + device, { details: body }, @@ -183,6 +184,7 @@ function createUnsubscribeHandlerNgsi2(device, id, callback) { new errors.EntityGenericError( device.name, device.type, + device, { details: body }, From 93cc2d477b6cc7254157e30582c81f207844faf6 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Wed, 21 Feb 2024 16:22:55 +0100 Subject: [PATCH 03/23] do not check full message --- test/unit/ngsi-ld/ngsiService/active-devices-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/ngsi-ld/ngsiService/active-devices-test.js b/test/unit/ngsi-ld/ngsiService/active-devices-test.js index 151ce0e4b..9c175047e 100644 --- a/test/unit/ngsi-ld/ngsiService/active-devices-test.js +++ b/test/unit/ngsi-ld/ngsiService/active-devices-test.js @@ -600,7 +600,7 @@ describe('NGSI-LD - Active attributes test', function () { should.exist(error.name); error.code.should.equal(207); error.details.notUpdated.should.equal('someEntities'); - error.message.should.equal('Error accesing entity data for device: light1 of type: Light'); + //error.message.should.equal('Error accesing entity data for device: light1 of type: Light'); error.name.should.equal('ENTITY_GENERIC_ERROR'); contextBrokerMock.done(); done(); From ef68669de856f489ea340c160e88578ced65d642 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Wed, 21 Feb 2024 16:28:30 +0100 Subject: [PATCH 04/23] add typeInformation to TypeNotFound error --- lib/errors.js | 5 +++-- lib/services/ngsi/entities-NGSI-LD.js | 4 ++-- lib/services/ngsi/entities-NGSI-v2.js | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index 5bfcce7a2..c1a515e82 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -83,9 +83,10 @@ class UnsupportedContentType { } } class TypeNotFound { - constructor(id, type) { + constructor(id, type, typeInformation) { this.name = 'TYPE_NOT_FOUND'; - this.message = 'Type : ' + type + ' not found for device with id: ' + id; + this.message = + 'Type : ' + type + ' not found for device with id: ' + id + ' with: ' + JSON.stringify(typeInformation); this.code = 500; } } diff --git a/lib/services/ngsi/entities-NGSI-LD.js b/lib/services/ngsi/entities-NGSI-LD.js index 2b32bf245..d46b6d887 100644 --- a/lib/services/ngsi/entities-NGSI-LD.js +++ b/lib/services/ngsi/entities-NGSI-LD.js @@ -432,7 +432,7 @@ function sendQueryValueNgsiLD(entityName, attributes, typeInformation, token, ca options.method = 'GET'; if (!typeInformation || !typeInformation.type) { - callback(new errors.TypeNotFound(null, entityName)); + callback(new errors.TypeNotFound(null, entityName, typeInformation)); return; } @@ -545,7 +545,7 @@ function sendUpdateValueNgsiLD(entityName, attributes, typeInformation, token, c } if (!typeInformation || !typeInformation.type) { - callback(new errors.TypeNotFound(null, entityName)); + callback(new errors.TypeNotFound(null, entityName, typeInformation)); return; } const idTypeSSSList = pluginUtils.getIdTypeServSubServiceFromDevice(typeInformation); diff --git a/lib/services/ngsi/entities-NGSI-v2.js b/lib/services/ngsi/entities-NGSI-v2.js index 19a93074e..aed0fa898 100644 --- a/lib/services/ngsi/entities-NGSI-v2.js +++ b/lib/services/ngsi/entities-NGSI-v2.js @@ -241,7 +241,7 @@ function sendQueryValueNgsi2(entityName, attributes, typeInformation, token, cal options.method = 'GET'; if (!typeInformation || !typeInformation.type) { - callback(new errors.TypeNotFound(null, entityName)); + callback(new errors.TypeNotFound(null, entityName, typeInformation)); return; } @@ -295,7 +295,7 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call //Check mandatory information: type if (!typeInformation || !typeInformation.type) { - callback(new errors.TypeNotFound(null, entityName)); + callback(new errors.TypeNotFound(null, entityName, typeInformation)); return; } //Rename all measures with matches with id and type to measure_id and measure_type From 6fa1196a83c2d3ec79096694ecd9b4dd2178fc6a Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Wed, 21 Feb 2024 16:56:49 +0100 Subject: [PATCH 05/23] add typeInformation to DeviceNotFound error --- lib/errors.js | 4 +- lib/services/devices/deviceRegistryMongoDB.js | 6 +- lib/services/devices/deviceService.js | 4 +- lib/services/devices/devices-NGSI-LD.js | 2 +- lib/services/devices/devices-NGSI-v2.js | 2 +- lib/services/ngsi/entities-NGSI-LD.js | 2 +- lib/services/ngsi/entities-NGSI-v2.js | 2 +- .../northBound/contextServer-NGSI-LD.js | 105 +++++++++--------- .../northBound/contextServer-NGSI-v2.js | 2 +- .../northBound/deviceProvisioningServer.js | 38 ++++++- 10 files changed, 95 insertions(+), 72 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index c1a515e82..4032ee29c 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -97,9 +97,9 @@ class MissingAttributes { } } class DeviceNotFound { - constructor(id) { + constructor(id, typeInformation) { this.name = 'DEVICE_NOT_FOUND'; - this.message = 'No device was found with id:' + id; + this.message = 'No device was found with id:' + id + ' and ' + JSON.stringify(typeInformation); this.code = 404; } } diff --git a/lib/services/devices/deviceRegistryMongoDB.js b/lib/services/devices/deviceRegistryMongoDB.js index f9b161581..510dc8f58 100644 --- a/lib/services/devices/deviceRegistryMongoDB.js +++ b/lib/services/devices/deviceRegistryMongoDB.js @@ -206,7 +206,7 @@ function findOneInMongoDB(queryParams, id, callback) { } else { logger.debug(context, 'Device [%s] not found.', id); - callback(new errors.DeviceNotFound(id)); + callback(new errors.DeviceNotFound(id, queryParams)); } }); } @@ -282,7 +282,7 @@ function getByNameAndType(name, type, service, servicepath, callback) { } else { logger.debug(context, 'Device [%s] not found.', name); - callback(new errors.DeviceNotFound(name)); + callback(new errors.DeviceNotFound(name, optionsQuery)); } }); } @@ -373,7 +373,7 @@ function getDevicesByAttribute(name, value, service, subservice, callback) { } else { logger.debug(context, 'Device [%s] not found.', name); - callback(new errors.DeviceNotFound(name)); + callback(new errors.DeviceNotFound(name, filter)); } }); } diff --git a/lib/services/devices/deviceService.js b/lib/services/devices/deviceService.js index 45c2761b3..66e3255d5 100644 --- a/lib/services/devices/deviceService.js +++ b/lib/services/devices/deviceService.js @@ -646,7 +646,7 @@ function findOrCreate(deviceId, apikey, group, callback) { newDevice, group ); - callback(new errors.DeviceNotFound(deviceId)); + callback(new errors.DeviceNotFound(deviceId, newDevice)); } } else { callback(error); @@ -671,7 +671,7 @@ function retrieveDevice(deviceId, apiKey, callback) { } else { logger.error(context, "Couldn't find device data for APIKey [%s] and DeviceId[%s]", deviceId, apiKey); - callback(new errors.DeviceNotFound(deviceId)); + callback(new errors.DeviceNotFound(deviceId, { apikey: apiKey })); } }); } else { diff --git a/lib/services/devices/devices-NGSI-LD.js b/lib/services/devices/devices-NGSI-LD.js index 54d15f6f0..17e983db8 100644 --- a/lib/services/devices/devices-NGSI-LD.js +++ b/lib/services/devices/devices-NGSI-LD.js @@ -216,7 +216,7 @@ function updateRegisterDeviceNgsiLD(deviceObj, entityInfoUpdated, callback) { callback(null, oldDevice); } else { - callback(new errors.DeviceNotFound(newDevice.id)); + callback(new errors.DeviceNotFound(newDevice.id, newDevice)); } } diff --git a/lib/services/devices/devices-NGSI-v2.js b/lib/services/devices/devices-NGSI-v2.js index 6c214414f..d8a2fe632 100644 --- a/lib/services/devices/devices-NGSI-v2.js +++ b/lib/services/devices/devices-NGSI-v2.js @@ -288,7 +288,7 @@ function updateRegisterDeviceNgsi2(deviceObj, entityInfoUpdated, callback) { callback(null, oldDevice); } else { - callback(new errors.DeviceNotFound(newDevice.id)); + callback(new errors.DeviceNotFound(newDevice.id, newDevice)); } } diff --git a/lib/services/ngsi/entities-NGSI-LD.js b/lib/services/ngsi/entities-NGSI-LD.js index d46b6d887..8691d7ee8 100644 --- a/lib/services/ngsi/entities-NGSI-LD.js +++ b/lib/services/ngsi/entities-NGSI-LD.js @@ -381,7 +381,7 @@ function generateNGSILDOperationHandler(operationName, entityName, typeInformati } if (errorField !== undefined) { - callback(new errors.DeviceNotFound(entityName)); + callback(new errors.DeviceNotFound(entityName, typeInformation)); } else { callback( new errors.EntityGenericError( diff --git a/lib/services/ngsi/entities-NGSI-v2.js b/lib/services/ngsi/entities-NGSI-v2.js index aed0fa898..72a774a09 100644 --- a/lib/services/ngsi/entities-NGSI-v2.js +++ b/lib/services/ngsi/entities-NGSI-v2.js @@ -173,7 +173,7 @@ function generateNGSI2OperationHandler(operationName, entityName, typeInformatio } if (errorField !== undefined) { - callback(new errors.DeviceNotFound(entityName)); + callback(new errors.DeviceNotFound(entityName, typeInformation)); } else { callback( new errors.EntityGenericError( diff --git a/lib/services/northBound/contextServer-NGSI-LD.js b/lib/services/northBound/contextServer-NGSI-LD.js index a1016b9b8..e9c3d1b66 100644 --- a/lib/services/northBound/contextServer-NGSI-LD.js +++ b/lib/services/northBound/contextServer-NGSI-LD.js @@ -48,41 +48,36 @@ const overwritePaths = ['/ngsi-ld/v1/entities/:entity/attrs', '/ngsi-ld/v1/entit const updatePaths = ['/ngsi-ld/v1/entities/:entity/attrs', '/ngsi-ld/v1/entities/:entity/attrs/:attr']; const queryPaths = ['/ngsi-ld/v1/entities/:entity']; - /** * Replacement of NGSI-LD Null placeholders with real null values * */ -function replaceNGSILDNull(payload){ - Object.keys(payload).forEach((key) =>{ +function replaceNGSILDNull(payload) { + Object.keys(payload).forEach((key) => { const value = payload[key]; - if ( value === constants.NGSI_LD_NULL){ - payload[key] = null; - } else if (typeof value === 'object' && - !Array.isArray(value) && - value !== null){ + if (value === constants.NGSI_LD_NULL) { + payload[key] = null; + } else if (typeof value === 'object' && !Array.isArray(value) && value !== null) { payload[key] = replaceNGSILDNull(payload[key]); } - }) - return payload; + }); + return payload; } /** * Check to see if the payload or its subattributes contain null values * */ -function containsNulls(payload, result){ - Object.keys(payload).forEach((key) =>{ +function containsNulls(payload, result) { + Object.keys(payload).forEach((key) => { const value = payload[key]; - if ( value === null){ - result.nulls = true; - } else if (typeof value === 'object' && - !Array.isArray(value) && - value !== null){ + if (value === null) { + result.nulls = true; + } else if (typeof value === 'object' && !Array.isArray(value) && value !== null) { containsNulls(payload[key], result); } - }) - return result; + }); + return result; } /** @@ -90,23 +85,23 @@ function containsNulls(payload, result){ * to real nulls and checks for the presence of null and datasetId * */ -function preprocessNGSILD(req, res, next){ - res.locals.hasDatasetId = false; - const payload = req.body - if (payload && typeof payload === 'object'){ - Object.keys(payload).forEach((key) =>{ - if (_.isArray(payload[key])){ +function preprocessNGSILD(req, res, next) { + res.locals.hasDatasetId = false; + const payload = req.body; + if (payload && typeof payload === 'object') { + Object.keys(payload).forEach((key) => { + if (_.isArray(payload[key])) { payload[key].forEach((obj) => { - if (obj.datasetId){ + if (obj.datasetId) { res.locals.hasDatasetId = true; } }); - } else if (payload[key] && payload[key].datasetId && payload[key].datasetId !== '@none'){ - res.locals.hasDatasetId = true; - } + } else if (payload[key] && payload[key].datasetId && payload[key].datasetId !== '@none') { + res.locals.hasDatasetId = true; + } }); req.body = replaceNGSILDNull(payload); - const result = { nulls: false } + const result = { nulls: false }; containsNulls(payload, result); res.locals.hasNulls = result.nulls; } @@ -124,16 +119,23 @@ function preprocessNGSILD(req, res, next){ function validateNGSILD(supportNull, supportDatasetId) { return function validate(req, res, next) { if (!supportNull && res.locals.hasNulls) { - next(new errors.BadRequest('NGSI-LD Null found within the payload. This IoT Agent does not support nulls for this endpoint.')); + next( + new errors.BadRequest( + 'NGSI-LD Null found within the payload. This IoT Agent does not support nulls for this endpoint.' + ) + ); } else if (!supportDatasetId && res.locals.hasDatasetId) { - next(new errors.BadRequest('datasetId found within the payload. This IoT Agent does not support multi-attribute requests.')); + next( + new errors.BadRequest( + 'datasetId found within the payload. This IoT Agent does not support multi-attribute requests.' + ) + ); } else { next(); } }; } - /** * Extract metadata attributes from input. * @@ -413,34 +415,31 @@ function defaultQueryHandlerNgsiLD(id, type, service, subservice, attributes, ca * @param {Object} req Update request to generate Actions from */ function generateMergePatchActionNgsiLD(req, callback) { - const entityId = req.params.entity; - - function addAttributes(deviceData, body, attributes){ + function addAttributes(deviceData, body, attributes) { const keys = Object.keys(body); for (const j in deviceData) { if (keys.includes(deviceData[j].name)) { - const obj = body[deviceData[j].name] - if ( obj === null) { + const obj = body[deviceData[j].name]; + if (obj === null) { attributes.push({ type: deviceData[j].type, value: null, name: deviceData[j].name }); } else { - attributes.push({ + attributes.push({ type: deviceData[j].type, value: obj.value, name: deviceData[j].name }); } - } + } } return attributes; } - deviceService.getDeviceByName( entityId, @@ -451,8 +450,8 @@ function generateMergePatchActionNgsiLD(req, callback) { callback(error); } else { const attributes = []; - addAttributes(deviceObj.commands, req.body, attributes) - addAttributes(deviceObj.lazy, req.body, attributes) + addAttributes(deviceObj.commands, req.body, attributes); + addAttributes(deviceObj.lazy, req.body, attributes); const executeMergePatchHandler = apply( contextServerUtils.mergePatchHandler, entityId, @@ -461,10 +460,7 @@ function generateMergePatchActionNgsiLD(req, callback) { contextServerUtils.getLDPath(req), attributes ); - async.waterfall( - [executeMergePatchHandler], - callback() - ); + async.waterfall([executeMergePatchHandler], callback()); } } ); @@ -477,7 +473,6 @@ function generateMergePatchActionNgsiLD(req, callback) { * @param {Object} res Response that will be sent. */ function handleMergePatchNgsiLD(req, res, next) { - function handleMergePatchRequest(error, result) { if (error) { logger.debug(context, 'There was an error handling the merge-patch: %s.', error); @@ -492,15 +487,15 @@ function handleMergePatchNgsiLD(req, res, next) { if ((req.is('json') || req.is('application/ld+json')) === false) { return handleMergePatchRequest(new errors.UnsupportedContentType(req.header('content-type'))); } - + if (req.body) { logger.debug(context, JSON.stringify(req.body, null, 4)); } - if (contextServerUtils.mergePatchHandler){ + if (contextServerUtils.mergePatchHandler) { generateMergePatchActionNgsiLD(req, handleMergePatchRequest); } else { - return handleMergePatchRequest(new errors.MethodNotSupported(req.method, req.path)) + return handleMergePatchRequest(new errors.MethodNotSupported(req.method, req.path)); } } @@ -610,7 +605,7 @@ function handleQueryNgsiLD(req, res, next) { getFunction(function handleFindDevice(error, innerDevice) { let deviceList = []; if (!innerDevice) { - return callback(new errors.DeviceNotFound(contextEntity.id)); + return callback(new errors.DeviceNotFound(contextEntity.id, contextEntity)); } if (innerDevice.count) { @@ -689,7 +684,7 @@ function ErrorHandlingNgsiLD(action) { error: error.name, description: error.message.replace(/[<>\"\'=;\(\)]/g, '') }); - } + }; } /** @@ -812,7 +807,7 @@ function loadUnsupportedEndpointsNGSILD(router) { function loadContextRoutesNGSILD(router) { // In a more evolved implementation, more endpoints could be added to queryPathsNgsi2 // according to https://www.etsi.org/standards-search#page=1&search=GS%20CIM%20009 - + const support = config.getConfig().server.ldSupport; let i; @@ -832,7 +827,7 @@ function loadContextRoutesNGSILD(router) { router.patch('/ngsi-ld/v1/entities/:entity', [ preprocessNGSILD, validateNGSILD(support.null, support.datasetId), - handleMergePatchNgsiLD, + handleMergePatchNgsiLD, ErrorHandlingNgsiLD('Merge-Patch') ]); diff --git a/lib/services/northBound/contextServer-NGSI-v2.js b/lib/services/northBound/contextServer-NGSI-v2.js index 360def2ea..d7bbf8711 100644 --- a/lib/services/northBound/contextServer-NGSI-v2.js +++ b/lib/services/northBound/contextServer-NGSI-v2.js @@ -503,7 +503,7 @@ function handleQueryNgsi2(req, res, next) { getFunction(function handleFindDevice(error, innerDevice) { let deviceList = []; if (!innerDevice) { - return callback(new errors.DeviceNotFound(contextEntity.id)); + return callback(new errors.DeviceNotFound(contextEntity.id), contextEntity); } if (innerDevice.count) { diff --git a/lib/services/northBound/deviceProvisioningServer.js b/lib/services/northBound/deviceProvisioningServer.js index d599b2758..c9b3ccb07 100644 --- a/lib/services/northBound/deviceProvisioningServer.js +++ b/lib/services/northBound/deviceProvisioningServer.js @@ -263,7 +263,11 @@ function handleGetDevice(req, res, next) { } else if (device) { res.status(200).json(toProvisioningAPIFormat(device)); } else { - next(new errors.DeviceNotFound(req.params.deviceId)); + next(new errors.DeviceNotFound(req.params.deviceId), { + apikey: req.query.apikey, + service: req.headers['fiware-service'], + subservice: req.headers['fiware-servicepath'] + }); } } ); @@ -276,7 +280,13 @@ function getDevice(deviceId, apikey, service, subservice, callback) { } else if (device) { callback(null, device); } else { - callback(new errors.DeviceNotFound(deviceId)); + callback( + new errors.DeviceNotFound(deviceId, { + apikey: apikey, + service: service, + subservice: subservice + }) + ); } }); } @@ -320,7 +330,13 @@ function handleRemoveDevice(req, res, next) { if (error && error.code !== 404) { next(error); } else if (error && error.code === 404) { - next(new errors.DeviceNotFound(req.params.deviceId)); + next( + new errors.DeviceNotFound(req.params.deviceId, { + apikey: req.query.apikey, + service: req.headers['fiware-service'], + subservice: req.headers['fiware-servicepath'] + }) + ); } else { res.status(204).send(); } @@ -359,7 +375,13 @@ function handleRemoveDevices(req, res, next) { if (error && error.code !== 404) { theError = !theError ? error : theError; } else if (error && error.code === 404) { - theError = !theError ? new errors.DeviceNotFound(devicetoRemove.deviceId) : theError; + theError = !theError + ? new errors.DeviceNotFound(devicetoRemove.deviceId, { + apikey: devicetoRemove.apikey, + service: req.headers['fiware-service'], + subservice: req.headers['fiware-servicepath'] + }) + : theError; } } ); // waterfall @@ -423,7 +445,13 @@ function handleUpdateDevice(req, res, next) { } ); } else { - next(new errors.DeviceNotFound(req.params.deviceId)); + next( + new errors.DeviceNotFound(req.params.deviceId, { + apikey: req.query.apikey, + service: req.headers['fiware-service'], + subservice: req.headers['fiware-servicepath'] + }) + ); } } ); From 7b506dace999945eb4d9f5c74ce65e0acbb5641d Mon Sep 17 00:00:00 2001 From: Keshav Soni <102344018+KeshavSoni2511@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:19:29 +0530 Subject: [PATCH 06/23] Update entities-NGSI-v2.js --- lib/services/ngsi/entities-NGSI-v2.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/services/ngsi/entities-NGSI-v2.js b/lib/services/ngsi/entities-NGSI-v2.js index 08f1d3b66..78a16be7d 100644 --- a/lib/services/ngsi/entities-NGSI-v2.js +++ b/lib/services/ngsi/entities-NGSI-v2.js @@ -301,7 +301,10 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call jexlctxt = reduceAttrToPlainObject(idTypeSSSList, jexlctxt); //Managing timestamp (mustInsertTimeInstant flag to decide if we should insert Timestamp later on) - const mustInsertTimeInstant = typeInformation.timestamp !== undefined ? typeInformation.timestamp : false; + const mustInsertTimeInstant = + typeInformation.timestamp !== undefined + ? typeInformation.timestamp + : false; if (mustInsertTimeInstant) { //remove TimeInstant from measures From 70b9387b02a37fb492fc2130740e7694ab71187a Mon Sep 17 00:00:00 2001 From: Keshav Soni <102344018+KeshavSoni2511@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:27:10 +0530 Subject: [PATCH 07/23] Update entities-NGSI-v2.js const config is removed as it is never used --- lib/services/ngsi/entities-NGSI-v2.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/services/ngsi/entities-NGSI-v2.js b/lib/services/ngsi/entities-NGSI-v2.js index 78a16be7d..95f0d5bfd 100644 --- a/lib/services/ngsi/entities-NGSI-v2.js +++ b/lib/services/ngsi/entities-NGSI-v2.js @@ -31,7 +31,6 @@ const request = require('../../request-shim'); const alarms = require('../common/alarmManagement'); const errors = require('../../errors'); const pluginUtils = require('../../plugins/pluginUtils'); -const config = require('../../commonConfig'); const constants = require('../../constants'); const jexlParser = require('../../plugins/jexlParser'); const expressionPlugin = require('../../plugins/expressionPlugin'); From 7d0e2c438f45a84b4221ad73c4ab0dd64f8ebf3b Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 08:34:25 +0100 Subject: [PATCH 08/23] update CNR --- CHANGES_NEXT_RELEASE | 1 + lib/services/ngsi/entities-NGSI-LD.js | 10 +--------- lib/services/ngsi/entities-NGSI-v2.js | 10 +--------- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 4f082b34c..6d989b02f 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1,2 +1,3 @@ +- ADD: Log and return device/group information when EntityGenericError TypeNotFound DeviceNotFound BadTimestamp errors - Add: `POST /iot/op/delete` operation to delete multiple devices at once (#1578) - Fix: store device subscriptions updates (#1086) diff --git a/lib/services/ngsi/entities-NGSI-LD.js b/lib/services/ngsi/entities-NGSI-LD.js index 8691d7ee8..81046aee3 100644 --- a/lib/services/ngsi/entities-NGSI-LD.js +++ b/lib/services/ngsi/entities-NGSI-LD.js @@ -383,15 +383,7 @@ function generateNGSILDOperationHandler(operationName, entityName, typeInformati if (errorField !== undefined) { callback(new errors.DeviceNotFound(entityName, typeInformation)); } else { - callback( - new errors.EntityGenericError( - entityName, - typeInformation.type, - typeInformation, - body, - response.statusCode - ) - ); + callback(new errors.EntityGenericError(entityName, typeInformation.type, typeInformation, body)); } } else { logger.debug(context, 'Unknown error executing ' + operationName + ' operation'); diff --git a/lib/services/ngsi/entities-NGSI-v2.js b/lib/services/ngsi/entities-NGSI-v2.js index 72a774a09..8418b8c6d 100644 --- a/lib/services/ngsi/entities-NGSI-v2.js +++ b/lib/services/ngsi/entities-NGSI-v2.js @@ -175,15 +175,7 @@ function generateNGSI2OperationHandler(operationName, entityName, typeInformatio if (errorField !== undefined) { callback(new errors.DeviceNotFound(entityName, typeInformation)); } else { - callback( - new errors.EntityGenericError( - entityName, - typeInformation.type, - typeInformation, - body, - response.statusCode - ) - ); + callback(new errors.EntityGenericError(entityName, typeInformation.type, typeInformation, body)); } } else { logger.debug(context, 'Unknown error executing ' + operationName + ' operation'); From 121eab5065eebe99a747d3a086a80333f6800e67 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 08:52:03 +0100 Subject: [PATCH 09/23] bad timestmap error should not progress to CB --- CHANGES_NEXT_RELEASE | 1 + lib/services/ngsi/entities-NGSI-v2.js | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 4f082b34c..be6f9ddad 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1,2 +1,3 @@ - Add: `POST /iot/op/delete` operation to delete multiple devices at once (#1578) - Fix: store device subscriptions updates (#1086) +- FIX: badtimestamp error should not progress to ContextBroker diff --git a/lib/services/ngsi/entities-NGSI-v2.js b/lib/services/ngsi/entities-NGSI-v2.js index 2238a4ed2..21b812610 100644 --- a/lib/services/ngsi/entities-NGSI-v2.js +++ b/lib/services/ngsi/entities-NGSI-v2.js @@ -318,6 +318,7 @@ function sendUpdateValueNgsi2(entityName, measures, typeInformation, token, call timestamp.value = plainMeasures[constants.TIMESTAMP_ATTRIBUTE]; } else { callback(new errors.BadTimestamp(plainMeasures[constants.TIMESTAMP_ATTRIBUTE], entityName)); + return; } } else if (!typeInformation.timezone) { timestamp.value = new Date().toISOString(); From f9eb5ff6449cfcabe54889e2252a9edba84b2f05 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 09:11:11 +0100 Subject: [PATCH 10/23] add DuplicateDeviceId and DuplicateGroup errros --- lib/errors.js | 15 +++++++++++---- lib/services/devices/deviceRegistryMemory.js | 2 +- lib/services/devices/deviceRegistryMongoDB.js | 2 +- lib/services/devices/deviceService.js | 2 +- lib/services/groups/groupRegistryMemory.js | 2 +- lib/services/groups/groupRegistryMongoDB.js | 2 +- lib/services/groups/groupService.js | 2 +- 7 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index 4032ee29c..b94c67a65 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -104,16 +104,23 @@ class DeviceNotFound { } } class DuplicateDeviceId { - constructor(id) { + constructor(id, device) { this.name = 'DUPLICATE_DEVICE_ID'; - this.message = 'A device with the same pair (Service, DeviceId) was found:' + id; + this.message = + 'A device with the same pair (Service, DeviceId) was found:' + id + ' and ' + JSON.stringify(device); this.code = 409; } } class DuplicateGroup { - constructor(res, key) { + constructor(group) { this.name = 'DUPLICATE_GROUP'; - this.message = 'A device configuration already exists for resource ' + res + ' and API Key ' + key; + this.message = + 'A device configuration already exists for resource ' + + group.resource + + ' and API Key ' + + group.apikey + + ' and ' + + JSON.stringify(group); this.code = 409; } } diff --git a/lib/services/devices/deviceRegistryMemory.js b/lib/services/devices/deviceRegistryMemory.js index 7f7408dd0..b801f2744 100644 --- a/lib/services/devices/deviceRegistryMemory.js +++ b/lib/services/devices/deviceRegistryMemory.js @@ -54,7 +54,7 @@ function storeDevice(newDevice, callback) { } if (registeredDevices[newDevice.service][newDevice.id]) { - callback(new errors.DuplicateDeviceId(newDevice.id)); + callback(new errors.DuplicateDeviceId(newDevice)); } else { registeredDevices[newDevice.service][newDevice.id] = deepClone(newDevice); registeredDevices[newDevice.service][newDevice.id].creationDate = Date.now(); diff --git a/lib/services/devices/deviceRegistryMongoDB.js b/lib/services/devices/deviceRegistryMongoDB.js index 510dc8f58..291848ce2 100644 --- a/lib/services/devices/deviceRegistryMongoDB.js +++ b/lib/services/devices/deviceRegistryMongoDB.js @@ -102,7 +102,7 @@ function storeDevice(newDevice, callback) { if (error.code === 11000) { logger.debug(context, 'Tried to insert a device with duplicate ID in the database: %s', error); - callback(new errors.DuplicateDeviceId(newDevice.id)); + callback(new errors.DuplicateDeviceId(newDevice)); } else { logger.debug(context, 'Error storing device information: %s', error); diff --git a/lib/services/devices/deviceService.js b/lib/services/devices/deviceService.js index 66e3255d5..2d773ef78 100644 --- a/lib/services/devices/deviceService.js +++ b/lib/services/devices/deviceService.js @@ -244,7 +244,7 @@ function registerDevice(deviceObj, callback) { /* eslint-disable-next-line no-unused-vars */ function (error, device) { if (!error) { - innerCb(new errors.DuplicateDeviceId(deviceObj.id)); + innerCb(new errors.DuplicateDeviceId(deviceObj)); } else { innerCb(); } diff --git a/lib/services/groups/groupRegistryMemory.js b/lib/services/groups/groupRegistryMemory.js index a4ef73a1d..5d0173175 100644 --- a/lib/services/groups/groupRegistryMemory.js +++ b/lib/services/groups/groupRegistryMemory.js @@ -50,7 +50,7 @@ function exists(group) { function createGroup(group, callback) { if (exists(group)) { - callback(new errors.DuplicateGroup(group.resource, group.apikey)); + callback(new errors.DuplicateGroup(group)); } else { const storeGroup = _.clone(group); diff --git a/lib/services/groups/groupRegistryMongoDB.js b/lib/services/groups/groupRegistryMongoDB.js index 8a5bdb9e9..740a3fad7 100644 --- a/lib/services/groups/groupRegistryMongoDB.js +++ b/lib/services/groups/groupRegistryMongoDB.js @@ -110,7 +110,7 @@ function createGroup(group, callback) { group.apikey ); - callback(new errors.DuplicateGroup(group.resource, group.apikey)); + callback(new errors.DuplicateGroup(group)); } else { logger.debug(context, 'Error storing device group information: %s', error); diff --git a/lib/services/groups/groupService.js b/lib/services/groups/groupService.js index d8e8a48bc..a1e70061a 100644 --- a/lib/services/groups/groupService.js +++ b/lib/services/groups/groupService.js @@ -48,7 +48,7 @@ function validateGroup(group, callback) { return function (error, foundGroup) { logger.debug(context, 'generateDuplicateHander error %j and foundGroup %j', error, foundGroup); if (!error || (foundGroup && foundGroup.count > 0)) { - innerCb(new errors.DuplicateGroup(group.resource, group.apikey)); + innerCb(new errors.DuplicateGroup(group)); } else { innerCb(); } From 27234d4b4408574f1aad19c92b4bc069f52e7a72 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 09:11:37 +0100 Subject: [PATCH 11/23] add DuplicateDeviceId and DuplicateGroup errros --- lib/errors.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index b94c67a65..89275e76c 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -104,10 +104,10 @@ class DeviceNotFound { } } class DuplicateDeviceId { - constructor(id, device) { + constructor(device) { this.name = 'DUPLICATE_DEVICE_ID'; this.message = - 'A device with the same pair (Service, DeviceId) was found:' + id + ' and ' + JSON.stringify(device); + 'A device with the same pair (Service, DeviceId) was found:' + device.id + ' and ' + JSON.stringify(device); this.code = 409; } } From 57f6dc07fadda6d68299e509a5bab30ce43c4b81 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 09:21:06 +0100 Subject: [PATCH 12/23] add MissingAttributes error --- lib/errors.js | 4 ++-- lib/services/devices/devices-NGSI-LD.js | 2 +- lib/services/devices/devices-NGSI-v2.js | 2 +- lib/services/northBound/restUtils.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index 89275e76c..d829d91bb 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -91,9 +91,9 @@ class TypeNotFound { } } class MissingAttributes { - constructor(msg) { + constructor(msg, device) { this.name = 'MISSING_ATTRIBUTES'; - this.message = 'The request was not well formed:' + msg; + this.message = 'The request was not well formed:' + msg + ' with: ' + +JSON.stringify(device); } } class DeviceNotFound { diff --git a/lib/services/devices/devices-NGSI-LD.js b/lib/services/devices/devices-NGSI-LD.js index 17e983db8..42487e6fb 100644 --- a/lib/services/devices/devices-NGSI-LD.js +++ b/lib/services/devices/devices-NGSI-LD.js @@ -184,7 +184,7 @@ function updateEntityNgsiLD(deviceData, updatedDevice, callback) { */ function updateRegisterDeviceNgsiLD(deviceObj, entityInfoUpdated, callback) { if (!deviceObj.id || !deviceObj.type) { - callback(new errors.MissingAttributes('Id or device missing')); + callback(new errors.MissingAttributes('Id or device missing', deviceObj)); return; } diff --git a/lib/services/devices/devices-NGSI-v2.js b/lib/services/devices/devices-NGSI-v2.js index d8a2fe632..9efb65707 100644 --- a/lib/services/devices/devices-NGSI-v2.js +++ b/lib/services/devices/devices-NGSI-v2.js @@ -249,7 +249,7 @@ function updateEntityNgsi2(deviceData, updatedDevice, callback) { */ function updateRegisterDeviceNgsi2(deviceObj, entityInfoUpdated, callback) { if (!deviceObj.id || !deviceObj.type) { - callback(new errors.MissingAttributes('Id or device missing')); + callback(new errors.MissingAttributes('Id or device missing', deviceObj)); return; } diff --git a/lib/services/northBound/restUtils.js b/lib/services/northBound/restUtils.js index 9be885c80..46dc27b38 100644 --- a/lib/services/northBound/restUtils.js +++ b/lib/services/northBound/restUtils.js @@ -65,7 +65,7 @@ function checkMandatoryQueryParams(mandatoryAttributes, body, callback) { } if (missing.length !== 0) { - const error = new errors.MissingAttributes('Missing attributes: ' + JSON.stringify(missing)); + const error = new errors.MissingAttributes('Missing attributes: ' + JSON.stringify(missing), body); error.code = '400'; callback(error); From c0ea562969f8522f82180f5e918324fe20643c09 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 09:53:00 +0100 Subject: [PATCH 13/23] add CommandNotFound error --- lib/errors.js | 8 +++- .../commands/commandRegistryMemory.js | 14 ++++++- .../commands/commandRegistryMongoDB.js | 41 ++++++++++++------- lib/services/ngsi/ngsiService.js | 2 +- 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index d829d91bb..ec506f014 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -184,9 +184,13 @@ class WrongSyntax { } } class CommandNotFound { - constructor(name) { + constructor(name, typeInformation) { this.name = 'COMMAND_NOT_FOUND'; - this.message = "Couldn't update the command because no command with the name [" + name + '] was found.'; + this.message = + "Couldn't update the command because no command with the name [" + + name + + '] was found with ' + + JSON.stringify(typeInformation); this.code = 400; } } diff --git a/lib/services/commands/commandRegistryMemory.js b/lib/services/commands/commandRegistryMemory.js index b1948d044..e0a59577c 100644 --- a/lib/services/commands/commandRegistryMemory.js +++ b/lib/services/commands/commandRegistryMemory.js @@ -75,7 +75,12 @@ function updateCommand(service, subservice, deviceId, command, callback) { callback(null, foundCommand); } else { - callback(new errors.CommandNotFound(command.name)); + const deviceInfo = { + service, + subservice, + deviceId + }; + callback(new errors.CommandNotFound(command.name, deviceInfo)); } } @@ -144,7 +149,12 @@ function remove(service, subservice, deviceId, name, callback) { delete registeredCommands[foundCommand._id]; callback(null, foundCommand); } else { - callback(new errors.CommandNotFound(name)); + const deviceInfo = { + service, + subservice, + deviceId + }; + callback(new errors.CommandNotFound(name, deviceInfo)); } } diff --git a/lib/services/commands/commandRegistryMongoDB.js b/lib/services/commands/commandRegistryMongoDB.js index 31efedc3a..a3df434ca 100644 --- a/lib/services/commands/commandRegistryMongoDB.js +++ b/lib/services/commands/commandRegistryMongoDB.js @@ -39,7 +39,7 @@ function findCommand(service, subservice, deviceId, name, callback) { name }; - logger.debug(context, 'Looking for command [%s] for device [%s]', name, deviceId); + logger.debug(context, 'Looking for command [%s] for device [%s] with [%j]', name, deviceId, queryObj); const query = Command.model.findOne(queryObj); @@ -53,8 +53,14 @@ function findCommand(service, subservice, deviceId, name, callback) { } else if (data) { callback(null, data); } else { - logger.debug(context, 'Command for DeviceID [%j] with name [%j] not found', deviceId, name); - callback(new errors.CommandNotFound(name)); + logger.debug( + context, + 'Command for DeviceID [%j] with name [%j] not found with [%j]', + deviceId, + name, + queryObj + ); + callback(new errors.CommandNotFound(name, queryObj)); } }); } @@ -124,15 +130,15 @@ function listCommands(service, subservice, deviceId, callback) { const query = Command.model.find(condition).sort(); - async.series([query.exec.bind(query), Command.model.countDocuments.bind(Command.model, condition)], function ( - error, - results - ) { - callback(error, { - count: results[1], - commands: results[0].map(toObjectFn) - }); - }); + async.series( + [query.exec.bind(query), Command.model.countDocuments.bind(Command.model, condition)], + function (error, results) { + callback(error, { + count: results[1], + commands: results[0].map(toObjectFn) + }); + } + ); } function remove(service, subservice, deviceId, name, callback) { @@ -159,9 +165,14 @@ function remove(service, subservice, deviceId, name, callback) { callback(null, commandResult); } else { - logger.debug(context, 'Command [%s] not found for removal.', name); - - callback(new errors.CommandNotFound(name)); + const deviceInfo = { + service, + subservice, + deviceId, + name + }; + logger.debug(context, 'Command [%s] not found for removal with %j', name, deviceInfo); + callback(new errors.CommandNotFound(name, deviceInfo)); } }); } diff --git a/lib/services/ngsi/ngsiService.js b/lib/services/ngsi/ngsiService.js index aea6ef802..92833d521 100644 --- a/lib/services/ngsi/ngsiService.js +++ b/lib/services/ngsi/ngsiService.js @@ -236,7 +236,7 @@ function setCommandResult( if (commandInfo.length === 1) { exports.update(entityName, typeInformation.type, apikey, attributes, typeInformation, callback); } else { - callback(new errors.CommandNotFound(commandName)); + callback(new errors.CommandNotFound(commandName, typeInformation)); } }); } From af0ae4ed132f60f4df0ac73924eaae7908e3f3a3 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 10:21:42 +0100 Subject: [PATCH 14/23] add CommandNotFound GroupNotFound --- lib/errors.js | 7 ++++--- lib/services/groups/groupService.js | 10 ++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index ec506f014..033e90985 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -93,7 +93,7 @@ class TypeNotFound { class MissingAttributes { constructor(msg, device) { this.name = 'MISSING_ATTRIBUTES'; - this.message = 'The request was not well formed:' + msg + ' with: ' + +JSON.stringify(device); + this.message = 'The request was not well formed:' + msg + ' with: ' + JSON.stringify(device); } } class DeviceNotFound { @@ -219,9 +219,10 @@ class DeviceGroupNotFound { } } class GroupNotFound { - constructor(service, subservice) { + constructor(service, subservice, type) { this.name = 'GROUP_NOT_FOUND'; - this.message = 'Group not found for service [' + service + '] and subservice [' + subservice + ']'; + this.message = + 'Group not found for service [' + service + '] subservice [' + subservice + '] and type [' + type + ']'; this.code = 404; } } diff --git a/lib/services/groups/groupService.js b/lib/services/groups/groupService.js index a1e70061a..8f9d734f5 100644 --- a/lib/services/groups/groupService.js +++ b/lib/services/groups/groupService.js @@ -291,8 +291,14 @@ function getEffectiveApiKey(service, subservice, type, callback) { logger.debug(context, 'Using default API Key: %s', config.getConfig().defaultKey); callback(null, config.getConfig().defaultKey); } else { - logger.error(context, 'Could not find any API Key information for device.'); - callback(new errors.GroupNotFound(service, subservice)); + logger.error( + context, + 'Could not find any APIKey information for device in service %s subservice %s and type %s', + service, + subservice, + type + ); + callback(new errors.GroupNotFound(service, subservice, type)); } } From 5d6f54d7bb7160cfd822e714e534b1d08579aa24 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 10:28:46 +0100 Subject: [PATCH 15/23] add BadGeocoordinates --- lib/errors.js | 2 +- lib/services/devices/devices-NGSI-v2.js | 2 +- lib/services/ngsi/entities-NGSI-LD.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index 033e90985..c1cf4ae7e 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -261,7 +261,7 @@ class BadTimestamp { } } class BadGeocoordinates { - constructor(payload) { + constructor(payload, deviceData) { this.name = 'BAD_GEOCOORDINATES'; this.message = 'Invalid rfc7946 coordinates [' + payload + ']'; this.code = 400; diff --git a/lib/services/devices/devices-NGSI-v2.js b/lib/services/devices/devices-NGSI-v2.js index 9efb65707..77ee7431f 100644 --- a/lib/services/devices/devices-NGSI-v2.js +++ b/lib/services/devices/devices-NGSI-v2.js @@ -210,7 +210,7 @@ function updateEntityNgsi2(deviceData, updatedDevice, callback) { // Format any GeoJSON attrs properly options.json[att] = NGSIv2.formatGeoAttrs(options.json[att]); } catch (error) { - return callback(new errors.BadGeocoordinates(JSON.stringify(options.json))); + return callback(new errors.BadGeocoordinates(JSON.stringify(options.json), deviceData)); } } diff --git a/lib/services/ngsi/entities-NGSI-LD.js b/lib/services/ngsi/entities-NGSI-LD.js index 81046aee3..be8512905 100644 --- a/lib/services/ngsi/entities-NGSI-LD.js +++ b/lib/services/ngsi/entities-NGSI-LD.js @@ -1052,7 +1052,7 @@ function sendUpdateValueNgsiLD(entityName, attributes, typeInformation, token, c options.json = [formatAsNGSILD(options.json)]; } } catch (error) { - return callback(new errors.BadGeocoordinates(JSON.stringify(payload))); + return callback(new errors.BadGeocoordinates(JSON.stringify(payload), typeInformation)); } if (typeInformation.active) { From 6ecaacbf75ef0fa96e927fda7d619ff5543e8e62 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 10:32:17 +0100 Subject: [PATCH 16/23] fix device --- lib/errors.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/errors.js b/lib/errors.js index c1cf4ae7e..08a57e062 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -261,9 +261,9 @@ class BadTimestamp { } } class BadGeocoordinates { - constructor(payload, deviceData) { + constructor(payload, device) { this.name = 'BAD_GEOCOORDINATES'; - this.message = 'Invalid rfc7946 coordinates [' + payload + ']'; + this.message = 'Invalid rfc7946 coordinates [' + payload + '] in ' + JSON.stringify(device); this.code = 400; } } From ae0c71ed422d8fe2febd566cde98a041c0f162e2 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 11:03:46 +0100 Subject: [PATCH 17/23] =?UTF-8?q?update=20CNR=C2=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES_NEXT_RELEASE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 6d989b02f..11addbd1c 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1,3 +1,3 @@ -- ADD: Log and return device/group information when EntityGenericError TypeNotFound DeviceNotFound BadTimestamp errors +- ADD: Log and return device/group information when EntityGenericError TypeNotFound DeviceNotFound BadTimestamp BadGeocoordinates CommandNotFound GroupNotFound MissingAttributes DuplicateDeviceId and DuplicateGroup errors - Add: `POST /iot/op/delete` operation to delete multiple devices at once (#1578) - Fix: store device subscriptions updates (#1086) From c8433b5af81718434abde6a0cbf5130b18ad0d7c Mon Sep 17 00:00:00 2001 From: Keshav Soni <102344018+KeshavSoni2511@users.noreply.github.com> Date: Thu, 22 Feb 2024 18:15:10 +0530 Subject: [PATCH 18/23] Update CHANGES_NEXT_RELEASE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes done as per feedback received Co-authored-by: Fermín Galán Márquez --- CHANGES_NEXT_RELEASE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 33ad2b9df..5a9443896 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1,3 +1,3 @@ -- Fix: typeInformation contain global config values (#1515) +- Hardening: simplify implementation so typeInformation contains global config values (#1515) - Add: `POST /iot/op/delete` operation to delete multiple devices at once (#1578) - Fix: store device subscriptions updates (#1086) From d6cf6376e567ff54259f73615df0d96c87cb293c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferm=C3=ADn=20Gal=C3=A1n=20M=C3=A1rquez?= Date: Thu, 22 Feb 2024 15:26:59 +0100 Subject: [PATCH 19/23] Update CHANGES_NEXT_RELEASE --- CHANGES_NEXT_RELEASE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index be6f9ddad..cee39d7cb 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1,3 +1,3 @@ - Add: `POST /iot/op/delete` operation to delete multiple devices at once (#1578) - Fix: store device subscriptions updates (#1086) -- FIX: badtimestamp error should not progress to ContextBroker +- Fix: badtimestamp error should not progress to ContextBroker From 4bd98b59e7de8645e8db0f55c77711bd5e3b5353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferm=C3=ADn=20Gal=C3=A1n=20M=C3=A1rquez?= Date: Thu, 22 Feb 2024 15:28:40 +0100 Subject: [PATCH 20/23] Update CHANGES_NEXT_RELEASE --- CHANGES_NEXT_RELEASE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index b34f98ab0..58bbfae3a 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1,4 +1,4 @@ -- Add: log and return device/group information when EntityGenericError, TypeNotFound, DeviceNotFound, BadTimestamp, BadGeocoordinates, CommandNotFound, GroupNotFound, MissingAttributes, DuplicateDeviceId and DuplicateGroup errors +- Add: log and return device/group information when EntityGenericError, TypeNotFound, DeviceNotFound, BadTimestamp, BadGeocoordinates, CommandNotFound, GroupNotFound, MissingAttributes, DuplicateDeviceId and DuplicateGroup errors (iotagent-json#815) - Hardening: simplify implementation so typeInformation contains global config values (#1515) - Add: `POST /iot/op/delete` operation to delete multiple devices at once (#1578) - Fix: store device subscriptions updates (#1086) From 09b7ebce593c4fe204a4fd39a8ec6f30fe9f611e Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Thu, 22 Feb 2024 15:42:42 +0100 Subject: [PATCH 21/23] Update active-devices-test.js --- test/unit/ngsi-ld/ngsiService/active-devices-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/ngsi-ld/ngsiService/active-devices-test.js b/test/unit/ngsi-ld/ngsiService/active-devices-test.js index 9c175047e..b799af782 100644 --- a/test/unit/ngsi-ld/ngsiService/active-devices-test.js +++ b/test/unit/ngsi-ld/ngsiService/active-devices-test.js @@ -600,7 +600,6 @@ describe('NGSI-LD - Active attributes test', function () { should.exist(error.name); error.code.should.equal(207); error.details.notUpdated.should.equal('someEntities'); - //error.message.should.equal('Error accesing entity data for device: light1 of type: Light'); error.name.should.equal('ENTITY_GENERIC_ERROR'); contextBrokerMock.done(); done(); From fe79fb963fbe98ad84094a43d87e40b7690de3f1 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Tue, 27 Feb 2024 09:19:08 +0100 Subject: [PATCH 22/23] step 4.2.0-next -> 4.3.0 --- CHANGES_NEXT_RELEASE | 5 ----- package.json | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index 52eed3e12..e69de29bb 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -1,5 +0,0 @@ -- Add: log and return device/group information when EntityGenericError, TypeNotFound, DeviceNotFound, BadTimestamp, BadGeocoordinates, CommandNotFound, GroupNotFound, MissingAttributes, DuplicateDeviceId and DuplicateGroup errors (iotagent-json#815) -- Hardening: simplify implementation so typeInformation contains global config values (#1515) -- Add: `POST /iot/op/delete` operation to delete multiple devices at once (#1578) -- Fix: store device subscriptions updates (#1086) -- Fix: badtimestamp error should not progress to ContextBroker diff --git a/package.json b/package.json index b30aaaff8..18a77ad5e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "iotagent-node-lib", "license": "AGPL-3.0-only", "description": "IoT Agent library to interface with NGSI Context Broker", - "version": "4.2.0-next", + "version": "4.3.0", "homepage": "https://github.com/telefonicaid/iotagent-node-lib", "keywords": [ "fiware", From 93450495004de2f5853e03d3ee08a6352b534b20 Mon Sep 17 00:00:00 2001 From: Alvaro Vega Date: Tue, 27 Feb 2024 15:18:55 +0100 Subject: [PATCH 23/23] step 4.3.0 -> 4.3.0-next --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18a77ad5e..37e08fe00 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "iotagent-node-lib", "license": "AGPL-3.0-only", "description": "IoT Agent library to interface with NGSI Context Broker", - "version": "4.3.0", + "version": "4.3.0-next", "homepage": "https://github.com/telefonicaid/iotagent-node-lib", "keywords": [ "fiware",