Skip to content

Commit

Permalink
Merge pull request #1676 from telefonicaid/task/upgrade_mongoose_8
Browse files Browse the repository at this point in the history
upgrade mongoose from 5 to 8.8.4
  • Loading branch information
GregorioBlazquez authored Dec 16, 2024
2 parents d4184a4 + 144d568 commit 68ac6db
Show file tree
Hide file tree
Showing 12 changed files with 407 additions and 411 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ jobs:
strategy:
matrix:
node-version:
- 14.x
- 16.x
- 18.x
steps:
Expand Down
5 changes: 3 additions & 2 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
- Upgrade express de from 4.19.2 to 4.20.0
- Upgrade mongoose dep from 5.13.20 to 5.13.22
- Upgrade express dep from 4.19.2 to 4.20.0
- Upgrade mongodb devdep from 4.17.1 to 4.17.2
- Upgrade mongoose dep from 5.13.20 to 8.4.4 (solving vulnerability CVE-2024-53900) (#1674)
4 changes: 2 additions & 2 deletions lib/model/Command.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ const Command = new Schema({
creationDate: { type: Date, default: Date.now }
});

function load(db) {
module.exports.model = db.model('Command', Command);
function load() {
module.exports.model = mongoose.model('Command', Command);
module.exports.internalSchema = Command;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/model/Device.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ const Device = new Schema({
payloadType: String
});

function load(db) {
module.exports.model = db.model('Device', Device);
function load() {
module.exports.model = mongoose.model('Device', Device);
module.exports.internalSchema = Device;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/model/Group.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ const Group = new Schema({
payloadType: String
});

function load(db) {
function load() {
Group.index({ apikey: 1, resource: 1 }, { unique: true });
module.exports.model = db.model('Group', Group);
module.exports.model = mongoose.model('Group', Group);
module.exports.internalSchema = Group;
}

Expand Down
165 changes: 53 additions & 112 deletions lib/model/dbConn.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const config = require('../commonConfig');
const constants = require('../constants');
const alarms = require('../services/common/alarmManagement');
const logger = require('logops');
const async = require('async');
const errors = require('../errors');
let defaultDb;
const DEFAULT_DB_NAME = 'iotagent';
Expand All @@ -40,103 +39,62 @@ const context = {
};

function loadModels() {
require('./Device').load(defaultDb);
require('./Group').load(defaultDb);
require('./Command').load(defaultDb);
require('./Device').load();
require('./Group').load();
require('./Command').load();
}

/**
* Creates a new connection to the Mongo DB.
*
* @this Reference to the dbConn module itself.
*/

function init(host, db, port, options, callback) {
/*jshint camelcase:false, validthis:true */
let url;
let retries = 0;
let lastError;
const maxRetries =
(config.getConfig().mongodb && config.getConfig().mongodb.retries) || constants.DEFAULT_MONGODB_RETRIES;
const maxRetries = config.getConfig().mongodb?.retries || constants.DEFAULT_MONGODB_RETRIES;

function addPort(item) {
return item + ':' + port;
}

function commaConcat(previous, current, currentIndex) {
if (currentIndex !== 0) {
previous += ',';
}

previous += current;

return previous;
return `${item}:${port}`;
}

url = 'mongodb://';

if (options.auth) {
url += options.auth.user + ':' + options.auth.password + '@';
url += `${encodeURIComponent(options.auth.user)}:${encodeURIComponent(options.auth.password)}@`;
}

const hosts = host.split(',').map(addPort).reduce(commaConcat, '');

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

if (options.extraArgs) {
if (options.extraArgs instanceof Object && Object.keys(options.extraArgs).length > 0) {
url += '?';
url += Object.entries(options.extraArgs)
.map(function ([k, v]) {
return encodeURIComponent(k) + '=' + encodeURIComponent(v);
})
.join('&');
const query = new URLSearchParams(options.extraArgs).toString();
if (query) {
url += `?${query}`;
}
delete options.extraArgs;
}

/* eslint-disable-next-line no-unused-vars */
function createConnectionHandler(error, results) {
if (defaultDb) {
logger.info(context, 'Successfully connected to MongoDB.');
module.exports.db = defaultDb;
loadModels();
} else {
logger.error(context, 'MONGODB-002: Error found after [%d] attempts: %s', retries, error || lastError);
}

callback(error);
}

function retryCheck() {
return !defaultDb && retries < maxRetries;
}

function connectionAttempt(url, options, callback) {
logger.info(context, 'Attempting to connect to MongoDB instance with url %j. Attempt %d', url, retries);
// FIXME: useNewUrlParser is no longer used in underlying mongodb driver 4.x
// (see https://github.com/mongodb/node-mongodb-native/blob/HEAD/etc/notes/CHANGES_4.0.0.md)
// but not sure if current mongoose version is still using mongodb 3.x internally
// probably mongodb-connectionoptions-test.js needs to be fixed if useNewUrlParser is removed at the end
options.useNewUrlParser = true;
options.useUnifiedTopology = true;
mongoose.set('useCreateIndex', true);
/* eslint-disable-next-line no-unused-vars */
const candidateDb = mongoose.createConnection(url, options, function (error, result) {
if (error) {
logger.error(context, 'MONGODB-001: Error trying to connect to MongoDB: %s', error);
lastError = error;
} else {
defaultDb = candidateDb;
function connectionAttempt(callback) {
logger.info(context, `Attempting to connect to MongoDB at ${url}. Attempt ${retries + 1}`);

mongoose
.connect(url, options)
.then(() => {
defaultDb = mongoose.connection;
logger.info(context, 'Successfully connected to MongoDB.');
loadModels();
defaultDb.on('error', function (error) {
logger.error(context, 'Mongo Driver error: %j', error);
lastError = error;
alarms.raise(constants.MONGO_ALARM, error);
});
/* eslint-disable-next-line no-unused-vars */
defaultDb.on('connecting', function (error) {
logger.debug(context, 'Mongo Driver connecting');
});

defaultDb.on('connected', function () {
logger.debug(context, 'Mongo Driver connected');
});
Expand All @@ -159,77 +117,60 @@ function init(host, db, port, options, callback) {
defaultDb.on('close', function () {
logger.debug(context, 'Mongo Driver close');
});
}

callback();
});
}

function tryCreateConnection(callback) {
const attempt = async.apply(connectionAttempt, url, options, callback);
const seconds =
(config.getConfig().mongodb && config.getConfig().mongodb.retryTime) ||
constants.DEFAULT_MONGODB_RETRY_TIME;

retries++;

if (retries === 1) {
logger.info(context, 'First connection attempt');
attempt();
} else {
logger.info(context, 'Waiting %d seconds before attempting again.', seconds);
setTimeout(attempt, seconds * 1000);
}
callback();
})
.catch((err) => {
logger.error(context, `MONGODB-001: Error trying to connect to MongoDB: ${err}`);
lastError = err;
retries++;
if (retries < maxRetries) {
const retryTime = config.getConfig().mongodb?.retryTime || constants.DEFAULT_MONGODB_RETRY_TIME;
logger.info(context, `Retrying in ${retryTime} seconds...`);
setTimeout(() => connectionAttempt(callback), retryTime * 1000);
} else {
logger.error(
context,
'MONGODB-002: Error to connect found after %d attempts: %s',
retries,
lastError
);
callback(err);
}
});
}

defaultDb = null;
async.whilst(retryCheck, tryCreateConnection, createConnectionHandler);
connectionAttempt(callback);
}

function configureDb(callback) {
/*jshint camelcase:false, validthis:true */
const currentConfig = config.getConfig();

if (currentConfig.deviceRegistry && currentConfig.deviceRegistry.type === 'mongodb') {
if (!currentConfig.mongodb || !currentConfig.mongodb.host) {
if (currentConfig.deviceRegistry?.type === 'mongodb') {
if (!currentConfig.mongodb?.host) {
logger.fatal(context, 'MONGODB-003: No host found for MongoDB driver.');
callback(new errors.BadConfiguration('No host found for MongoDB driver'));
} else {
let dbName = currentConfig.mongodb.db;
const dbName = currentConfig.mongodb.db || DEFAULT_DB_NAME;
const port = currentConfig.mongodb.port || 27017;
const options = {};

if (!currentConfig.mongodb.db) {
dbName = DEFAULT_DB_NAME;
}

if (currentConfig.mongodb.replicaSet) {
options.replicaSet = currentConfig.mongodb.replicaSet;
}

if (currentConfig.mongodb.ssl) {
options.ssl = currentConfig.mongodb.ssl;
}

if (currentConfig.mongodb.extraArgs) {
options.extraArgs = currentConfig.mongodb.extraArgs;
}
if (currentConfig.mongodb.replicaSet) options.replicaSet = currentConfig.mongodb.replicaSet;
if (currentConfig.mongodb.ssl) options.ssl = currentConfig.mongodb.ssl;
if (currentConfig.mongodb.extraArgs) options.extraArgs = currentConfig.mongodb.extraArgs;

if (currentConfig.mongodb.user && currentConfig.mongodb.password) {
options.auth = {};
options.auth.user = currentConfig.mongodb.user;
options.auth.password = currentConfig.mongodb.password;
// authSource only applies if auth is set
options.auth = {
user: currentConfig.mongodb.user,
password: currentConfig.mongodb.password
};
if (currentConfig.mongodb.authSource) {
// Overload extraArgs if it was set
options.extraArgs = {
...options.extraArgs,
authSource: currentConfig.mongodb.authSource
};
}
}

init(config.getConfig().mongodb.host, dbName, port, options, callback);
init(currentConfig.mongodb.host, dbName, port, options, callback);
}
} else {
callback();
Expand Down
Loading

0 comments on commit 68ac6db

Please sign in to comment.