RIC:1060: Change in PTL
[ric-plt/sdl.git] / src / configurationreader.cpp
index 85ab627..2cd707b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2018-2019 Nokia.
+   Copyright (c) 2018-2022 Nokia.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    limitations under the License.
 */
 
+/*
+ * This source code is part of the near-RT RIC (RAN Intelligent Controller)
+ * platform project (RICP).
+*/
+
 #include "private/abort.hpp"
 #include "private/configurationreader.hpp"
 #include <boost/property_tree/json_parser.hpp>
@@ -24,6 +29,7 @@
 #include "private/namespaceconfigurations.hpp"
 #include "private/namespacevalidator.hpp"
 #include "private/system.hpp"
+#include <boost/algorithm/string.hpp>
 
 using namespace shareddatalayer;
 
@@ -190,6 +196,27 @@ namespace
         for (const auto &namespaceConfigurationMapItem : namespaceConfigurationMap )
             parseNsConfiguration(namespaceConfigurations, namespaceConfigurationMapItem.first, namespaceConfigurationMapItem.second.first, namespaceConfigurationMapItem.second.second);
     }
+
+    const std::string DEFAULT_REDIS_PORT("6379");
+
+    void appendDBPortToAddrList(std::string& addresses, const std::string& port)
+    {
+        size_t base(0);
+        std::vector<std::string> portList;
+        boost::split(portList, port, boost::is_any_of(","));
+
+        std::size_t idx(0);
+        auto redisPort((portList.size() > 0 && idx < portList.size()) ? portList.at(idx) : DEFAULT_REDIS_PORT);
+        auto pos = addresses.find(',', base);
+        while (std::string::npos != pos)
+        {
+            addresses.insert(pos, ":" + redisPort);
+            base = pos + 2 + redisPort.size();
+            pos = addresses.find(',', base);
+            idx++;
+        }
+        addresses.append(":" + redisPort);
+    }
 }
 
 ConfigurationReader::ConfigurationReader(std::shared_ptr<Logger> logger):
@@ -200,10 +227,16 @@ ConfigurationReader::ConfigurationReader(std::shared_ptr<Logger> logger):
 ConfigurationReader::ConfigurationReader(const Directories& directories,
                                          System& system,
                                          std::shared_ptr<Logger> logger):
-       dbHostEnvVariableName(DB_HOST_ENV_VAR_NAME),
-       dbHostEnvVariableValue({}),
-       dbPortEnvVariableName(DB_PORT_ENV_VAR_NAME),
-       dbPortEnvVariableValue({}),
+    dbHostEnvVariableName(DB_HOST_ENV_VAR_NAME),
+    dbHostEnvVariableValue({}),
+    dbPortEnvVariableName(DB_PORT_ENV_VAR_NAME),
+    dbPortEnvVariableValue({}),
+    sentinelPortEnvVariableName(SENTINEL_PORT_ENV_VAR_NAME),
+    sentinelPortEnvVariableValue({}),
+    sentinelMasterNameEnvVariableName(SENTINEL_MASTER_NAME_ENV_VAR_NAME),
+    sentinelMasterNameEnvVariableValue({}),
+    dbClusterAddrListEnvVariableName(DB_CLUSTER_ADDR_LIST_ENV_VAR_NAME),
+    dbClusterAddrListEnvVariableValue({}),
     jsonDatabaseConfiguration(boost::none),
     logger(logger)
 {
@@ -215,6 +248,15 @@ ConfigurationReader::ConfigurationReader(const Directories& directories,
         auto envStr = system.getenv(dbPortEnvVariableName.c_str());
         if (envStr)
             dbPortEnvVariableValue = envStr;
+        envStr = system.getenv(sentinelPortEnvVariableName.c_str());
+        if (envStr)
+            sentinelPortEnvVariableValue = envStr;
+        envStr = system.getenv(sentinelMasterNameEnvVariableName.c_str());
+        if (envStr)
+            sentinelMasterNameEnvVariableValue = envStr;
+        envStr = system.getenv(dbClusterAddrListEnvVariableName.c_str());
+        if (envStr)
+            dbClusterAddrListEnvVariableValue = envStr;
     }
 
     readConfigurationFromDirectories(directories);
@@ -285,12 +327,48 @@ void ConfigurationReader::readDatabaseConfiguration(DatabaseConfiguration& datab
     {
         if (sourceForDatabaseConfiguration == dbHostEnvVariableName)
         {
-            // Currently hard coded to redis-standalone, because RIC dbaas does not support Redis cluster configuration.
-               validateAndSetDbType("redis-standalone", databaseConfiguration, sourceForDatabaseConfiguration);
-               if (dbPortEnvVariableValue.empty())
-                       parseDatabaseServersConfigurationFromString(databaseConfiguration, dbHostEnvVariableValue, sourceForDatabaseConfiguration);
-               else
-                       parseDatabaseServersConfigurationFromString(databaseConfiguration, dbHostEnvVariableValue + ":" + dbPortEnvVariableValue, sourceForDatabaseConfiguration);
+            // NOTE: Redis cluster is not currently configurable via environment variables.
+            std::string dbHostAddrs;
+            if (!dbHostEnvVariableValue.empty() && sentinelPortEnvVariableValue.empty() && dbClusterAddrListEnvVariableValue.empty())
+            {
+                validateAndSetDbType("redis-standalone", databaseConfiguration, sourceForDatabaseConfiguration);
+                dbHostAddrs = dbHostEnvVariableValue;
+            }
+            else if (!dbHostEnvVariableValue.empty() && !sentinelPortEnvVariableValue.empty() && dbClusterAddrListEnvVariableValue.empty())
+            {
+                validateAndSetDbType("redis-sentinel", databaseConfiguration, sourceForDatabaseConfiguration);
+                dbHostAddrs = dbHostEnvVariableValue;
+            }
+            else if (sentinelPortEnvVariableValue.empty() && !dbClusterAddrListEnvVariableValue.empty())
+            {
+                validateAndSetDbType("sdl-standalone-cluster", databaseConfiguration, sourceForDatabaseConfiguration);
+                dbHostAddrs = dbClusterAddrListEnvVariableValue;
+            }
+            else if (!sentinelPortEnvVariableValue.empty() && !dbClusterAddrListEnvVariableValue.empty())
+            {
+                validateAndSetDbType("sdl-sentinel-cluster", databaseConfiguration, sourceForDatabaseConfiguration);
+                dbHostAddrs = dbClusterAddrListEnvVariableValue;
+            }
+            else
+            {
+                std::ostringstream os;
+                os << "Configuration error in " << sourceForDatabaseConfiguration << ": "
+                   << "Missing environment variable configuration!";
+                throw Exception(os.str());
+            }
+
+            if (!dbPortEnvVariableValue.empty())
+                appendDBPortToAddrList(dbHostAddrs, dbPortEnvVariableValue);
+            parseDatabaseServersConfigurationFromString(databaseConfiguration,
+                                                        dbHostAddrs,
+                                                        sourceForDatabaseConfiguration);
+            auto dbType = databaseConfiguration.getDbType();
+            if (DatabaseConfiguration::DbType::REDIS_SENTINEL == dbType ||
+                DatabaseConfiguration::DbType::SDL_SENTINEL_CLUSTER == dbType)
+            {
+                databaseConfiguration.checkAndApplySentinelPorts(sentinelPortEnvVariableValue);
+                databaseConfiguration.checkAndApplySentinelMasterNames(sentinelMasterNameEnvVariableValue);
+            }
         }
         else
             parseDatabaseConfigurationTree(databaseConfiguration, jsonDatabaseConfiguration, sourceForDatabaseConfiguration);