Skip to content

Commit

Permalink
Merge pull request #130 from telefonicaid/bug/commandErrorError
Browse files Browse the repository at this point in the history
Bug/command error error
  • Loading branch information
XavierVal authored Jul 4, 2016
2 parents dde952f + a279fe5 commit 04a9e9a
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1 +1 @@

- FIX Commands won't write the Error results in the Context Broker.
40 changes: 31 additions & 9 deletions lib/bindings/HTTPBindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,16 @@ function handleIncomingMeasure(req, res, next) {
* @param {String} apiKey API Key corresponding to the Devices configuration.
* @param {Object} device Device object containing all the information about a device.
* @param {String} message UL payload.
* @param {String} status End status of the command.
*/
function updateCommand(apiKey, device, message, callback) {
var commandObj = ulParser.result(message);

function updateCommand(apiKey, device, message, command, status, callback) {
iotAgentLib.setCommandResult(
device.name,
config.getConfig().iota.defaultResource,
apiKey,
commandObj.command,
commandObj.result,
constants.COMMAND_STATUS_COMPLETED,
command,
message,
status,
device,
function(error) {
if (error) {
Expand Down Expand Up @@ -226,10 +225,21 @@ function generateCommandExecution(apiKey, device, attribute) {

return function sendUlCommandHTTP(callback) {
request(options, function(error, response, body) {
if (error || response.statusCode !== 200) {
callback(new errors.HTTPCommandResponseError(response.statusCode, error));
if (error) {
callback(new errors.HTTPCommandResponseError('', error, cmdName));
} else if (response.statusCode !== 200) {
callback(new errors.HTTPCommandResponseError(response.statusCode, error, cmdName));
} else {
process.nextTick(updateCommand.bind(null, apiKey, device, body, callback));
var commandObj = ulParser.result(body);

process.nextTick(updateCommand.bind(
null,
apiKey,
device,
commandObj.result,
commandObj.command,
constants.COMMAND_STATUS_COMPLETED,
callback));
}
});
};
Expand All @@ -250,6 +260,18 @@ function commandHandler(device, attributes, callback) {
async.series(attributes.map(generateCommandExecution.bind(null, apiKey, device)), function(error) {
if (error) {
logger.error('Error handling incoming command for device [%s]', device.id);

updateCommand(
apiKey,
device,
error.message,
error.command,
constants.COMMAND_STATUS_ERROR,
function(error) {
if (error) {
logger.error('Error updating error information for device [%s]', device.id);
}
});
} else {
logger.debug('Incoming command for device [%s]', device.id);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ module.exports = {
this.message = 'Some of the mandatory params weren\'t found in the request: ' + JSON.stringify(paramList);
this.code = 400;
},
HTTPCommandResponseError: function(code, error) {
HTTPCommandResponseError: function(code, error, command) {
this.command = command;
this.name = 'HTTP_COMMAND_RESPONSE_ERROR';
this.message = 'There was an error in the response of a device to a command [' + code + ' ]:' + error;
this.code = 400;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "iotagent-ul",
"description": "IoT Agent for the Ultrlight 2.0 protocol",
"version": "1.1.5",
"version": "1.1.6",
"homepage": "https://github.com/dmoranj/iotagent-ul",
"author": {
"name": "Daniel Moran",
Expand Down
19 changes: 19 additions & 0 deletions test/contextRequests/updateCommandWrongEndpoint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"updateAction": "UPDATE",
"contextElements": [
{
"id": "Wrong MQTT Device",
"type": "AnMQTTDevice",
"isPattern": "false",
"attributes": [
{
"name": "PING",
"type": "command",
"value": {
"data": "22"
}
}
]
}
]
}
22 changes: 22 additions & 0 deletions test/contextRequests/updateStatusError.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"contextElements": [
{
"type": "AnMQTTDevice",
"isPattern": "false",
"id": "Wrong MQTT Device",
"attributes": [
{
"name": "PING_status",
"type": "commandStatus",
"value": "ERROR"
},
{
"name": "PING_info",
"type": "commandResult",
"value": "There was an error in the response of a device to a command [ ]:Error: getaddrinfo ENOTFOUND unexistent.com unexistent.com:80"
}
]
}
],
"updateAction": "UPDATE"
}
19 changes: 19 additions & 0 deletions test/deviceProvisioning/provisionCommandWrongEndpoint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"devices": [
{
"device_id": "MQTT_WRONG",
"entity_name": "Wrong MQTT Device",
"entity_type": "AnMQTTDevice",
"timezone": "America/Santiago",
"protocol": "HTTP_UL",
"transport": "HTTP",
"endpoint": "http://unexistent.com/command",
"commands": [
{
"name": "PING",
"type": "command"
}
]
}
]
}
75 changes: 75 additions & 0 deletions test/unit/commandsHTTP-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,79 @@ describe('HTTP Transport binding: commands', function() {
});
});
});

describe('When a command arrive with a wrong endpoint', function() {
var commandOptions = {
url: 'http://localhost:' + config.iota.server.port + '/v1/updateContext',
method: 'POST',
json: utils.readExampleFile('./test/contextRequests/updateCommandWrongEndpoint.json'),
headers: {
'fiware-service': 'smartGondor',
'fiware-servicepath': '/gardens'
}
},
provisionWrongEndpoint = {
url: 'http://localhost:' + config.iota.server.port + '/iot/devices',
method: 'POST',
json: utils.readExampleFile('./test/deviceProvisioning/provisionCommandWrongEndpoint.json'),
headers: {
'fiware-service': 'smartGondor',
'fiware-servicepath': '/gardens'
}
};

beforeEach(function(done) {
nock.cleanAll();

contextBrokerMock = nock('http://10.11.128.16:1026')
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/NGSI9/registerContext')
.reply(200,
utils.readExampleFile('./test/contextAvailabilityResponses/registerIoTAgent1Success.json'));

contextBrokerMock
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/v1/updateContext')
.reply(200, utils.readExampleFile('./test/contextResponses/updateStatus1Success.json'));

contextBrokerMock
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/v1/updateContext')
.reply(200, utils.readExampleFile('./test/contextResponses/updateStatus1Success.json'));

contextBrokerMock
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/v1/updateContext', function(body) {
return body.contextElements['0'].attributes['0'].value === 'ERROR';
})
.reply(200, utils.readExampleFile('./test/contextResponses/updateStatus2Success.json'));

request(provisionWrongEndpoint, function(error, response, body) {
setTimeout(function() {
done();
}, 50);
});
});

it('should return a 200 OK without errors', function(done) {
request(commandOptions, function(error, response, body) {
should.not.exist(error);
response.statusCode.should.equal(200);
done();
});
});

it('should update the status in the Context Broker', function(done) {
request(commandOptions, function(error, response, body) {
setTimeout(function() {
contextBrokerMock.done();
done();
}, 100);
});
});
});
});
75 changes: 75 additions & 0 deletions test/unit/commandsHttp-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,79 @@ describe('HTTP Transport binding: commands', function() {
});
});
});

describe('When a command arrive with a wrong endpoint', function() {
var commandOptions = {
url: 'http://localhost:' + config.iota.server.port + '/v1/updateContext',
method: 'POST',
json: utils.readExampleFile('./test/contextRequests/updateCommandWrongEndpoint.json'),
headers: {
'fiware-service': 'smartGondor',
'fiware-servicepath': '/gardens'
}
},
provisionWrongEndpoint = {
url: 'http://localhost:' + config.iota.server.port + '/iot/devices',
method: 'POST',
json: utils.readExampleFile('./test/deviceProvisioning/provisionCommandWrongEndpoint.json'),
headers: {
'fiware-service': 'smartGondor',
'fiware-servicepath': '/gardens'
}
};

beforeEach(function(done) {
nock.cleanAll();

contextBrokerMock = nock('http://10.11.128.16:1026')
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/NGSI9/registerContext')
.reply(200,
utils.readExampleFile('./test/contextAvailabilityResponses/registerIoTAgent1Success.json'));

contextBrokerMock
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/v1/updateContext')
.reply(200, utils.readExampleFile('./test/contextResponses/updateStatus1Success.json'));

contextBrokerMock
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/v1/updateContext')
.reply(200, utils.readExampleFile('./test/contextResponses/updateStatus1Success.json'));

contextBrokerMock
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', '/gardens')
.post('/v1/updateContext', function(body) {
return body.contextElements['0'].attributes['0'].value === 'ERROR';
})
.reply(200, utils.readExampleFile('./test/contextResponses/updateStatus2Success.json'));

request(provisionWrongEndpoint, function(error, response, body) {
setTimeout(function() {
done();
}, 50);
});
});

it('should return a 200 OK without errors', function(done) {
request(commandOptions, function(error, response, body) {
should.not.exist(error);
response.statusCode.should.equal(200);
done();
});
});

it('should update the status in the Context Broker', function(done) {
request(commandOptions, function(error, response, body) {
setTimeout(function() {
contextBrokerMock.done();
done();
}, 100);
});
});
});
});

0 comments on commit 04a9e9a

Please sign in to comment.