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
#
# 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])
+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
Version history
---------------
+[1.2.1] - 2021-05-31
+
+* Multiple DBAAS Redis standalone groups
+
[1.2.0] - 2021-05-26
* Multiple DBAAS Redis Sentinel groups
AsyncStorage& getDummyHandler();
void setAsyncRedisStorageHandlers(const std::string& ns);
+ void setAsyncRedisStorageHandlersForCluster(const std::string& ns);
AsyncStorage& getAsyncRedisStorageHandler(const std::string& ns);
};
}
REDIS_STANDALONE,
REDIS_CLUSTER,
REDIS_SENTINEL,
- SDL_CLUSTER
+ SDL_STANDALONE_CLUSTER,
+ SDL_SENTINEL_CLUSTER
};
virtual ~DatabaseConfiguration() = default;
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;
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;
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>());
Name: sdl
-Version: 1.2.0
+Version: 1.2.1
Release: 1%{?dist}
Summary: C++ API library for Shared Data Layer clients
%{_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
{
}
-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,
}
}
+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);
}
AsyncStorage& AsyncStorageImpl::getRedisHandler(const std::string& ns)
{
#if HAVE_REDIS
- auto serverAddresses(databaseConfiguration->getServerAddresses());
if (asyncStorages.empty())
setAsyncRedisStorageHandlers(ns);
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):
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);
}
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);
}
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)) };
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();
{
#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)
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));
}
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));
{
}
- 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
expectDbTypeConfigurationCheckAndApply("redis-standalone");
expectDBServerAddressConfigurationCheckAndApply("unknownAddress.local:12345");
+ expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::REDIS_STANDALONE);
initializeReaderWithSDLconfigFileDirectory();
configurationReader->readConfigurationFromInputStream(is);
configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
expectDbTypeConfigurationCheckAndApply("redis-standalone");
expectDBServerAddressConfigurationCheckAndApply("server.local");
+ expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::REDIS_STANDALONE);
initializeReaderWithoutDirectories();
configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
}
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)
expectDbTypeConfigurationCheckAndApply("redis-standalone");
expectDBServerAddressConfigurationCheckAndApply("[2001::123]:12345");
+ expectGetDbTypeAndWillOnceReturn(DatabaseConfiguration::DbType::REDIS_STANDALONE);
initializeReaderWithoutDirectories();
configurationReader->readDatabaseConfiguration(databaseConfigurationMock);
}
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();
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";
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);
+}
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)
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);
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");