Skip to content

Commit

Permalink
add typeInformation to DeviceNotFound error
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvaroVega committed Feb 21, 2024
1 parent ef68669 commit 6fa1196
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 72 deletions.
4 changes: 2 additions & 2 deletions lib/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/services/devices/deviceRegistryMongoDB.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
});
}
Expand Down Expand Up @@ -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));
}
});
}
Expand Down Expand Up @@ -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));
}
});
}
Expand Down
4 changes: 2 additions & 2 deletions lib/services/devices/deviceService.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion lib/services/devices/devices-NGSI-LD.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/services/devices/devices-NGSI-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/services/ngsi/entities-NGSI-LD.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion lib/services/ngsi/entities-NGSI-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
105 changes: 50 additions & 55 deletions lib/services/northBound/contextServer-NGSI-LD.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,65 +48,60 @@ 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;
}

/**
* An Express middleware for preprocessing NGSI-LD payloads. Converts NGSI-LD Nulls
* 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;
}
Expand All @@ -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.
*
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -461,10 +460,7 @@ function generateMergePatchActionNgsiLD(req, callback) {
contextServerUtils.getLDPath(req),
attributes
);
async.waterfall(
[executeMergePatchHandler],
callback()
);
async.waterfall([executeMergePatchHandler], callback());
}
}
);
Expand All @@ -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);
Expand All @@ -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));
}
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -689,7 +684,7 @@ function ErrorHandlingNgsiLD(action) {
error: error.name,
description: error.message.replace(/[<>\"\'=;\(\)]/g, '')
});
}
};
}

/**
Expand Down Expand Up @@ -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;

Expand All @@ -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')
]);

Expand Down
2 changes: 1 addition & 1 deletion lib/services/northBound/contextServer-NGSI-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit 6fa1196

Please sign in to comment.