Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

send ngsiv2 measure as ngsiv2 request #773

Closed
wants to merge 13 commits into from
1 change: 1 addition & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Add: endpoit to send ngsiv2 measure to Context Broker
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issue number?

- Fix: binary data representation when sending data through HTTP & MQTT (#690)
- Fix: ensure service and subservice from device in logs about error proccesing message
- Remove: legacy code about unused parsedMessageError flag
56 changes: 56 additions & 0 deletions lib/bindings/HTTPBinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,53 @@ function handleIncomingMeasure(req, res, next) {
iotaUtils.retrieveDevice(req.deviceId, req.apiKey, transport, processDeviceMeasure);
}

function handleIncomingNgsiv2Measure(req, res, next) {
function sendHandler(error) {
if (error) {
next(error);
config
.getLogger()
.error(
context,
'MEASURES-002: Could not send the ngsiv2 measure to the Context Broker due to an error: %j',
error
);
} else {
config
.getLogger()
.info(
context,
'NGSIV2 measures for device %s with apiKey %s successfully sent',
req.deviceId,
req.apiKey
);

finishSouthBoundTransaction(next);
}
}

function processNGSIv2MeasureWithDevice(device) {
iotAgentLib.sendNgsiv2Measure(device.name, device.type, '', req.jsonPayload, device, sendHandler);
}

function processNGSIv2Measure(error, device) {
if (error) {
next(error);
} else {
const localContext = _.clone(context);
req.device = device;
localContext.service = device.service;
localContext.subservice = device.subservice;
intoTrans(localContext, processNGSIv2MeasureWithDevice)(device);
}
}

context = fillService(context, { service: 'n/a', subservice: 'n/a' });
config.getLogger().debug(context, 'Processing HTTP NGSIv2 measure');

iotAgentLib.getConfiguration(config.getConfig().iota.defaultResource || '', req.apiKey, processNGSIv2Measure);
}

function isCommand(req, res, next) {
if (
req.path ===
Expand Down Expand Up @@ -633,6 +680,15 @@ function start(callback) {
returnCommands
);

httpBindingServer.router.post(
constants.HTTP_NGSIV2_MEASURE_PATH,
bodyParser.json({ strict: false }), // accept anything JSON.parse accepts
checkMandatoryParams(false),
parseData,
handleIncomingNgsiv2Measure,
returnCommands
);

httpBindingServer.router.post(
(config.getConfig().iota.defaultResource || constants.HTTP_MEASURE_PATH) +
'/' +
Expand Down
1 change: 1 addition & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports = {
HTTP_MEASURE_PATH: '/iot/d',
HTTP_CONFIGURATION_PATH: '/configuration',
HTTP_COMMANDS_PATH: '/commands',
HTTP_NGSIV2_MEASURE_PATH: '/iot/ngsiv2',

TIMESTAMP_ATTRIBUTE: 'TimeInstant',
TIMESTAMP_TYPE_NGSI2: 'DateTime',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"body-parser": "1.20.0",
"dateformat": "3.0.3",
"express": "4.18.1",
"iotagent-node-lib": "https://github.com/telefonicaid/iotagent-node-lib.git#master",
"iotagent-node-lib": "https://github.com/telefonicaid/iotagent-node-lib.git#task/allow_ngsiv2_as_measure",
"logops": "2.1.2",
"mqtt": "4.3.7",
"sinon": "~6.1.0",
Expand Down
95 changes: 91 additions & 4 deletions test/unit/ngsiv2/HTTP_receive_measures-test3.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ const groupCreation = {
resource: '/iot/json',
apikey: 'KL223HHV8732SFL1',
entity_type: 'TheLightType',
trust: '8970A9078A803H3BL98PINEQRW8342HBAMS',
cbHost: 'http://unexistentHost:1026',
service: 'smartgondor',
subservice: 'gardens',
cbHost: 'http://192.168.1.1:1026',
commands: [],
lazy: [],
attributes: [
Expand Down Expand Up @@ -138,7 +139,7 @@ describe('HTTP: Measure reception ', function () {
});
});

describe('When a POST single JSON measure with NGSIv2 format arrives for the HTTP binding', function () {
describe('When a POST single JSON measure for an attribute with NGSIv2 format arrives for the HTTP binding', function () {
const optionsMeasure = {
url: 'http://localhost:' + config.http.port + '/iot/json/',
method: 'POST',
Expand Down Expand Up @@ -228,7 +229,7 @@ describe('HTTP: Measure reception ', function () {
});
});

describe('When a POST single JSON measure with NGSILD format arrives for the HTTP binding', function () {
describe('When a POST single JSON measure for an attribute with NGSILD format arrives for the HTTP binding', function () {
const optionsMeasure = {
url: 'http://localhost:' + config.http.port + '/iot/json/',
method: 'POST',
Expand Down Expand Up @@ -305,6 +306,92 @@ describe('HTTP: Measure reception ', function () {
});
});

describe('When a POST with a NGSIv2 measure arrives for the HTTP binding', function () {
const optionsMeasure = {
url: 'http://localhost:' + config.http.port + '/iot/ngsiv2',
method: 'POST',
json: {
id: 'urn:ngsi-ld:Streetlight:Streetlight-Mylightpoint-2',
type: 'Streetlight',
name: {
type: 'Text',
value: 'MyLightPoint-test1'
},
description: {
type: 'Text',
value: 'testdescription'
},
status: {
type: 'Text',
value: 'connected'
},
dateServiceStarted: {
type: 'DateTime',
value: '2020-06-04T09: 55: 02'
},
locationComment: {
type: 'Text',
value: 'Test1'
},
location: {
type: 'geo:json',
value: {
coordinates: [-87.88429, 41.99499],
type: 'Point'
}
},
address: {
type: 'Text',
value: {
streetAddress: 'MyStreet'
}
},
isRemotelyManaged: {
type: 'Integer',
value: 1
},
installationDate: {
type: 'DateTime',
value: '2022-04-17T02: 30: 04'
}
},
headers: {
'fiware-service': 'smartgondor',
'fiware-servicepath': '/gardens'
},
qs: {
i: 'MQTT_2',
k: 'KL223HHV8732SFL1'
}
};

beforeEach(function (done) {
contextBrokerMock
.matchHeader('fiware-service', 'smartgondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/v2/op/update', utils.readExampleFile('./test/unit/ngsiv2/contextRequests/ngsiv2entities.json'))
.reply(204);

request(groupCreation, function (error, response, body) {
done();
});
});
it('should return a 200 OK with no error', function (done) {
request(optionsMeasure, function (error, result, body) {
should.not.exist(error);
result.statusCode.should.equal(200);
done();
});
});

it('should send its value to the Context Broker', function (done) {
request(optionsMeasure, function (error, result, body) {
contextBrokerMock.done();
done();
});
});
});

describe('When a POST single Text measure arrives for the HTTP binding', function () {
const optionsMeasure = {
url: 'http://localhost:' + config.http.port + '/iot/json/attrs/humidity',
Expand Down
54 changes: 54 additions & 0 deletions test/unit/ngsiv2/contextRequests/ngsiv2entities.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"actionType": "append",
"entities": [
{
"id": "urn:ngsi-ld:Streetlight:Streetlight-Mylightpoint-2",
"type": "Streetlight",
"name": {
"type": "Text",
"value": "MyLightPoint-test1"
},
"description": {
"type": "Text",
"value": "testdescription"
},
"status": {
"type": "Text",
"value": "connected"
},
"dateServiceStarted": {
"type": "DateTime",
"value": "2020-06-04T09: 55: 02"
},
"locationComment": {
"type": "Text",
"value": "Test1"
},
"location": {
"type": "geo:json",
"value": {
"coordinates": [
-87.88429,
41.99499
],
"type": "Point"
}
},
"address": {
"type": "Text",
"value": {
"streetAddress": "MyStreet"
}
},
"isRemotelyManaged": {
"type": "Integer",
"value": 1
},
"installationDate": {
"type": "DateTime",
"value": "2022-04-17T02: 30: 04"
}
}
]
}

Loading