From e4ef00304dc93cb33804070c0c15cb29c9263b2c Mon Sep 17 00:00:00 2001 From: Kengo Nakatsuka Date: Thu, 22 Jun 2023 13:53:16 +0900 Subject: [PATCH] Add -dbURI option --- src/app/contextBroker/contextBroker.cpp | 5 +- src/lib/mongoBackend/MongoGlobal.cpp | 4 +- src/lib/mongoBackend/MongoGlobal.h | 1 + src/lib/mongoDriver/mongoConnectionPool.cpp | 100 ++++++++++++-------- src/lib/mongoDriver/mongoConnectionPool.h | 1 + test/unittests/main_UnitTest.cpp | 4 +- 6 files changed, 74 insertions(+), 41 deletions(-) diff --git a/src/app/contextBroker/contextBroker.cpp b/src/app/contextBroker/contextBroker.cpp index 7e81493ad0..bf81abec8f 100644 --- a/src/app/contextBroker/contextBroker.cpp +++ b/src/app/contextBroker/contextBroker.cpp @@ -148,6 +148,7 @@ char authMech[64]; char authDb[64]; bool dbSSL; bool dbDisableRetryWrites; +char dbURI[1024]; char pidPath[256]; bool harakiri; bool useOnlyIPv4; @@ -276,6 +277,7 @@ bool logDeprecate; #define NGSIV1_AUTOCAST_DESC "automatic cast for number, booleans and dates in NGSIv1 update/create attribute operations" #define MQTT_MAX_AGE_DESC "max time (in minutes) that an unused MQTT connection is kept, default: 60" #define LOG_DEPRECATE_DESC "log deprecation usages as warnings" +#define DBURI_DESC "complete URI for database connection" @@ -295,6 +297,7 @@ PaArgument paArgs[] = { "-port", &port, "PORT", PaInt, PaOpt, 1026, 1, 65535, PORT_DESC }, { "-pidpath", pidPath, "PID_PATH", PaString, PaOpt, PIDPATH, PaNL, PaNL, PIDPATH_DESC }, + { "-dbURI", dbURI, "MONGO_URI", PaString, PaOpt, _i "", PaNL, PaNL, DBURI_DESC }, { "-dbhost", dbHost, "MONGO_HOST", PaString, PaOpt, LOCALHOST, PaNL, PaNL, DBHOST_DESC }, { "-rplSet", rplSet, "MONGO_REPLICA_SET", PaString, PaOpt, _i "", PaNL, PaNL, RPLSET_DESC }, { "-dbuser", user, "MONGO_USER", PaString, PaOpt, _i "", PaNL, PaNL, DBUSER_DESC }, @@ -1213,7 +1216,7 @@ int main(int argC, char* argV[]) alarmMgr.init(relogAlarms); mqttMgr.init(mqttTimeout); orionInit(orionExit, ORION_VERSION, policy, statCounters, statSemWait, statTiming, statNotifQueue, strictIdv1); - mongoInit(dbHost, rplSet, dbName, user, pwd, authMech, authDb, dbSSL, dbDisableRetryWrites, mtenant, dbTimeout, writeConcern, dbPoolSize, statSemWait); + mongoInit(dbURI, dbHost, rplSet, dbName, user, pwd, authMech, authDb, dbSSL, dbDisableRetryWrites, mtenant, dbTimeout, writeConcern, dbPoolSize, statSemWait); metricsMgr.init(!disableMetrics, statSemWait); logSummaryInit(&lsPeriod); diff --git a/src/lib/mongoBackend/MongoGlobal.cpp b/src/lib/mongoBackend/MongoGlobal.cpp index 876a8daeec..189fd2f93c 100644 --- a/src/lib/mongoBackend/MongoGlobal.cpp +++ b/src/lib/mongoBackend/MongoGlobal.cpp @@ -104,6 +104,7 @@ bool mongoMultitenant(void) */ void mongoInit ( + const char* dbURI, const char* dbHost, const char* rplSet, std::string dbName, @@ -123,7 +124,8 @@ void mongoInit // Set the global multitenant variable multitenant = mtenant; - if (orion::mongoConnectionPoolInit(dbHost, + if (orion::mongoConnectionPoolInit(dbURI, + dbHost, dbName.c_str(), rplSet, user, diff --git a/src/lib/mongoBackend/MongoGlobal.h b/src/lib/mongoBackend/MongoGlobal.h index 53d86c6194..9b750e01b5 100644 --- a/src/lib/mongoBackend/MongoGlobal.h +++ b/src/lib/mongoBackend/MongoGlobal.h @@ -71,6 +71,7 @@ extern bool mongoMultitenant(void); */ void mongoInit ( + const char* dbURI, const char* dbHost, const char* rplSet, std::string dbName, diff --git a/src/lib/mongoDriver/mongoConnectionPool.cpp b/src/lib/mongoDriver/mongoConnectionPool.cpp index 281b1c472c..b1ae052654 100644 --- a/src/lib/mongoDriver/mongoConnectionPool.cpp +++ b/src/lib/mongoDriver/mongoConnectionPool.cpp @@ -316,6 +316,7 @@ static void mongoDriverLogger */ static std::string composeMongoUri ( + const char* dbURI, const char* host, const char* rplSet, const char* username, @@ -329,54 +330,76 @@ static std::string composeMongoUri { // Compose the mongoUri, taking into account all information - std::string uri = "mongodb://"; + std::string uri; - // Add auth parameter if included - if (strlen(username) != 0 && strlen(passwd) != 0) + if (strlen(dbURI) != 0) { - uri += username + std::string(":") + passwd + "@"; + const char* pwd = strstr(dbURI, "${PWD}"); + if (pwd != NULL) + { + if (strlen(passwd) == 0) + { + LM_X(1, ("Invalid Command Line Options: -dbURI is used with a password substitution, but no password (-dbpwd) is supplied")); + } + + uri = std::string(dbURI, pwd - dbURI) + passwd + (pwd + 6); + } + else + { + uri = dbURI; + } } + else + { + uri = "mongodb://"; - uri += host + std::string("/"); + // Add auth parameter if included + if (strlen(username) != 0 && strlen(passwd) != 0) + { + uri += username + std::string(":") + passwd + "@"; + } - if (strlen(authDb) != 0) - { - uri += authDb; - } + uri += host + std::string("/"); - // First option prefix is '?' symbol - std::string optionPrefix = "?"; + if (strlen(authDb) != 0) + { + uri += authDb; + } - if (strlen(rplSet) != 0) - { - uri += optionPrefix + "replicaSet=" + rplSet; - optionPrefix = "&"; - } + // First option prefix is '?' symbol + std::string optionPrefix = "?"; - if (strlen(mechanism) != 0) - { - uri += optionPrefix + "authMechanism=" + mechanism; - optionPrefix = "&"; - } + if (strlen(rplSet) != 0) + { + uri += optionPrefix + "replicaSet=" + rplSet; + optionPrefix = "&"; + } - if (dbSSL) - { - uri += optionPrefix + "tls=true&tlsAllowInvalidCertificates=true"; - optionPrefix = "&"; - } + if (strlen(mechanism) != 0) + { + uri += optionPrefix + "authMechanism=" + mechanism; + optionPrefix = "&"; + } - if (dbDisableRetryWrites) - { - uri += optionPrefix + "retryWrites=false"; - optionPrefix = "&"; - } + if (dbSSL) + { + uri += optionPrefix + "tls=true&tlsAllowInvalidCertificates=true"; + optionPrefix = "&"; + } - if (timeout > 0) - { - char buf[STRING_SIZE_FOR_LONG]; - i2s(timeout, buf, sizeof(buf)); - uri += optionPrefix + "connectTimeoutMS=" + buf; - optionPrefix = "&"; + if (dbDisableRetryWrites) + { + uri += optionPrefix + "retryWrites=false"; + optionPrefix = "&"; + } + + if (timeout > 0) + { + char buf[STRING_SIZE_FOR_LONG]; + i2s(timeout, buf, sizeof(buf)); + uri += optionPrefix + "connectTimeoutMS=" + buf; + optionPrefix = "&"; + } } LM_T(LmtMongo, ("MongoDB connection URI: '%s'", offuscatePassword(uri, passwd).c_str())); @@ -392,6 +415,7 @@ static std::string composeMongoUri */ int orion::mongoConnectionPoolInit ( + const char* dbURI, const char* host, const char* db, const char* rplSet, @@ -421,7 +445,7 @@ int orion::mongoConnectionPoolInit atexit(shutdownClient); // Set mongo Uri to connect - std::string uri = composeMongoUri(host, rplSet, username, passwd, mechanism, authDb, dbSSL, dbDisableRetryWrites, timeout); + std::string uri = composeMongoUri(dbURI, host, rplSet, username, passwd, mechanism, authDb, dbSSL, dbDisableRetryWrites, timeout); #ifdef UNIT_TEST /* Basically, we are mocking all the DB pool with a single connection. The getMongoConnection() and mongoReleaseConnection() methods diff --git a/src/lib/mongoDriver/mongoConnectionPool.h b/src/lib/mongoDriver/mongoConnectionPool.h index 79ca14c9e3..0dddc183ae 100644 --- a/src/lib/mongoDriver/mongoConnectionPool.h +++ b/src/lib/mongoDriver/mongoConnectionPool.h @@ -46,6 +46,7 @@ extern void mongoVersionGet(int* mayor, int* minor); */ extern int mongoConnectionPoolInit ( + const char* dbURI, const char* host, const char* db, const char* rplSet, diff --git a/test/unittests/main_UnitTest.cpp b/test/unittests/main_UnitTest.cpp index 420f3493b6..7d7b9bc991 100644 --- a/test/unittests/main_UnitTest.cpp +++ b/test/unittests/main_UnitTest.cpp @@ -80,6 +80,7 @@ unsigned long logLineMaxSize = 32 * 1024; bool logDeprecate = false; +char dbURI[1024]; char dbHost[256]; char rplSet[64]; char dbName[64]; @@ -107,6 +108,7 @@ unsigned long fcMaxInterval = 0; */ PaArgument paArgs[] = { + { "-dbURI", dbURI, "DB_URI", PaString, PaOpt, (int64_t) "", PaNL, PaNL, "" }, { "-dbhost", dbHost, "DB_HOST", PaString, PaOpt, (int64_t) "localhost", PaNL, PaNL, "" }, { "-rplSet", rplSet, "RPL_SET", PaString, PaOpt, (int64_t) "", PaNL, PaNL, "" }, { "-dbuser", user, "DB_USER", PaString, PaOpt, (int64_t) "", PaNL, PaNL, "" }, @@ -158,7 +160,7 @@ int main(int argC, char** argV) LM_M(("Init tests")); orionInit(exitFunction, orionUnitTestVersion, SemReadWriteOp, false, false, false, false, false); // Note that disableRetryTries, multitenancy and mutex time stats are disabled for unit test mongo init - mongoInit(dbHost, rplSet, dbName, user, pwd, authMech, authDb, dbSSL, false, false, dbTimeout, writeConcern, dbPoolSize, false); + mongoInit(dbURI, dbHost, rplSet, dbName, user, pwd, authMech, authDb, dbSSL, false, false, dbTimeout, writeConcern, dbPoolSize, false); alarmMgr.init(false); logSummaryInit(&lsPeriod); // setupDatabase(); FIXME #3775: pending on mongo unit test re-enabling