diff --git a/common/dbconnector.cpp b/common/dbconnector.cpp index d8015b946..dc080d9b2 100644 --- a/common/dbconnector.cpp +++ b/common/dbconnector.cpp @@ -16,11 +16,17 @@ using namespace std; namespace swss { -void SonicDBConfig::parseDatabaseConfig(const string &file, - std::unordered_map &inst_entry, - std::unordered_map &db_entry, - std::unordered_map &separator_entry) +void SonicDBConfig::initialize(const string &file) { + + SWSS_LOG_ENTER(); + + if (m_init) + { + SWSS_LOG_ERROR("SonicDBConfig already initialized"); + throw runtime_error("SonicDBConfig already initialized"); + } + ifstream i(file); if (i.good()) { @@ -34,7 +40,7 @@ void SonicDBConfig::parseDatabaseConfig(const string &file, string socket = it.value().at("unix_socket_path"); string hostname = it.value().at("hostname"); int port = it.value().at("port"); - inst_entry[instName] = {socket, hostname, port}; + m_inst_info[instName] = {socket, {hostname, port}}; } for (auto it = j["DATABASES"].begin(); it!= j["DATABASES"].end(); it++) @@ -43,12 +49,12 @@ void SonicDBConfig::parseDatabaseConfig(const string &file, string instName = it.value().at("instance"); int dbId = it.value().at("id"); string separator = it.value().at("separator"); - db_entry[dbName] = {instName, dbId, separator}; + m_db_info[dbName] = {instName, dbId, separator}; - separator_entry.emplace(dbId, separator); + m_db_separator.emplace(dbId, separator); } + m_init = true; } - catch (domain_error& e) { SWSS_LOG_ERROR("key doesn't exist in json object, NULL value has no iterator >> %s\n", e.what()); @@ -67,174 +73,32 @@ void SonicDBConfig::parseDatabaseConfig(const string &file, } } -void SonicDBConfig::initializeGlobalConfig(const string &file) -{ - std::string local_file, dir_name, ns_name; - std::unordered_map db_entry; - std::unordered_map inst_entry; - std::unordered_map separator_entry; - - SWSS_LOG_ENTER(); - - if (m_global_init) - { - SWSS_LOG_ERROR("SonicDBConfig Global config is already initialized"); - return; - } - - ifstream i(file); - if (i.good()) - { - local_file = dir_name = std::string(); - - // Get the directory name from the file path given as input. - std::string::size_type pos = file.rfind("/"); - if( pos != std::string::npos) - { - dir_name = file.substr(0,pos+1); - } - - try - { - json j; - i >> j; - - for (auto& element : j["INCLUDES"]) - { - local_file.append(dir_name); - local_file.append(element["include"]); - - if(element["namespace"].empty()) - { - // If database_config.json is already initlized via SonicDBConfig::initialize - // skip initializing it here again. - if(m_init) - { - local_file.clear(); - continue; - } - ns_name = EMPTY_NAMESPACE; - } - else - { - ns_name = element["namespace"]; - } - - parseDatabaseConfig(local_file, inst_entry, db_entry, separator_entry); - m_inst_info[ns_name] = inst_entry; - m_db_info[ns_name] = db_entry; - m_db_separator[ns_name] = separator_entry; - - if(element["namespace"].empty()) - { - // Make regular init also done - m_init = true; - } - - inst_entry.clear(); - db_entry.clear(); - separator_entry.clear(); - local_file.clear(); - } - } - - catch (domain_error& e) - { - SWSS_LOG_ERROR("key doesn't exist in json object, NULL value has no iterator >> %s\n", e.what()); - throw runtime_error("key doesn't exist in json object, NULL value has no iterator >> " + string(e.what())); - } - catch (exception &e) - { - SWSS_LOG_ERROR("Sonic database config file syntax error >> %s\n", e.what()); - throw runtime_error("Sonic database config file syntax error >> " + string(e.what())); - } - } - else - { - SWSS_LOG_ERROR("Sonic database config global file doesn't exist at %s\n", file.c_str()); - } - - // Set it as the global config file is already parsed and init done. - m_global_init = true; -} - -void SonicDBConfig::initialize(const string &file) -{ - std::unordered_map db_entry; - std::unordered_map inst_entry; - std::unordered_map separator_entry; - - SWSS_LOG_ENTER(); - - if (m_init) - { - SWSS_LOG_ERROR("SonicDBConfig already initialized"); - throw runtime_error("SonicDBConfig already initialized"); - } - - parseDatabaseConfig(file, inst_entry, db_entry, separator_entry); - m_inst_info[EMPTY_NAMESPACE] = inst_entry; - m_db_info[EMPTY_NAMESPACE] = db_entry; - m_db_separator[EMPTY_NAMESPACE] = separator_entry; - - // Set it as the config file is already parsed and init done. - m_init = true; -} - -void SonicDBConfig::validateNamespace(const string &nameSpace) -{ - SWSS_LOG_ENTER(); - - // With valid namespace input and database_global.json is not loaded, ask user to initializeGlobalConfig first - if(!nameSpace.empty()) - { - // If global initialization is not done, ask user to initialize global DB Config first. - if (!m_global_init) - { - SWSS_LOG_ERROR("Initialize global DB config first using API SonicDBConfig::initializeGlobalConfig \n"); - throw runtime_error("Initialize global DB config using API SonicDBConfig::initializeGlobalConfig"); - } - - // Check if the namespace is valid, check if this is a key in either of this map - unordered_map>::const_iterator entry = m_inst_info.find(nameSpace); - if (entry == m_inst_info.end()) - { - SWSS_LOG_ERROR("Namespace %s is not a valid namespace name in config file\n", nameSpace.c_str()); - throw runtime_error("Namespace " + nameSpace + " is not a valid namespace name in config file"); - } - } -} - -string SonicDBConfig::getDbInst(const string &dbName, const string &nameSpace) +string SonicDBConfig::getDbInst(const string &dbName) { if (!m_init) - initialize(DEFAULT_SONIC_DB_CONFIG_FILE); - validateNamespace(nameSpace); - return m_db_info[nameSpace].at(dbName).instName; + initialize(); + return m_db_info.at(dbName).instName; } -int SonicDBConfig::getDbId(const string &dbName, const string &nameSpace) +int SonicDBConfig::getDbId(const string &dbName) { if (!m_init) - initialize(DEFAULT_SONIC_DB_CONFIG_FILE); - validateNamespace(nameSpace); - return m_db_info[nameSpace].at(dbName).dbId; + initialize(); + return m_db_info.at(dbName).dbId; } -string SonicDBConfig::getSeparator(const string &dbName, const string &nameSpace) +string SonicDBConfig::getSeparator(const string &dbName) { if (!m_init) - initialize(DEFAULT_SONIC_DB_CONFIG_FILE); - validateNamespace(nameSpace); - return m_db_info[nameSpace].at(dbName).separator; + initialize(); + return m_db_info.at(dbName).separator; } -string SonicDBConfig::getSeparator(int dbId, const string &nameSpace) +string SonicDBConfig::getSeparator(int dbId) { if (!m_init) - initialize(DEFAULT_SONIC_DB_CONFIG_FILE); - validateNamespace(nameSpace); - return m_db_separator[nameSpace].at(dbId); + initialize(); + return m_db_separator.at(dbId); } string SonicDBConfig::getSeparator(const DBConnector* db) @@ -245,64 +109,42 @@ string SonicDBConfig::getSeparator(const DBConnector* db) } string dbName = db->getDbName(); - string nameSpace = db->getNamespace(); if (dbName.empty()) { - return getSeparator(db->getDbId(), nameSpace); + return getSeparator(db->getDbId()); } else { - return getSeparator(dbName, nameSpace); + return getSeparator(dbName); } } -string SonicDBConfig::getDbSock(const string &dbName, const string &nameSpace) +string SonicDBConfig::getDbSock(const string &dbName) { if (!m_init) - initialize(DEFAULT_SONIC_DB_CONFIG_FILE); - validateNamespace(nameSpace); - return m_inst_info[nameSpace].at(getDbInst(dbName)).unixSocketPath; + initialize(); + return m_inst_info.at(getDbInst(dbName)).first; } -string SonicDBConfig::getDbHostname(const string &dbName, const string &nameSpace) +string SonicDBConfig::getDbHostname(const string &dbName) { if (!m_init) - initialize(DEFAULT_SONIC_DB_CONFIG_FILE); - validateNamespace(nameSpace); - return m_inst_info[nameSpace].at(getDbInst(dbName)).hostname; + initialize(); + return m_inst_info.at(getDbInst(dbName)).second.first; } -int SonicDBConfig::getDbPort(const string &dbName, const string &nameSpace) +int SonicDBConfig::getDbPort(const string &dbName) { if (!m_init) - initialize(DEFAULT_SONIC_DB_CONFIG_FILE); - validateNamespace(nameSpace); - return m_inst_info[nameSpace].at(getDbInst(dbName)).port; -} - -vector SonicDBConfig::getNamespaces() -{ - vector list; - - if (!m_global_init) - initializeGlobalConfig(); - - // This API returns back non-empty namespaces. - for (auto it = m_inst_info.cbegin(); it != m_inst_info.cend(); ++it) { - if(!((it->first).empty())) - list.push_back(it->first); - } - - return list; + initialize(); + return m_inst_info.at(getDbInst(dbName)).second.second; } constexpr const char *SonicDBConfig::DEFAULT_SONIC_DB_CONFIG_FILE; -constexpr const char *SonicDBConfig::DEFAULT_SONIC_DB_GLOBAL_CONFIG_FILE; -unordered_map> SonicDBConfig::m_inst_info; -unordered_map> SonicDBConfig::m_db_info; -unordered_map> SonicDBConfig::m_db_separator; +unordered_map>> SonicDBConfig::m_inst_info; +unordered_map SonicDBConfig::m_db_info; +unordered_map SonicDBConfig::m_db_separator; bool SonicDBConfig::m_init = false; -bool SonicDBConfig::m_global_init = false; constexpr const char *DBConnector::DEFAULT_UNIXSOCKET; @@ -322,8 +164,7 @@ DBConnector::~DBConnector() DBConnector::DBConnector(int dbId, const string& hostname, int port, unsigned int timeout) : - m_dbId(dbId), - m_namespace(EMPTY_NAMESPACE) + m_dbId(dbId) { struct timeval tv = {0, (suseconds_t)timeout * 1000}; @@ -340,8 +181,7 @@ DBConnector::DBConnector(int dbId, const string& hostname, int port, } DBConnector::DBConnector(int dbId, const string& unixPath, unsigned int timeout) : - m_dbId(dbId), - m_namespace(EMPTY_NAMESPACE) + m_dbId(dbId) { struct timeval tv = {0, (suseconds_t)timeout * 1000}; @@ -352,31 +192,30 @@ DBConnector::DBConnector(int dbId, const string& unixPath, unsigned int timeout) if (m_conn->err) throw system_error(make_error_code(errc::address_not_available), - "Unable to connect to redis (unix-socket)"); + "Unable to connect to redis (unixs-socket)"); select(this); } -DBConnector::DBConnector(const string& dbName, unsigned int timeout, bool isTcpConn, const string& nameSpace) - : m_dbId(SonicDBConfig::getDbId(dbName, nameSpace)) +DBConnector::DBConnector(const string& dbName, unsigned int timeout, bool isTcpConn) + : m_dbId(SonicDBConfig::getDbId(dbName)) , m_dbName(dbName) - , m_namespace(nameSpace) { struct timeval tv = {0, (suseconds_t)timeout * 1000}; if (timeout) { if (isTcpConn) - m_conn = redisConnectWithTimeout(SonicDBConfig::getDbHostname(dbName, nameSpace).c_str(), SonicDBConfig::getDbPort(dbName, nameSpace), tv); + m_conn = redisConnectWithTimeout(SonicDBConfig::getDbHostname(dbName).c_str(), SonicDBConfig::getDbPort(dbName), tv); else - m_conn = redisConnectUnixWithTimeout(SonicDBConfig::getDbSock(dbName, nameSpace).c_str(), tv); + m_conn = redisConnectUnixWithTimeout(SonicDBConfig::getDbSock(dbName).c_str(), tv); } else { if (isTcpConn) - m_conn = redisConnect(SonicDBConfig::getDbHostname(dbName, nameSpace).c_str(), SonicDBConfig::getDbPort(dbName, nameSpace)); + m_conn = redisConnect(SonicDBConfig::getDbHostname(dbName).c_str(), SonicDBConfig::getDbPort(dbName)); else - m_conn = redisConnectUnix(SonicDBConfig::getDbSock(dbName, nameSpace).c_str()); + m_conn = redisConnectUnix(SonicDBConfig::getDbSock(dbName).c_str()); } if (m_conn->err) @@ -386,12 +225,6 @@ DBConnector::DBConnector(const string& dbName, unsigned int timeout, bool isTcpC select(this); } -DBConnector::DBConnector(const string& dbName, unsigned int timeout, bool isTcpConn) - : DBConnector(dbName, timeout, isTcpConn, EMPTY_NAMESPACE) -{ - // Empty contructor -} - redisContext *DBConnector::getContext() const { return m_conn; @@ -407,15 +240,19 @@ string DBConnector::getDbName() const return m_dbName; } -string DBConnector::getNamespace() const -{ - return m_namespace; -} - DBConnector *DBConnector::newConnector(unsigned int timeout) const { DBConnector *ret; - ret = new DBConnector(getDbName(), timeout, (getContext()->connection_type == REDIS_CONN_TCP), getNamespace()); + if (getContext()->connection_type == REDIS_CONN_TCP) + ret = new DBConnector(getDbId(), + getContext()->tcp.host, + getContext()->tcp.port, + timeout); + else + ret = new DBConnector(getDbId(), + getContext()->unix_sock.path, + timeout); + ret->m_dbName = m_dbName; return ret; } diff --git a/common/dbconnector.h b/common/dbconnector.h index 6431af1e7..62fbbde96 100644 --- a/common/dbconnector.h +++ b/common/dbconnector.h @@ -7,20 +7,11 @@ #include #include -#define EMPTY_NAMESPACE std::string() namespace swss { class DBConnector; -class RedisInstInfo -{ -public: - std::string unixSocketPath; - std::string hostname; - int port; -}; - class SonicDBInfo { public: @@ -33,35 +24,25 @@ class SonicDBConfig { public: static void initialize(const std::string &file = DEFAULT_SONIC_DB_CONFIG_FILE); - static void initializeGlobalConfig(const std::string &file = DEFAULT_SONIC_DB_GLOBAL_CONFIG_FILE); - static void validateNamespace(const std::string &nameSpace); - static std::string getDbInst(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); - static int getDbId(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); - static std::string getSeparator(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); - static std::string getSeparator(int dbId, const std::string &nameSpace = EMPTY_NAMESPACE); + static std::string getDbInst(const std::string &dbName); + static int getDbId(const std::string &dbName); + static std::string getSeparator(const std::string &dbName); + static std::string getSeparator(int dbId); static std::string getSeparator(const DBConnector* db); - static std::string getDbSock(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); - static std::string getDbHostname(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); - static int getDbPort(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); - static std::vector getNamespaces(); + static std::string getDbSock(const std::string &dbName); + static std::string getDbHostname(const std::string &dbName); + static int getDbPort(const std::string &dbName); static bool isInit() { return m_init; }; - static bool isGlobalInit() { return m_global_init; }; private: static constexpr const char *DEFAULT_SONIC_DB_CONFIG_FILE = "/var/run/redis/sonic-db/database_config.json"; - static constexpr const char *DEFAULT_SONIC_DB_GLOBAL_CONFIG_FILE = "/var/run/redis/sonic-db/database_global.json"; - // { namespace { instName, { unix_socket_path, hostname, port } } } - static std::unordered_map> m_inst_info; - // { namespace, { dbName, {instName, dbId, separator} } } - static std::unordered_map> m_db_info; - // { namespace, { dbId, separator } } - static std::unordered_map> m_db_separator; + // { instName, { unix_socket_path, {hostname, port} } } + static std::unordered_map>> m_inst_info; + // { dbName, {instName, dbId} } + static std::unordered_map m_db_info; + // { dbIp, separator } + static std::unordered_map m_db_separator; static bool m_init; - static bool m_global_init; - static void parseDatabaseConfig(const std::string &file, - std::unordered_map &inst_entry, - std::unordered_map &db_entry, - std::unordered_map &separator_entry); }; class DBConnector @@ -79,14 +60,12 @@ class DBConnector DBConnector(int dbId, const std::string &hostname, int port, unsigned int timeout); DBConnector(int dbId, const std::string &unixPath, unsigned int timeout); DBConnector(const std::string &dbName, unsigned int timeout, bool isTcpConn = false); - DBConnector(const std::string &dbName, unsigned int timeout, bool isTcpConn, const std::string &nameSpace); ~DBConnector(); redisContext *getContext() const; int getDbId() const; std::string getDbName() const; - std::string getNamespace() const; static void select(DBConnector *db); @@ -105,7 +84,6 @@ class DBConnector redisContext *m_conn; int m_dbId; std::string m_dbName; - std::string m_namespace; }; } diff --git a/common/redisselect.cpp b/common/redisselect.cpp index 4c76f19f8..465428220 100644 --- a/common/redisselect.cpp +++ b/common/redisselect.cpp @@ -16,15 +16,6 @@ int RedisSelect::getFd() { return m_subscribe->getContext()->fd; } -int RedisSelect::getDbConnectorId() -{ - return m_subscribe->getDbId(); -} - -std::string RedisSelect::getDbNamespace() -{ - return m_subscribe->getNamespace(); -} uint64_t RedisSelect::readData() { diff --git a/common/redisselect.h b/common/redisselect.h index 6c291a4dd..97a70b12b 100644 --- a/common/redisselect.h +++ b/common/redisselect.h @@ -20,8 +20,6 @@ class RedisSelect : public Selectable bool hasCachedData() override; bool initializedWithData() override; void updateAfterRead() override; - int getDbConnectorId() override; - std::string getDbNamespace() override; /* Create a new redisContext, SELECT DB and SUBSCRIBE */ void subscribe(DBConnector* db, const std::string &channelName); diff --git a/common/selectable.h b/common/selectable.h index 7de56685a..268b933c8 100644 --- a/common/selectable.h +++ b/common/selectable.h @@ -58,16 +58,6 @@ class Selectable return m_priority; } - virtual int getDbConnectorId() - { - return 0; - } - - virtual std::string getDbNamespace() - { - return std::string(); - } - private: friend class Select; diff --git a/tests/Makefile.am b/tests/Makefile.am index 9fbf48ead..a059ac792 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,7 +28,6 @@ tests_SOURCES = redis_ut.cpp \ warm_restart_ut.cpp \ redis_multi_db_ut.cpp \ logger_ut.cpp \ - redis_multi_ns_ut.cpp \ fdb_flush.cpp \ main.cpp diff --git a/tests/main.cpp b/tests/main.cpp index 94aa53da8..89c4bdb29 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -7,11 +7,6 @@ using namespace swss; string existing_file = "./tests/redis_multi_db_ut_config/database_config.json"; string nonexisting_file = "./tests/redis_multi_db_ut_config/database_config_nonexisting.json"; -string global_existing_file = "./tests/redis_multi_db_ut_config/database_global.json"; - -#define TEST_DB "APPL_DB" -#define TEST_NAMESPACE "asic0" -#define INVALID_NAMESPACE "invalid" class SwsscommonEnvironment : public ::testing::Environment { public: @@ -37,39 +32,6 @@ class SwsscommonEnvironment : public ::testing::Environment { SonicDBConfig::initialize(existing_file); cout<<"INIT: load local db config file, isInit = "< -#include -#include "gtest/gtest.h" -#include "common/dbconnector.h" -#include "common/json.hpp" -#include - -using namespace std; -using namespace swss; -using json = nlohmann::json; - -extern string global_existing_file; - -TEST(DBConnector, multi_ns_test) -{ - std::string local_file, dir_name, ns_name; - vector namespaces; - vector ns_names; - - // load global config file again, should throw exception with init already done - try - { - cout<<"INIT: loading local config file again"<> g; - - // Get the directory name from the file path given as input. - std::string::size_type pos = global_existing_file.rfind("/"); - dir_name = global_existing_file.substr(0,pos+1); - - for (auto& element : g["INCLUDES"]) - { - local_file.append(dir_name); - local_file.append(element["include"]); - - if(element["namespace"].empty()) - { - ns_name = EMPTY_NAMESPACE; - } - else - { - ns_name = element["namespace"]; - namespaces.push_back(ns_name); - } - - // parse config file - ifstream i(local_file); - - if (i.good()) - { - json j; - i >> j; - unordered_map m_inst_info; - for (auto it = j["INSTANCES"].begin(); it!= j["INSTANCES"].end(); it++) - { - string instName = it.key(); - string socket = it.value().at("unix_socket_path"); - string hostname = it.value().at("hostname"); - int port = it.value().at("port"); - m_inst_info[instName] = {socket, hostname, port}; - } - - for (auto it = j["DATABASES"].begin(); it!= j["DATABASES"].end(); it++) - { - string dbName = it.key(); - string instName = it.value().at("instance"); - int dbId = it.value().at("id"); - cout<<"testing "<