Multiple DBAAS Redis standalone groups 74/6174/4 1.2.1
authorPetri Ovaska <petri.ovaska@nokia.com>
Mon, 31 May 2021 11:06:32 +0000 (14:06 +0300)
committerPetri Ovaska <petri.ovaska@nokia.com>
Tue, 1 Jun 2021 13:11:54 +0000 (16:11 +0300)
Added support to have one or more Redis standalone DB groups (like
The Redis Sentinel group in previous ece67088 commit). The DB
groups can be used to distribute SDL DB operations to different
standalone DB instances.

Release version 1.2.1

Issue-ID: RIC-699
Change-Id: Ib7da0200298c8c016dee05743b815c07d04baa76
Signed-off-by: Petri Ovaska <petri.ovaska@nokia.com>
15 files changed:
configure.ac
debian/changelog.in
docs/release-notes.rst
include/private/asyncstorageimpl.hpp
include/private/databaseconfiguration.hpp
include/private/databaseconfigurationimpl.hpp
include/private/tst/databaseconfigurationmock.hpp
rpm/sdl.spec.in
src/asyncstorageimpl.cpp
src/configurationreader.cpp
src/databaseconfigurationimpl.cpp
src/redis/asyncdatabasediscovery.cpp
tst/asyncstorageimpl_test.cpp
tst/configurationreader_test.cpp
tst/databaseconfigurationimpl_test.cpp

index 5ad03f7..1943c3c 100644 (file)
@@ -11,7 +11,7 @@
 
 m4_define([SDL_MAJOR], [1])
 m4_define([SDL_MINOR], [2])
-m4_define([SDL_MICRO], [0])
+m4_define([SDL_MICRO], [1])
 
 # SDL ABI version with libtool
 #
@@ -28,7 +28,7 @@ m4_define([SDL_MICRO], [0])
 # Change the numbers just before release.
 
 m4_define([SDL_CURRENT], [2])
-m4_define([SDL_REVISION], [8])
+m4_define([SDL_REVISION], [9])
 m4_define([SDL_AGE], [0])
 
 AC_INIT([shareddatalayer], [SDL_MAJOR.SDL_MINOR.SDL_MICRO], [], [], [https://gerrit.o-ran-sc.org/r/admin/repos/ric-plt/sdl])
index 8ecc598..268fce4 100644 (file)
@@ -1,3 +1,9 @@
+sdl (1.2.1-1) UNRELEASED; urgency=low
+
+  * Multiple DBAAS Redis standalone groups
+
+ -- Petri Ovaska <petri.ovaska@nokia.com>  Mon, 31 May 2021 14:06:32 +0300
+
 sdl (1.2.0-1) UNRELEASED; urgency=low
 
   * Multiple DBAAS Redis Sentinel groups
index ca53e2b..63d7d29 100644 (file)
@@ -29,6 +29,10 @@ This document provides the release notes of the sdl library.
 Version history
 ---------------
 
+[1.2.1] - 2021-05-31
+
+* Multiple DBAAS Redis standalone groups
+
 [1.2.0] - 2021-05-26
 
 * Multiple DBAAS Redis Sentinel groups
index 5999833..006e22e 100644 (file)
@@ -103,6 +103,7 @@ namespace shareddatalayer
         AsyncStorage& getDummyHandler();
 
         void setAsyncRedisStorageHandlers(const std::string& ns);
+        void setAsyncRedisStorageHandlersForCluster(const std::string& ns);
         AsyncStorage& getAsyncRedisStorageHandler(const std::string& ns);
     };
 }
index 56274cb..e8e5b8d 100644 (file)
@@ -40,7 +40,8 @@ namespace shareddatalayer
             REDIS_STANDALONE,
             REDIS_CLUSTER,
             REDIS_SENTINEL,
-            SDL_CLUSTER
+            SDL_STANDALONE_CLUSTER,
+            SDL_SENTINEL_CLUSTER
         };
 
         virtual ~DatabaseConfiguration() = default;
@@ -50,6 +51,7 @@ namespace shareddatalayer
         virtual void checkAndApplySentinelMasterName(const std::string& name) = 0;
         virtual DatabaseConfiguration::DbType getDbType() const = 0;
         virtual DatabaseConfiguration::Addresses getServerAddresses() const = 0;
+        virtual DatabaseConfiguration::Addresses getServerAddresses(const boost::optional<std::size_t>& addressIndex) const = 0;
         virtual DatabaseConfiguration::Addresses getDefaultServerAddresses() const = 0;
         virtual boost::optional<HostAndPort> getSentinelAddress() const = 0; // Optional return value, because empty HostAndPort can't be created.
         virtual boost::optional<HostAndPort> getSentinelAddress(const boost::optional<std::size_t>& addressIndex) const = 0;
index c499d5a..955b292 100644 (file)
@@ -45,6 +45,8 @@ namespace shareddatalayer
 
         DatabaseConfigurationImpl::Addresses getServerAddresses() const override;
 
+        DatabaseConfigurationImpl::Addresses getServerAddresses(const boost::optional<std::size_t>& addressIndex) const override;
+
         DatabaseConfiguration::Addresses getDefaultServerAddresses() const override;
 
         boost::optional<HostAndPort> getSentinelAddress() const override;
index e4fe0af..8f8d30e 100644 (file)
@@ -37,6 +37,7 @@ namespace shareddatalayer
             MOCK_METHOD1(checkAndApplySentinelMasterName, void(const std::string& name));
             MOCK_CONST_METHOD0(getDbType, DatabaseConfiguration::DbType());
             MOCK_CONST_METHOD0(getServerAddresses, DatabaseConfiguration::Addresses());
+            MOCK_CONST_METHOD1(getServerAddresses, DatabaseConfiguration::Addresses(const boost::optional<std::size_t>& addressIndex));
             MOCK_CONST_METHOD0(getDefaultServerAddresses, DatabaseConfiguration::Addresses());
             MOCK_CONST_METHOD0(isEmpty, bool());
             MOCK_CONST_METHOD0(getSentinelAddress, boost::optional<HostAndPort>());
index ed49ad7..46197cb 100755 (executable)
@@ -1,5 +1,5 @@
 Name:     sdl
-Version:  1.2.0
+Version:  1.2.1
 Release:  1%{?dist}
 Summary:  C++ API library for Shared Data Layer clients
 
@@ -50,6 +50,9 @@ rm -f %{buildroot}%{_libdir}/lib*.*a
 %{_includedir}/sdl
 
 %changelog
+* Mon May 31 2021 Petri Ovaska <petri.ovaska@nokia.com> - 1.2.1-1
+- Multiple DBAAS Redis standalone groups
+
 * Wed May 26 2021 Petri Ovaska <petri.ovaska@nokia.com> - 1.2.0-1
 - Multiple DBAAS Redis Sentinel groups
 - New namespace (--ns) option in sdltool test-get-set -command
index d9478c2..a018c51 100644 (file)
@@ -96,16 +96,17 @@ AsyncStorageImpl::AsyncStorageImpl(std::shared_ptr<Engine> engine,
 {
 }
 
-void AsyncStorageImpl::setAsyncRedisStorageHandlers(const std::string& ns)
+void AsyncStorageImpl::setAsyncRedisStorageHandlersForCluster(const std::string& ns)
 {
-    for (std::size_t i = 0; i < databaseConfiguration->getServerAddresses().size(); i++)
+    static auto serverCount = databaseConfiguration->getServerAddresses().size();
+    for (std::size_t addrIndex = 0; addrIndex < serverCount; addrIndex++)
     {
         auto redisHandler = std::make_shared<AsyncRedisStorage>(engine,
                                                                 asyncDatabaseDiscoveryCreator(
                                                                         engine,
                                                                         ns,
                                                                         std::ref(*databaseConfiguration),
-                                                                        i,
+                                                                        addrIndex,
                                                                         logger),
                                                                 publisherId,
                                                                 namespaceConfigurations,
@@ -114,10 +115,32 @@ void AsyncStorageImpl::setAsyncRedisStorageHandlers(const std::string& ns)
     }
 }
 
+void AsyncStorageImpl::setAsyncRedisStorageHandlers(const std::string& ns)
+{
+    if (DatabaseConfiguration::DbType::SDL_STANDALONE_CLUSTER == databaseConfiguration->getDbType() ||
+        DatabaseConfiguration::DbType::SDL_SENTINEL_CLUSTER == databaseConfiguration->getDbType())
+    {
+            setAsyncRedisStorageHandlersForCluster(ns);
+            return;
+    }
+    auto redisHandler = std::make_shared<AsyncRedisStorage>(engine,
+                                                            asyncDatabaseDiscoveryCreator(
+                                                                    engine,
+                                                                    ns,
+                                                                    std::ref(*databaseConfiguration),
+                                                                    boost::none,
+                                                                    logger),
+                                                            publisherId,
+                                                            namespaceConfigurations,
+                                                            logger);
+    asyncStorages.push_back(redisHandler);
+}
+
 AsyncStorage& AsyncStorageImpl::getAsyncRedisStorageHandler(const std::string& ns)
 {
     std::size_t handlerIndex{0};
-    if (DatabaseConfiguration::DbType::SDL_CLUSTER == databaseConfiguration->getDbType())
+    if (DatabaseConfiguration::DbType::SDL_STANDALONE_CLUSTER == databaseConfiguration->getDbType() ||
+        DatabaseConfiguration::DbType::SDL_SENTINEL_CLUSTER == databaseConfiguration->getDbType())
         handlerIndex = getClusterHashIndex(ns, databaseConfiguration->getServerAddresses().size());
     return *asyncStorages.at(handlerIndex);
 }
@@ -125,7 +148,6 @@ AsyncStorage& AsyncStorageImpl::getAsyncRedisStorageHandler(const std::string& n
 AsyncStorage& AsyncStorageImpl::getRedisHandler(const std::string& ns)
 {
 #if HAVE_REDIS
-    auto serverAddresses(databaseConfiguration->getServerAddresses());
     if (asyncStorages.empty())
             setAsyncRedisStorageHandlers(ns);
 
index 18945b6..1870a87 100644 (file)
@@ -195,6 +195,19 @@ namespace
         for (const auto &namespaceConfigurationMapItem : namespaceConfigurationMap )
             parseNsConfiguration(namespaceConfigurations, namespaceConfigurationMapItem.first, namespaceConfigurationMapItem.second.first, namespaceConfigurationMapItem.second.second);
     }
+
+    void appendDBPortToAddrList(std::string& addresses, const std::string& port)
+    {
+        size_t base(0);
+        auto pos = addresses.find(',', base);
+        while (std::string::npos != pos)
+        {
+            addresses.insert(pos, ":" + port);
+            base = pos + 2 + port.size();
+            pos = addresses.find(',', base);
+        }
+        addresses.append(":" + port);
+    }
 }
 
 ConfigurationReader::ConfigurationReader(std::shared_ptr<Logger> logger):
@@ -306,24 +319,44 @@ void ConfigurationReader::readDatabaseConfiguration(DatabaseConfiguration& datab
         if (sourceForDatabaseConfiguration == dbHostEnvVariableName)
         {
             // NOTE: Redis cluster is not currently configurable via environment variables.
-            if (sentinelPortEnvVariableValue.empty())
+            std::string dbHostAddrs;
+            if (!dbHostEnvVariableValue.empty() && sentinelPortEnvVariableValue.empty() && dbClusterAddrListEnvVariableValue.empty())
             {
                 validateAndSetDbType("redis-standalone", databaseConfiguration, sourceForDatabaseConfiguration);
-                if (dbPortEnvVariableValue.empty())
-                    parseDatabaseServersConfigurationFromString(databaseConfiguration, dbHostEnvVariableValue, sourceForDatabaseConfiguration);
-                else
-                    parseDatabaseServersConfigurationFromString(databaseConfiguration, dbHostEnvVariableValue + ":" + dbPortEnvVariableValue, 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
             {
-                if (dbClusterAddrListEnvVariableValue.empty())
-                    validateAndSetDbType("redis-sentinel", databaseConfiguration, sourceForDatabaseConfiguration);
-                else {
-                    validateAndSetDbType("sdl-cluster", databaseConfiguration, sourceForDatabaseConfiguration);
-                    parseDatabaseServersConfigurationFromString(databaseConfiguration,
-                                                                dbClusterAddrListEnvVariableValue,
-                                                                dbClusterAddrListEnvVariableName);
-                }
+                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.checkAndApplySentinelAddress(dbHostEnvVariableValue + ":" + sentinelPortEnvVariableValue);
                 databaseConfiguration.checkAndApplySentinelMasterName(sentinelMasterNameEnvVariableValue);
             }
index 211c537..4ee548f 100644 (file)
@@ -54,8 +54,10 @@ void DatabaseConfigurationImpl::checkAndApplyDbType(const std::string& type)
         dbType = DatabaseConfiguration::DbType::REDIS_CLUSTER;
     else if (type == "redis-sentinel")
         dbType = DatabaseConfiguration::DbType::REDIS_SENTINEL;
-    else if (type == "sdl-cluster")
-        dbType = DatabaseConfiguration::DbType::SDL_CLUSTER;
+    else if (type == "sdl-standalone-cluster")
+        dbType = DatabaseConfiguration::DbType::SDL_STANDALONE_CLUSTER;
+    else if (type == "sdl-sentinel-cluster")
+        dbType = DatabaseConfiguration::DbType::SDL_SENTINEL_CLUSTER;
     else
         throw DatabaseConfiguration::InvalidDbType(type);
 }
@@ -80,6 +82,14 @@ DatabaseConfiguration::Addresses DatabaseConfigurationImpl::getServerAddresses()
     return serverAddresses;
 }
 
+DatabaseConfiguration::Addresses DatabaseConfigurationImpl::getServerAddresses(const boost::optional<std::size_t>& addressIndex) const
+{
+    if (addressIndex)
+        return { HostAndPort(serverAddresses.at(*addressIndex)) };
+
+    return serverAddresses;
+}
+
 DatabaseConfiguration::Addresses DatabaseConfigurationImpl::getDefaultServerAddresses() const
 {
     return { HostAndPort(getDefaultHost(), htons(DEFAULT_PORT)) };
index 8723def..526757e 100644 (file)
@@ -38,7 +38,7 @@ std::shared_ptr<AsyncDatabaseDiscovery> AsyncDatabaseDiscovery::create(std::shar
                                                                        const boost::optional<std::size_t>& addressIndex,
                                                                        std::shared_ptr<Logger> logger)
 {
-    auto staticAddresses(staticDatabaseConfiguration.getServerAddresses());
+    auto staticAddresses(staticDatabaseConfiguration.getServerAddresses(addressIndex));
 
     if (staticAddresses.empty())
         staticAddresses = staticDatabaseConfiguration.getDefaultServerAddresses();
@@ -59,7 +59,7 @@ std::shared_ptr<AsyncDatabaseDiscovery> AsyncDatabaseDiscovery::create(std::shar
     {
 #if HAVE_HIREDIS
         if (staticDbType == DatabaseConfiguration::DbType::REDIS_SENTINEL ||
-            staticDbType == DatabaseConfiguration::DbType::SDL_CLUSTER)
+            staticDbType == DatabaseConfiguration::DbType::SDL_SENTINEL_CLUSTER)
         {
             auto sentinelAddress(staticDatabaseConfiguration.getSentinelAddress(addressIndex));
             if (sentinelAddress)
index 8fd2147..d1b3649 100644 (file)
@@ -148,7 +148,7 @@ TEST_F(AsyncStorageImplTest, CorrectHandlerIsUsedBasedOnConfiguration)
 TEST_F(AsyncStorageImplTest, CorrectSdlClusterHandlerIsUsedBasedOnConfiguration)
 {
     expectNamespaceConfigurationIsDbBackendUseEnabled_returnTrue();
-    dummyDatabaseConfiguration->checkAndApplyDbType("sdl-cluster");
+    dummyDatabaseConfiguration->checkAndApplyDbType("sdl-sentinel-cluster");
     AsyncStorage& returnedHandler = asyncStorageImpl->getOperationHandler(ns);
     EXPECT_EQ(typeid(AsyncRedisStorage&), typeid(returnedHandler));
 }
index 4e730f0..55db2fc 100644 (file)
@@ -62,6 +62,12 @@ namespace
             EXPECT_CALL(databaseConfigurationMock, checkAndApplyDbType(type));
         }
 
+        void expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType type)
+        {
+            EXPECT_CALL(databaseConfigurationMock, getDbType())
+                    .WillOnce(Return(type));
+        }
+
         void expectDBServerAddressConfigurationCheckAndApply(const std::string& address)
         {
             EXPECT_CALL(databaseConfigurationMock, checkAndApplyServerAddress(address));
@@ -763,13 +769,15 @@ public:
     {
     }
 
-    void readEnvironmentConfigurationAndExpectConfigurationErrorException()
+    void readEnvironmentConfigurationAndExpectConfigurationErrorException(const std::string&  msg,
+                                                                          bool expectCall)
     {
         std::ostringstream os;
-        os << "Configuration error in " << someKnownInputSource << ": some error";
+        os << "Configuration error in " << someKnownInputSource << ": " << msg;
 
-        EXPECT_CALL(databaseConfigurationMock, checkAndApplyDbType(_))
-            .WillOnce(Throw(Exception("some error")));
+        if (expectCall)
+            EXPECT_CALL(databaseConfigurationMock, checkAndApplyDbType(_))
+                .WillOnce(Throw(Exception("some error")));
 
         EXPECT_THROW( {
             try
@@ -806,6 +814,7 @@ TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationCanOv
 
     expectDbTypeConfigurationCheckAndApply("redis-standalone");
     expectDBServerAddressConfigurationCheckAndApply("unknownAddress.local:12345");
+    expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::REDIS_STANDALONE);
     initializeReaderWithSDLconfigFileDirectory();
     configurationReader->readConfigurationFromInputStream(is);
     configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
@@ -823,6 +832,7 @@ TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationWitho
 
     expectDbTypeConfigurationCheckAndApply("redis-standalone");
     expectDBServerAddressConfigurationCheckAndApply("server.local");
+    expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::REDIS_STANDALONE);
     initializeReaderWithoutDirectories();
     configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
 }
@@ -830,13 +840,14 @@ TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationWitho
 TEST_F(ConfigurationReaderEnvironmentVariableTest, EmptyEnvironmentVariableThrows)
 {
     dbHostEnvVariableValue = "";
-    readEnvironmentConfigurationAndExpectConfigurationErrorException();
+    readEnvironmentConfigurationAndExpectConfigurationErrorException("Missing environment variable configuration!",
+                                                                      false);
 }
 
 TEST_F(ConfigurationReaderEnvironmentVariableTest, IllegalCharacterInEnvironmentVariableThrows)
 {
     dbHostEnvVariableValue = "@";
-    readEnvironmentConfigurationAndExpectConfigurationErrorException();
+    readEnvironmentConfigurationAndExpectConfigurationErrorException("some error", true);
 }
 
 TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationAcceptIPv6Address)
@@ -851,6 +862,7 @@ TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationAccep
 
     expectDbTypeConfigurationCheckAndApply("redis-standalone");
     expectDBServerAddressConfigurationCheckAndApply("[2001::123]:12345");
+    expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::REDIS_STANDALONE);
     initializeReaderWithoutDirectories();
     configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
 }
@@ -869,6 +881,8 @@ TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationWithS
     expectGetEnvironmentString(nullptr); //DB_CLUSTER_ENV_VAR_NAME
 
     expectDbTypeConfigurationCheckAndApply("redis-sentinel");
+    expectDBServerAddressConfigurationCheckAndApply("sentinelAddress.local:1111");
+    expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::REDIS_SENTINEL);
     expectSentinelAddressConfigurationCheckAndApply("sentinelAddress.local:2222");
     expectSentinelMasterNameConfigurationCheckAndApply(sentinelMasterNameEnvVariableValue);
     initializeReaderWithoutDirectories();
@@ -880,8 +894,7 @@ TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationWithS
     InSequence dummy;
     dbHostEnvVariableValue = "address-0.local";
     expectGetEnvironmentString(dbHostEnvVariableValue.c_str());
-    dbPortEnvVariableValue = "1111";
-    expectGetEnvironmentString(dbPortEnvVariableValue.c_str());
+    expectGetEnvironmentString(nullptr); //DB_PORT_ENV_VAR_NAME
     sentinelPortEnvVariableValue = "2222";
     expectGetEnvironmentString(sentinelPortEnvVariableValue.c_str());
     sentinelMasterNameEnvVariableValue = "mymaster";
@@ -889,12 +902,54 @@ TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationWithS
     dbClusterAddrListEnvVariableValue = "address-0.local,address-1.local,address-2.local";
     expectGetEnvironmentString(dbClusterAddrListEnvVariableValue.c_str());
 
-    expectDbTypeConfigurationCheckAndApply("sdl-cluster");
+    expectDbTypeConfigurationCheckAndApply("sdl-sentinel-cluster");
     expectDBServerAddressConfigurationCheckAndApply("address-0.local");
     expectDBServerAddressConfigurationCheckAndApply("address-1.local");
     expectDBServerAddressConfigurationCheckAndApply("address-2.local");
+    expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::SDL_SENTINEL_CLUSTER);
     expectSentinelAddressConfigurationCheckAndApply("address-0.local:2222");
     expectSentinelMasterNameConfigurationCheckAndApply(sentinelMasterNameEnvVariableValue);
     initializeReaderWithoutDirectories();
     configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
 }
+
+TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationWithoutSentinelAndWithClusterConfiguration)
+{
+    InSequence dummy;
+    dbHostEnvVariableValue = "address-0.local";
+    expectGetEnvironmentString(dbHostEnvVariableValue.c_str());
+    expectGetEnvironmentString(nullptr); //DB_PORT_ENV_VAR_NAME
+    expectGetEnvironmentString(nullptr); //SENTINEL_PORT_ENV_VAR_NAME
+    expectGetEnvironmentString(nullptr); //SENTINEL_MASTER_NAME_ENV_VAR_NAME
+    dbClusterAddrListEnvVariableValue = "address-0.local,address-1.local,address-2.local";
+    expectGetEnvironmentString(dbClusterAddrListEnvVariableValue.c_str());
+
+    expectDbTypeConfigurationCheckAndApply("sdl-standalone-cluster");
+    expectDBServerAddressConfigurationCheckAndApply("address-0.local");
+    expectDBServerAddressConfigurationCheckAndApply("address-1.local");
+    expectDBServerAddressConfigurationCheckAndApply("address-2.local");
+    expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::SDL_STANDALONE_CLUSTER);
+    initializeReaderWithoutDirectories();
+    configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
+}
+
+TEST_F(ConfigurationReaderEnvironmentVariableTest, EnvironmentConfigurationWithoutSentinelAndWithClusterConfigurationAndDbPort)
+{
+    InSequence dummy;
+    dbHostEnvVariableValue = "address-0.local";
+    expectGetEnvironmentString(dbHostEnvVariableValue.c_str());
+    dbPortEnvVariableValue = "1111";
+    expectGetEnvironmentString(dbPortEnvVariableValue.c_str());
+    expectGetEnvironmentString(nullptr); //SENTINEL_PORT_ENV_VAR_NAME
+    expectGetEnvironmentString(nullptr); //SENTINEL_MASTER_NAME_ENV_VAR_NAME
+    dbClusterAddrListEnvVariableValue = "address-0.local,address-1.local,address-2.local";
+    expectGetEnvironmentString(dbClusterAddrListEnvVariableValue.c_str());
+
+    expectDbTypeConfigurationCheckAndApply("sdl-standalone-cluster");
+    expectDBServerAddressConfigurationCheckAndApply("address-0.local:1111");
+    expectDBServerAddressConfigurationCheckAndApply("address-1.local:1111");
+    expectDBServerAddressConfigurationCheckAndApply("address-2.local:1111");
+    expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::SDL_STANDALONE_CLUSTER);
+    initializeReaderWithoutDirectories();
+    configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
+}
index 5a5356c..008d564 100644 (file)
@@ -83,11 +83,18 @@ TEST_F(DatabaseConfigurationImplTest, CanApplyRedisSentinelDbTypeStringAndReturn
     EXPECT_EQ(DatabaseConfiguration::DbType::REDIS_SENTINEL, retDbType);
 }
 
-TEST_F(DatabaseConfigurationImplTest, CanApplySdlClusterDbTypeStringAndReturnType)
+TEST_F(DatabaseConfigurationImplTest, CanApplySdlStandaloneClusterDbTypeStringAndReturnType)
 {
-    databaseConfigurationImpl->checkAndApplyDbType("sdl-cluster");
+    databaseConfigurationImpl->checkAndApplyDbType("sdl-standalone-cluster");
     const auto retDbType(databaseConfigurationImpl->getDbType());
-    EXPECT_EQ(DatabaseConfiguration::DbType::SDL_CLUSTER, retDbType);
+    EXPECT_EQ(DatabaseConfiguration::DbType::SDL_STANDALONE_CLUSTER, retDbType);
+}
+
+TEST_F(DatabaseConfigurationImplTest, CanApplySdlSentinelClusterDbTypeStringAndReturnType)
+{
+    databaseConfigurationImpl->checkAndApplyDbType("sdl-sentinel-cluster");
+    const auto retDbType(databaseConfigurationImpl->getDbType());
+    EXPECT_EQ(DatabaseConfiguration::DbType::SDL_SENTINEL_CLUSTER, retDbType);
 }
 
 TEST_F(DatabaseConfigurationImplTest, CanApplyNewAddressesOneByOneAndReturnAllAddresses)
@@ -102,6 +109,22 @@ TEST_F(DatabaseConfigurationImplTest, CanApplyNewAddressesOneByOneAndReturnAllAd
     EXPECT_EQ(65535U, ntohs(retAddresses.at(1).getPort()));
 }
 
+TEST_F(DatabaseConfigurationImplTest, CanGetAddressesOneByOneWithAddressIndex)
+{
+    databaseConfigurationImpl->checkAndApplyServerAddress("server0.local");
+    databaseConfigurationImpl->checkAndApplyServerAddress("10.20.30.40:65535");
+    const auto addresses(databaseConfigurationImpl->getServerAddresses(boost::none));
+    const auto addresses0(databaseConfigurationImpl->getServerAddresses(0));
+    const auto addresses1(databaseConfigurationImpl->getServerAddresses(1));
+    EXPECT_EQ(2U, addresses.size());
+    EXPECT_EQ(1U, addresses0.size());
+    EXPECT_EQ(1U, addresses1.size());
+    EXPECT_EQ("server0.local", addresses0.at(0).getHost());
+    EXPECT_EQ(6379U, ntohs(addresses0.at(0).getPort()));
+    EXPECT_EQ("10.20.30.40", addresses1.at(0).getHost());
+    EXPECT_EQ(65535U, ntohs(addresses1.at(0).getPort()));
+}
+
 TEST_F(DatabaseConfigurationImplTest, CanThrowIfIllegalDbTypeIsApplied)
 {
     EXPECT_THROW(databaseConfigurationImpl->checkAndApplyDbType("bad_db_type"), DatabaseConfiguration::InvalidDbType);
@@ -148,9 +171,9 @@ TEST_F(DatabaseConfigurationImplTest, CanApplyAndReturnSentinelMasterName)
     EXPECT_EQ("mymaster", databaseConfigurationImpl->getSentinelMasterName());
 }
 
-TEST_F(DatabaseConfigurationImplTest, CanReturnSDLClusterAddress)
+TEST_F(DatabaseConfigurationImplTest, CanReturnSDLSentinelClusterAddress)
 {
-    databaseConfigurationImpl->checkAndApplyDbType("sdl-cluster");
+    databaseConfigurationImpl->checkAndApplyDbType("sdl-sentinel-cluster");
     databaseConfigurationImpl->checkAndApplyServerAddress("cluster-0.local");
     databaseConfigurationImpl->checkAndApplyServerAddress("cluster-1.local");
     databaseConfigurationImpl->checkAndApplyServerAddress("cluster-2.local");