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

telefonicaid / iotagent-json / 21669604017

04 Feb 2026 11:25AM UTC coverage: 78.742%. First build
21669604017

Pull #909

github

web-flow
Merge 1e8dacb86 into a60ac1875
Pull Request #909: catch and log error when wrong file format loading extra jexl tranfor…

521 of 758 branches covered (68.73%)

Branch coverage included in aggregate %.

0 of 4 new or added lines in 1 file covered. (0.0%)

1131 of 1340 relevant lines covered (84.4%)

134.64 hits per line

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

89.04
/lib/configService.js
1
/*
2
 * Copyright 2016 Telefonica Investigación y Desarrollo, S.A.U
3
 *
4
 * This file is part of iotagent-json
5
 *
6
 * iotagent-json 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
 * iotagent-json 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 iotagent-json.
18
 * If not, seehttp://www.gnu.org/licenses/.
19
 *
20
 * For those usages not covered by the GNU Affero General Public License
21
 * please contact with::[contacto@tid.es]
22
 */
23

24
let config = {};
1✔
25
const fs = require('fs');
1✔
26
const path = require('path');
1✔
27
let logger = require('logops');
1✔
28
const iotAgentLib = require('iotagent-node-lib');
1✔
29

30
function anyIsSet(variableSet) {
31
    for (let i = 0; i < variableSet.length; i++) {
792✔
32
        if (process.env[variableSet[i]]) {
8,945✔
33
            return true;
3✔
34
        }
35
    }
36

37
    return false;
789✔
38
}
39

40
/**
41
 * For a parameter pointing to a file, check the file exists
42
 *
43
 * @param {string} path        Path to the file
44
 */
45
function fileExists(path) {
46
    try {
5✔
47
        fs.statSync(path);
5✔
48
        logger.debug(path + ' - File exists.');
5✔
49
    } catch (e) {
50
        logger.fatal(path + ' - File does not exist.');
×
51
        throw Error(path + ' - File does not exist.');
×
52
    }
53
}
54

55
function processEnvironmentVariables() {
56
    const environmentVariables = [
264✔
57
        'IOTA_MQTT_PROTOCOL',
58
        'IOTA_MQTT_HOST',
59
        'IOTA_MQTT_PORT',
60
        'IOTA_MQTT_CA',
61
        'IOTA_MQTT_CERT',
62
        'IOTA_MQTT_KEY',
63
        'IOTA_MQTT_REJECT_UNAUTHORIZED',
64
        'IOTA_MQTT_USERNAME',
65
        'IOTA_MQTT_PASSWORD',
66
        'IOTA_MQTT_QOS',
67
        'IOTA_MQTT_RETAIN',
68
        'IOTA_MQTT_RETRIES',
69
        'IOTA_MQTT_RETRY_TIME',
70
        'IOTA_MQTT_KEEPALIVE',
71
        'IOTA_MQTT_AVOID_LEADING_SLASH',
72
        'IOTA_MQTT_CLEAN',
73
        'IOTA_MQTT_CLIENT_ID',
74
        'IOTA_MQTT_DISABLED',
75
        'IOTA_MQTT_SUBSCRIBE_BATCH_SIZE',
76
        'IOTA_AMQP_HOST',
77
        'IOTA_AMQP_PORT',
78
        'IOTA_AMQP_USERNAME',
79
        'IOTA_AMQP_PASSWORD',
80
        'IOTA_AMQP_EXCHANGE',
81
        'IOTA_AMQP_QUEUE',
82
        'IOTA_AMQP_DURABLE',
83
        'IOTA_AMQP_RETRIES',
84
        'IOTA_AMQP_RETRY_TIME',
85
        'IOTA_AMQP_DISABLED',
86
        'IOTA_HTTP_HOST',
87
        'IOTA_HTTP_PORT',
88
        'IOTA_HTTP_TIMEOUT',
89
        'IOTA_HTTP_KEY',
90
        'IOTA_HTTP_CERT',
91
        'IOTA_CONFIG_RETRIEVAL',
92
        'IOTA_DEFAULT_KEY',
93
        'IOTA_DEFAULT_TRANSPORT',
94
        'IOTA_EXTRA_JEXL_TRANSFORMATIONS_PATH'
95
    ];
96
    const mqttVariables = [
264✔
97
        'IOTA_MQTT_PROTOCOL',
98
        'IOTA_MQTT_HOST',
99
        'IOTA_MQTT_PORT',
100
        'IOTA_MQTT_CA',
101
        'IOTA_MQTT_CERT',
102
        'IOTA_MQTT_KEY',
103
        'IOTA_MQTT_REJECT_UNAUTHORIZED',
104
        'IOTA_MQTT_USERNAME',
105
        'IOTA_MQTT_PASSWORD',
106
        'IOTA_MQTT_QOS',
107
        'IOTA_MQTT_RETAIN',
108
        'IOTA_MQTT_RETRIES',
109
        'IOTA_MQTT_RETRY_TIME',
110
        'IOTA_MQTT_KEEPALIVE',
111
        'IOTA_MQTT_AVOID_LEADING_SLASH',
112
        'IOTA_MQTT_CLEAN',
113
        'IOTA_MQTT_CLIENT_ID',
114
        'IOTA_MQTT_DISABLED',
115
        'IOTA_MQTT_SUBSCRIBE_BATCH_SIZE'
116
    ];
117
    const amqpVariables = [
264✔
118
        'IOTA_AMQP_HOST',
119
        'IOTA_AMQP_PORT',
120
        'IOTA_AMQP_USERNAME',
121
        'IOTA_AMQP_PASSWORD',
122
        'IOTA_AMQP_EXCHANGE',
123
        'IOTA_AMQP_QUEUE',
124
        'IOTA_AMQP_DURABLE',
125
        'IOTA_AMQP_RETRIES',
126
        'IOTA_AMQP_RETRY_TIME',
127
        'IOTA_AMQP_DISABLED'
128
    ];
129
    const httpVariables = ['IOTA_HTTP_HOST', 'IOTA_HTTP_PORT', 'IOTA_HTTP_TIMEOUT', 'IOTA_HTTP_KEY', 'IOTA_HTTP_CERT'];
264✔
130

131
    const protectedVariables = [
264✔
132
        'IOTA_MQTT_KEY',
133
        'IOTA_MQTT_USERNAME',
134
        'IOTA_MQTT_PASSWORD',
135
        'IOTA_AMQP_USERNAME',
136
        'IOTA_AMQP_PASSWORD'
137
    ];
138
    // Substitute Docker Secret Variables where set.
139
    protectedVariables.forEach((key) => {
264✔
140
        iotAgentLib.configModule.getSecretData(key);
1,320✔
141
    });
142
    environmentVariables.forEach((key) => {
264✔
143
        let value = process.env[key];
10,032✔
144
        if (value) {
10,032✔
145
            if (key.endsWith('USERNAME') || key.endsWith('PASSWORD') || key.endsWith('KEY')) {
30✔
146
                value = '********';
6✔
147
            }
148
            logger.info('Setting %s to environment value: %s', key, value);
30✔
149
        }
150
    });
151

152
    if (process.env.IOTA_CONFIG_RETRIEVAL) {
264!
153
        config.configRetrieval = process.env.IOTA_CONFIG_RETRIEVAL;
×
154
    }
155
    if (process.env.IOTA_DEFAULT_KEY) {
264!
156
        config.defaultKey = process.env.IOTA_DEFAULT_KEY;
×
157
    }
158
    if (process.env.IOTA_DEFAULT_TRANSPORT) {
264!
159
        config.defaultTransport = process.env.IOTA_DEFAULT_TRANSPORT;
×
160
    }
161

162
    if (anyIsSet(mqttVariables)) {
264✔
163
        config.mqtt = config.mqtt || {};
1!
164
    }
165

166
    if (process.env.IOTA_MQTT_PROTOCOL) {
264✔
167
        config.mqtt.protocol = process.env.IOTA_MQTT_PROTOCOL;
1✔
168
    }
169

170
    if (process.env.IOTA_MQTT_HOST) {
264✔
171
        config.mqtt.host = process.env.IOTA_MQTT_HOST;
1✔
172
    }
173

174
    if (process.env.IOTA_MQTT_PORT) {
264✔
175
        config.mqtt.port = process.env.IOTA_MQTT_PORT;
1✔
176
    }
177

178
    if (process.env.IOTA_MQTT_CA) {
264✔
179
        fileExists(process.env.IOTA_MQTT_CA);
1✔
180
        config.mqtt.ca = process.env.IOTA_MQTT_CA;
1✔
181
    }
182

183
    if (process.env.IOTA_MQTT_CERT) {
264✔
184
        fileExists(process.env.IOTA_MQTT_CERT);
1✔
185
        config.mqtt.cert = process.env.IOTA_MQTT_CERT;
1✔
186
    }
187

188
    if (process.env.IOTA_MQTT_KEY) {
264✔
189
        fileExists(process.env.IOTA_MQTT_KEY);
1✔
190
        config.mqtt.key = process.env.IOTA_MQTT_KEY;
1✔
191
    }
192

193
    // Since default is true, need to be able accept "false" as
194
    // a valid Environment variable
195
    if (process.env.IOTA_MQTT_REJECT_UNAUTHORIZED !== undefined) {
264✔
196
        config.mqtt.rejectUnauthorized = process.env.IOTA_MQTT_REJECT_UNAUTHORIZED.trim().toLowerCase() === 'true';
1✔
197
    }
198

199
    if (process.env.IOTA_MQTT_USERNAME) {
264✔
200
        config.mqtt.username = process.env.IOTA_MQTT_USERNAME;
1✔
201
    }
202

203
    if (process.env.IOTA_MQTT_PASSWORD) {
264✔
204
        config.mqtt.password = process.env.IOTA_MQTT_PASSWORD;
1✔
205
    }
206

207
    if (process.env.IOTA_MQTT_QOS) {
264✔
208
        config.mqtt.qos = process.env.IOTA_MQTT_QOS;
1✔
209
    }
210

211
    if (process.env.IOTA_MQTT_RETAIN) {
264✔
212
        config.mqtt.retain = process.env.IOTA_MQTT_RETAIN.trim().toLowerCase() === 'true';
1✔
213
    }
214

215
    if (process.env.IOTA_MQTT_RETRIES) {
264✔
216
        config.mqtt.retries = process.env.IOTA_MQTT_RETRIES;
1✔
217
    }
218

219
    if (process.env.IOTA_MQTT_RETRY_TIME) {
264✔
220
        config.mqtt.retryTime = process.env.IOTA_MQTT_RETRY_TIME;
1✔
221
    }
222

223
    if (process.env.IOTA_MQTT_KEEPALIVE) {
264✔
224
        config.mqtt.keepalive = process.env.IOTA_MQTT_KEEPALIVE;
1✔
225
    }
226

227
    if (process.env.IOTA_MQTT_AVOID_LEADING_SLASH) {
264!
228
        config.mqtt.avoidLeadingSlash = process.env.IOTA_MQTT_AVOID_LEADING_SLASH;
×
229
    }
230

231
    if (process.env.IOTA_MQTT_CLEAN) {
264!
232
        config.mqtt.clean = process.env.IOTA_MQTT_CLEAN.trim().toLowerCase() === 'true';
×
233
    }
234

235
    if (process.env.IOTA_MQTT_CLIENT_ID) {
264!
236
        config.mqtt.clientId = process.env.IOTA_MQTT_CLIENT_ID;
×
237
    }
238

239
    if (process.env.IOTA_MQTT_DISABLED && process.env.IOTA_MQTT_DISABLED.trim().toLowerCase() === 'true') {
264✔
240
        config.mqtt.disabled = true;
1✔
241
    }
242

243
    if (process.env.IOTA_MQTT_SUBSCRIBE_BATCH_SIZE) {
264!
244
        config.mqtt.subscribeBatchSize = process.env.IOTA_MQTT_SUBSCRIBE_BATCH_SIZE;
×
245
    }
246

247
    if (anyIsSet(amqpVariables)) {
264✔
248
        config.amqp = config.amqp || {};
1!
249
    }
250

251
    if (process.env.IOTA_AMQP_HOST) {
264✔
252
        config.amqp.host = process.env.IOTA_AMQP_HOST;
1✔
253
    }
254

255
    if (process.env.IOTA_AMQP_PORT) {
264✔
256
        config.amqp.port = process.env.IOTA_AMQP_PORT;
1✔
257
    }
258

259
    if (process.env.IOTA_AMQP_USERNAME) {
264✔
260
        config.amqp.username = process.env.IOTA_AMQP_USERNAME;
1✔
261
    }
262

263
    if (process.env.IOTA_AMQP_PASSWORD) {
264✔
264
        config.amqp.password = process.env.IOTA_AMQP_PASSWORD;
1✔
265
    }
266

267
    if (process.env.IOTA_AMQP_EXCHANGE) {
264✔
268
        config.amqp.exchange = process.env.IOTA_AMQP_EXCHANGE;
1✔
269
    }
270

271
    if (process.env.IOTA_AMQP_QUEUE) {
264✔
272
        config.amqp.queue = process.env.IOTA_AMQP_QUEUE;
1✔
273
    }
274

275
    if (process.env.IOTA_AMQP_DURABLE) {
264✔
276
        config.amqp.options = {};
1✔
277
        config.amqp.options.durable = process.env.IOTA_AMQP_DURABLE.trim().toLowerCase() === 'true';
1✔
278
    }
279

280
    if (process.env.IOTA_AMQP_RETRIES) {
264✔
281
        config.amqp.retries = process.env.IOTA_AMQP_RETRIES;
1✔
282
    }
283

284
    if (process.env.IOTA_AMQP_RETRY_TIME) {
264✔
285
        config.amqp.retryTime = process.env.IOTA_AMQP_RETRY_TIME;
1✔
286
    }
287

288
    if (process.env.IOTA_AMQP_DISABLED && process.env.IOTA_AMQP_DISABLED.trim().toLowerCase() === 'true') {
264✔
289
        config.amqp.disabled = true;
1✔
290
    }
291

292
    if (anyIsSet(httpVariables)) {
264✔
293
        config.http = {};
1✔
294
    }
295

296
    if (process.env.IOTA_HTTP_HOST) {
264✔
297
        config.http.host = process.env.IOTA_HTTP_HOST;
1✔
298
    }
299

300
    if (process.env.IOTA_HTTP_PORT) {
264✔
301
        config.http.port = process.env.IOTA_HTTP_PORT;
1✔
302
    }
303

304
    if (process.env.IOTA_HTTP_TIMEOUT) {
264✔
305
        config.http.timeout = process.env.IOTA_HTTP_TIMEOUT;
1✔
306
    }
307

308
    if (process.env.IOTA_HTTP_KEY) {
264✔
309
        fileExists(process.env.IOTA_HTTP_KEY);
1✔
310
        config.http.key = process.env.IOTA_HTTP_KEY;
1✔
311
    }
312

313
    if (process.env.IOTA_HTTP_CERT) {
264✔
314
        fileExists(process.env.IOTA_HTTP_KEY);
1✔
315
        config.http.cert = process.env.IOTA_HTTP_CERT;
1✔
316
    }
317

318
    if (process.env.IOTA_EXTRA_JEXL_TRANSFORMATIONS_PATH) {
264!
319
        const p = path.resolve(process.env.IOTA_EXTRA_JEXL_TRANSFORMATIONS_PATH);
×
320
        fileExists(p);
×
NEW
321
        try {
×
NEW
322
            const extraJexlTransformations = require(p);
×
NEW
323
            config.extraJexlTransformations = extraJexlTransformations;
×
324
        } catch (err) {
NEW
325
            logger.error(`${p} - Failed to load extra JEXL transformations: ${err.message}`);
×
326
        }
327
    }
328
}
329

330
function setConfig(newConfig) {
331
    config = newConfig;
264✔
332

333
    processEnvironmentVariables();
264✔
334
}
335

336
function getConfig() {
337
    return config;
5,883✔
338
}
339

340
function setLogger(newLogger) {
341
    logger = newLogger;
261✔
342
}
343

344
function getLogger() {
345
    return logger;
13,587✔
346
}
347

348
exports.setConfig = setConfig;
1✔
349
exports.getConfig = getConfig;
1✔
350
exports.setLogger = setLogger;
1✔
351
exports.getLogger = getLogger;
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