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

return valid results when several status codes #251

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
- Fix: try return valid results when several status codes are returned by iotagents
- Fix: return target error code instead of 500 error code (#167)
81 changes: 66 additions & 15 deletions lib/services/iotaRedirector.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ const _ = require('underscore');
const async = require('async');
const domain = require('../utils/domain');
const fillService = domain.fillService;
var context = {
let context = {
op: 'IoTAManager.Redirector'
};
const error40x = [400, 401, 403, 404];

function guessCollection(body) {
if (body.services) {
Expand Down Expand Up @@ -262,6 +263,9 @@ function createRequests(req, res, next) {
for (let i = 0; i < req.protocolId.length; i++) {
req.requests.push(createRequest(req, req.protocolId[i], req.body));
}
if (req.requests.length === 0) {
logger.warn(context, 'None request was created to be redirected due to not protocolId was found ');
}
}

next();
Expand Down Expand Up @@ -311,13 +315,18 @@ function processRequests(req, res, next) {
)
);
} else if (body && body.length > 0) {
let parsedBody;
let parsedBody = [];
let parseError;

logger.debug(context, 'Response status: %s body: \n%s\n', response.statusCode, body);
try {
parsedBody = JSON.parse(body);
if (response.statusCode === 409) {
parseError = new errors.DuplicateError(parsedBody);
if (error40x.includes(response.statusCode)) {
// avoid a parse body error hides response status code
parsedBody = [];
} else {
parsedBody = JSON.parse(body);
if (response.statusCode === 409) {
parseError = new errors.DuplicateError(parsedBody);
}
}
logger.debug(context, 'Response body from the redirected request parsed: \n\n%j\n', parsedBody);
} catch (e) {
Expand Down Expand Up @@ -356,7 +365,7 @@ function processRequests(req, res, next) {
}

for (let i = 0; i < results.length; i++) {
logger.debug(context, 'results[%s][1] %j ', i, results[i][1]);
logger.debug(context, 'Combining results[%s][1] %j ', i, results[i][1]);

if (results[i][1].count) {
totalCount += results[i][1].count;
Expand Down Expand Up @@ -392,34 +401,76 @@ function processRequests(req, res, next) {
let combinedResult;

if (error) {
logger.error(context, 'The redirection ended up in error: ', error);
logger.error(context, 'The redirection ended up in error: %j', JSON.stringify(error));
next(error);
} else {
logger.debug(context, 'results %j', results);
const statusCodes = _.uniq(results.map(extractStatusCode));

if (statusCodes.length === 1) {
if (req.method === 'POST' || req.method === 'DELETE' || req.method === 'PUT') {
res.status(statusCodes[0]).send();
} else if (results.length >= 1) {
combinedResult = combineResults(results);

const logMsg =
'statusCodes ' +
JSON.stringify(statusCodes) +
' and combinedResults ' +
JSON.stringify(combinedResult) +
', redirecting for ' +
req.method;
if (combinedResult) {
logger.debug(context, logMsg);
res.status(statusCodes[0]).json(combinedResult);
} else {
next(new errors.TargetServerError('No valid replies from any IoTAgent', statusCodes[0]));
logger.warn(context, logMsg);
next(
new errors.TargetServerError(
'No valid replies from any IoTAgent: ' +
JSON.stringify(results) +
' redirecting request ' +
req.method,
statusCodes[0]
)
);
}
} else {
// req.method is GET and results.length = 0
res.status(statusCodes[0]).json({});
}
} else if (statusCodes.length > 1 && results.length >= 1 && req.method === 'GET') {
// check if there some valid statusCodes and then warn and return valid results
combinedResult = combineResults(results);
logger.warn(
context,
'several statusCodes %j and combinedResults %j, redirecting for GET',
statusCodes,
combinedResult
);
if (combinedResult) {
// Get valid result
res.status(statusCodes.sort()[0]).json(combinedResult);
} else {
next(
new errors.TargetServerError(
'No valid replies from any IoTAgent: ' +
JSON.stringify(results) +
' redirecting request ' +
req.method,
statusCodes.sort()[0]
)
);
}
} else {
// statusCodes.length === 0
// statusCodes.length > 1 && (req.method != GET || results.length < 1)
const errorMsg =
'Wrong status code obtained in some of the responses [' +
'Wrong status code ' +
JSON.stringify(statusCodes) +
'] redirecting request';

' obtained in some of the responses [' +
JSON.stringify(results) +
'] redirecting request: ' +
req.method;
logger.error(context, errorMsg);

next(new errors.TargetServerError(errorMsg));
}
}
Expand Down