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

telefonicaid / iotagent-node-lib / 18746791456

23 Oct 2025 11:25AM UTC coverage: 79.305% (+0.004%) from 79.301%
18746791456

Pull #1742

github

web-flow
Merge 6f0ea7b67 into c75a87805
Pull Request #1742: add mongo uri

2046 of 2757 branches covered (74.21%)

Branch coverage included in aggregate %.

37 of 42 new or added lines in 2 files covered. (88.1%)

1 existing line in 1 file now uncovered.

3932 of 4781 relevant lines covered (82.24%)

280.85 hits per line

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

79.17
/lib/model/dbConn.js
1
/*
2
 * Copyright 2014 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
/*
25
 * This module sets up the connection with the mongodb through mongoose. This connection will be used
26
 * in mongoose schemas to persist objects.
27
 */
28

29
const mongoose = require('mongoose');
1✔
30
const config = require('../commonConfig');
1✔
31
const constants = require('../constants');
1✔
32
const alarms = require('../services/common/alarmManagement');
1✔
33
const logger = require('logops');
1✔
34
const errors = require('../errors');
1✔
35
let defaultDb;
36
const DEFAULT_DB_NAME = 'iotagent';
1✔
37
const context = {
1✔
38
    op: 'IoTAgentNGSI.DbConn'
39
};
40

41
function loadModels() {
42
    require('./Device').load();
67✔
43
    require('./Group').load();
67✔
44
    require('./Command').load();
67✔
45
}
46

47
/**
48
 * Creates a new connection to the Mongo DB.
49
 *
50
 * @this Reference to the dbConn module itself.
51
 */
52
function init(host, db, port, options, callback, fullUri = null) {
83✔
53
    let url;
54
    let retries = 0;
83✔
55
    let lastError;
56
    const maxRetries = config.getConfig().mongodb?.retries || constants.DEFAULT_MONGODB_RETRIES;
83✔
57

58
    function addPort(item) {
59
        return `${item}:${port}`;
83✔
60
    }
61

62
    if (fullUri) {
83!
NEW
63
        url = fullUri;
×
64
    } else {
65
        url = 'mongodb://';
83✔
66

67
        if (options.auth) {
83✔
68
            url += `${encodeURIComponent(options.auth.user)}:${encodeURIComponent(options.auth.password)}@`;
3✔
69
        }
70

71
        const hosts = host.split(',').map(addPort).join(',');
83✔
72
        url += `${hosts}/${db}`;
83✔
73

74
        if (options.extraArgs) {
83✔
75
            const query = new URLSearchParams(options.extraArgs).toString();
6✔
76
            if (query) {
6✔
77
                url += `?${query}`;
4✔
78
            }
79
            delete options.extraArgs;
6✔
80
        }
81
    }
82

83
    function connectionAttempt(callback) {
84
        logger.info(context, `Attempting to connect to MongoDB at ${url}. Attempt ${retries + 1}`);
83✔
85

86
        mongoose
83✔
87
            .connect(url, options)
88
            .then(() => {
89
                defaultDb = mongoose.connection;
67✔
90
                logger.info(context, 'Successfully connected to MongoDB.');
67✔
91
                loadModels();
67✔
92
                defaultDb.on('error', function (error) {
67✔
93
                    logger.error(context, 'Mongo Driver error: %j', error);
×
94
                    lastError = error;
×
95
                    alarms.raise(constants.MONGO_ALARM, error);
×
96
                });
97
                defaultDb.on('connecting', () => logger.debug(context, 'Mongo Driver connecting'));
67✔
98
                defaultDb.on('connected', () => logger.debug(context, 'Mongo Driver connected'));
67✔
99
                defaultDb.on('reconnected', () => logger.debug(context, 'Mongo Driver reconnected'));
67✔
100
                defaultDb.on('disconnected', () => logger.debug(context, 'Mongo Driver disconnected'));
67✔
101
                defaultDb.on('reconnectFailed', () => {
67✔
102
                    logger.error(context, 'MONGODB-004: MongoDB connection was lost');
×
103
                    process.exit(1);
×
104
                });
105
                defaultDb.on('disconnecting', () => logger.debug(context, 'Mongo Driver disconnecting'));
67✔
106
                defaultDb.on('open', () => logger.debug(context, 'Mongo Driver open'));
67✔
107
                defaultDb.on('close', () => logger.debug(context, 'Mongo Driver close'));
67✔
108
                callback();
67✔
109
            })
110
            .catch((err) => {
111
                logger.error(context, `MONGODB-001: Error trying to connect to MongoDB: ${err}`);
×
112
                lastError = err;
×
113
                retries++;
×
114
                if (retries < maxRetries) {
×
115
                    const retryTime = config.getConfig().mongodb?.retryTime || constants.DEFAULT_MONGODB_RETRY_TIME;
×
116
                    logger.info(context, `Retrying in ${retryTime} seconds...`);
×
117
                    setTimeout(() => connectionAttempt(callback), retryTime * 1000);
×
118
                } else {
119
                    logger.error(
×
120
                        context,
121
                        'MONGODB-002: Error to connect found after %d attempts: %s',
122
                        retries,
123
                        lastError
124
                    );
125
                    callback(err);
×
126
                }
127
            });
128
    }
129

130
    connectionAttempt(callback);
83✔
131
}
132

133
function configureDb(callback) {
134
    const currentConfig = config.getConfig();
823✔
135

136
    if (currentConfig.deviceRegistry?.type === 'mongodb') {
823✔
137
        const mongoCfg = currentConfig.mongodb;
86✔
138

139
        if (mongoCfg?.uri) {
86!
UNCOV
140
            const options = {};
×
NEW
141
            logger.info(context, `Using full MongoDB URI from configuration`);
×
NEW
142
            init(null, null, null, options, callback, mongoCfg.uri);
×
NEW
143
            return;
×
144
        }
145

146
        if (!mongoCfg?.host) {
86✔
147
            logger.fatal(context, 'MONGODB-003: No host found for MongoDB driver.');
3✔
148
            callback(new errors.BadConfiguration('No host found for MongoDB driver'));
3✔
149
            return;
3✔
150
        }
151

152
        const dbName = mongoCfg.db || DEFAULT_DB_NAME;
83✔
153
        const port = mongoCfg.port || 27017;
83✔
154
        const options = {};
83✔
155

156
        if (mongoCfg.replicaSet) options.replicaSet = mongoCfg.replicaSet;
83✔
157
        if (mongoCfg.ssl) options.ssl = mongoCfg.ssl;
83✔
158
        if (mongoCfg.extraArgs) options.extraArgs = mongoCfg.extraArgs;
83✔
159

160
        if (mongoCfg.user && mongoCfg.password) {
83✔
161
            options.auth = {
3✔
162
                user: mongoCfg.user,
163
                password: mongoCfg.password
164
            };
165
            if (mongoCfg.authSource) {
3✔
166
                options.extraArgs = {
2✔
167
                    ...options.extraArgs,
168
                    authSource: mongoCfg.authSource
169
                };
170
            }
171
        }
172

173
        init(mongoCfg.host, dbName, port, options, callback);
83✔
174
    } else {
175
        callback();
737✔
176
    }
177
}
178

179
exports.configureDb = configureDb;
1✔
180
exports.db = defaultDb;
1✔
181
exports.DEFAULT_DB_NAME = DEFAULT_DB_NAME;
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