• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

telefonicaid / iotagent-node-lib / 22948149498

11 Mar 2026 10:29AM UTC coverage: 79.43% (+0.03%) from 79.404%
22948149498

Pull #1764

github

web-flow
Merge 29812ecc7 into 803e0ad74
Pull Request #1764: Task/add health check to /iot/about /metrics and /ready

2163 of 2908 branches covered (74.38%)

Branch coverage included in aggregate %.

204 of 265 new or added lines in 5 files covered. (76.98%)

1 existing line in 1 file now uncovered.

4166 of 5060 relevant lines covered (82.33%)

279.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.46
/lib/services/common/genericMiddleware.js
1
/*
2
 * Copyright 2016 Telefonica Investigación y Desarrollo, S.A.U
3
 *
4
 * This file is part of fiware-iotagent-lib
5
 *
6
 * fiware-iotagent-lib is free software: you can redistribute it and/or
7
 * modify it under the terms of the GNU Affero General Public License as
8
 * published by the Free Software Foundation, either version 3 of the License,
9
 * or (at your option) any later version.
10
 *
11
 * fiware-iotagent-lib is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 * See the GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public
17
 * License along with fiware-iotagent-lib.
18
 * If not, see http://www.gnu.org/licenses/.
19
 *
20
 * For those usages not covered by the GNU Affero General Public License
21
 * please contact with::daniel.moranjimenez@telefonica.com
22
 */
23

24
const logger = require('logops');
1✔
25
const revalidator = require('revalidator');
1✔
26
const statsRegistry = require('../stats/statsRegistry');
1✔
27
const errors = require('../../errors');
1✔
28
const fillService = require('./domain').fillService;
1✔
29
const config = require('../../commonConfig');
1✔
30
let iotaInformation;
31
let context = {
1✔
32
    op: 'IoTAgentNGSI.GenericMiddlewares'
33
};
34
const { getHealthState } = require('./health');
1✔
35

36
/**
37
 * Express middleware for handling errors in the IoTAs. It extracts the code information to return from the error itself
38
 * returning 500 when no error code has been found.
39
 *
40
 * @param {Object} error        Error object with all the information.
41
 */
42

43
/* eslint-disable-next-line  no-unused-vars */
44
function handleError(error, req, res, next) {
45
    let code = 500;
68✔
46
    context = fillService(context, {
68✔
47
        service: req.headers['fiware-service'],
48
        subservice: req.headers['fiware-servicepath']
49
    });
50
    logger.debug(context, 'Error [%s] handling request: %s', error.name, error.message);
68✔
51

52
    if (error.code && String(error.code).match(/^[2345]\d\d$/)) {
68✔
53
        code = error.code;
52✔
54
    }
55

56
    res.status(code).json({
68✔
57
        name: error.name,
58
        message: error.message
59
    });
60
}
61

62
/**
63
 *  Express middleware for tracing the complete request arriving to the IoTA in debug mode.
64
 */
65
function traceRequest(req, res, next) {
66
    context = fillService(context, {
×
67
        service: req.headers['fiware-service'],
68
        subservice: req.headers['fiware-servicepath']
69
    });
70
    logger.debug(context, 'Request for path [%s] query [%j] from [%s]', req.path, req.query, req.get('host'));
×
71

72
    if (req.is('json') || req.is('application/ld+json')) {
×
73
        logger.debug(context, 'Body:\n\n%s\n\n', JSON.stringify(req.body, null, 4));
×
74
    }
75

76
    next();
×
77
}
78

79
/**
80
 * Changes the log level to the one specified in the request.
81
 */
82

83
/* eslint-disable-next-line  no-unused-vars */
84
function changeLogLevel(req, res, next) {
85
    const levels = ['INFO', 'ERROR', 'FATAL', 'DEBUG', 'WARN', 'WARNING'];
3✔
86

87
    if (!req.query.level) {
3✔
88
        res.status(400).json({
1✔
89
            error: 'log level missing'
90
        });
91
    } else if (levels.indexOf(req.query.level.toUpperCase()) < 0) {
2✔
92
        res.status(400).json({
1✔
93
            error: 'invalid log level'
94
        });
95
    } else {
96
        let newLevel = req.query.level.toUpperCase();
1✔
97
        if (newLevel === 'WARNING') {
1!
98
            newLevel = 'WARN';
×
99
        }
100
        logger.setLevel(newLevel);
1✔
101
        res.status(200).send('');
1✔
102
    }
103
}
104

105
/**
106
 * Return the current log level.
107
 */
108

109
/* eslint-disable-next-line  no-unused-vars */
110
function getLogLevel(req, res, next) {
111
    res.status(200).json({
2✔
112
        level: logger.getLevel()
113
    });
114
}
115

116
/**
117
 * Ensures the request type is one of the supported ones.
118
 */
119
function ensureType(req, res, next) {
120
    if (req.is('json')) {
60✔
121
        next();
26✔
122
    } else if (req.is('application/ld+json')) {
34!
123
        next();
34✔
124
    } else {
125
        next(new errors.UnsupportedContentType(req.headers['content-type']));
×
126
    }
127
}
128

129
/**
130
 * Generates a Middleware that validates incoming requests based on the JSON Schema template passed as a parameter.
131
 *
132
 * @param {Object} template     JSON Schema template to validate the request.
133
 * @return {Object}            Express middleware used in request validation with the given template.
134
 */
135
function validateJson(template) {
136
    return function validate(req, res, next) {
2,915✔
137
        if (req.is('json') || req.is('application/ld+json')) {
60!
138
            const errorList = revalidator.validate(req.body, template);
60✔
139

140
            if (errorList.valid) {
60✔
141
                next();
59✔
142
            } else {
143
                context = fillService(context, {
1✔
144
                    service: req.headers['fiware-service'],
145
                    subservice: req.headers['fiware-servicepath']
146
                });
147
                logger.debug(context, 'Errors found validating request: %j', errorList);
1✔
148
                next(new errors.BadRequest('Errors found validating request.'));
1✔
149
            }
150
        } else {
151
            next();
×
152
        }
153
    };
154
}
155

156
/**
157
 *  Middleware that returns all the IoTA information stored in the module.
158
 */
159

160
/* eslint-disable-next-line  no-unused-vars */
161
function retrieveVersion(req, res, next) {
162
    res.status(200).json({
4✔
163
        ...iotaInformation,
164
        ...(config.getConfig().healthCheck && { connections: getHealthState() })
8✔
165
    });
166
}
167

168
/* eslint-disable-next-line  no-unused-vars */
169
function getReady(req, res, next) {
170
    statsRegistry.getGlobal('ready', function (err, ready) {
1✔
171
        if (ready) {
1!
NEW
172
            res.status(200).json({});
×
173
        } else {
174
            res.status(503).json({});
1✔
175
        }
176
    });
177
}
178

179
/**
180
 * Stores the information about the IoTAgent for further use in the `retrieveVersion()` middleware.
181
 *
182
 * @param {Object} newIoTAInfo              Object containing all the IoTA Information.
183
 */
184
function setIotaInformation(newIoTAInfo) {
185
    iotaInformation = newIoTAInfo;
812✔
186
}
187

188
exports.handleError = handleError;
1✔
189
exports.traceRequest = traceRequest;
1✔
190
exports.changeLogLevel = changeLogLevel;
1✔
191
exports.ensureType = ensureType;
1✔
192
exports.validateJson = validateJson;
1✔
193
exports.retrieveVersion = retrieveVersion;
1✔
194
exports.getReady = getReady;
1✔
195
exports.setIotaInformation = setIotaInformation;
1✔
196
exports.getLogLevel = getLogLevel;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc