Skip to content

Commit 1943e2b

Browse files
authored
Reintroducing PR #364 - DBconnector to support namespaces. (#371)
* Adding back PR#364 * Also changes to allign the dbConnector class here with that of sonic-py-swssdk 1. Ignore if the database_global.json file is not present. 2. validate the namespace before using it.
1 parent 00bcd1d commit 1943e2b

11 files changed

+599
-72
lines changed

common/dbconnector.cpp

+222-59
Large diffs are not rendered by default.

common/dbconnector.h

+35-13
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,20 @@
77
#include <utility>
88

99
#include <hiredis/hiredis.h>
10+
#define EMPTY_NAMESPACE std::string()
1011

1112
namespace swss {
1213

1314
class DBConnector;
1415

16+
class RedisInstInfo
17+
{
18+
public:
19+
std::string unixSocketPath;
20+
std::string hostname;
21+
int port;
22+
};
23+
1524
class SonicDBInfo
1625
{
1726
public:
@@ -24,25 +33,35 @@ class SonicDBConfig
2433
{
2534
public:
2635
static void initialize(const std::string &file = DEFAULT_SONIC_DB_CONFIG_FILE);
27-
static std::string getDbInst(const std::string &dbName);
28-
static int getDbId(const std::string &dbName);
29-
static std::string getSeparator(const std::string &dbName);
30-
static std::string getSeparator(int dbId);
36+
static void initializeGlobalConfig(const std::string &file = DEFAULT_SONIC_DB_GLOBAL_CONFIG_FILE);
37+
static void validateNamespace(const std::string &nameSpace);
38+
static std::string getDbInst(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE);
39+
static int getDbId(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE);
40+
static std::string getSeparator(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE);
41+
static std::string getSeparator(int dbId, const std::string &nameSpace = EMPTY_NAMESPACE);
3142
static std::string getSeparator(const DBConnector* db);
32-
static std::string getDbSock(const std::string &dbName);
33-
static std::string getDbHostname(const std::string &dbName);
34-
static int getDbPort(const std::string &dbName);
43+
static std::string getDbSock(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE);
44+
static std::string getDbHostname(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE);
45+
static int getDbPort(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE);
46+
static std::vector<std::string> getNamespaces();
3547
static bool isInit() { return m_init; };
48+
static bool isGlobalInit() { return m_global_init; };
3649

3750
private:
3851
static constexpr const char *DEFAULT_SONIC_DB_CONFIG_FILE = "/var/run/redis/sonic-db/database_config.json";
39-
// { instName, { unix_socket_path, {hostname, port} } }
40-
static std::unordered_map<std::string, std::pair<std::string, std::pair<std::string, int>>> m_inst_info;
41-
// { dbName, {instName, dbId} }
42-
static std::unordered_map<std::string, SonicDBInfo> m_db_info;
43-
// { dbIp, separator }
44-
static std::unordered_map<int, std::string> m_db_separator;
52+
static constexpr const char *DEFAULT_SONIC_DB_GLOBAL_CONFIG_FILE = "/var/run/redis/sonic-db/database_global.json";
53+
// { namespace { instName, { unix_socket_path, hostname, port } } }
54+
static std::unordered_map<std::string, std::unordered_map<std::string, RedisInstInfo>> m_inst_info;
55+
// { namespace, { dbName, {instName, dbId, separator} } }
56+
static std::unordered_map<std::string, std::unordered_map<std::string, SonicDBInfo>> m_db_info;
57+
// { namespace, { dbId, separator } }
58+
static std::unordered_map<std::string, std::unordered_map<int, std::string>> m_db_separator;
4559
static bool m_init;
60+
static bool m_global_init;
61+
static void parseDatabaseConfig(const std::string &file,
62+
std::unordered_map<std::string, RedisInstInfo> &inst_entry,
63+
std::unordered_map<std::string, SonicDBInfo> &db_entry,
64+
std::unordered_map<int, std::string> &separator_entry);
4665
};
4766

4867
class DBConnector
@@ -60,12 +79,14 @@ class DBConnector
6079
DBConnector(int dbId, const std::string &hostname, int port, unsigned int timeout);
6180
DBConnector(int dbId, const std::string &unixPath, unsigned int timeout);
6281
DBConnector(const std::string &dbName, unsigned int timeout, bool isTcpConn = false);
82+
DBConnector(const std::string &dbName, unsigned int timeout, bool isTcpConn, const std::string &nameSpace);
6383

6484
~DBConnector();
6585

6686
redisContext *getContext() const;
6787
int getDbId() const;
6888
std::string getDbName() const;
89+
std::string getNamespace() const;
6990

7091
static void select(DBConnector *db);
7192

@@ -84,6 +105,7 @@ class DBConnector
84105
redisContext *m_conn;
85106
int m_dbId;
86107
std::string m_dbName;
108+
std::string m_namespace;
87109
};
88110

89111
}

common/redisselect.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ int RedisSelect::getFd()
1616
{
1717
return m_subscribe->getContext()->fd;
1818
}
19+
int RedisSelect::getDbConnectorId()
20+
{
21+
return m_subscribe->getDbId();
22+
}
23+
24+
std::string RedisSelect::getDbNamespace()
25+
{
26+
return m_subscribe->getNamespace();
27+
}
1928

2029
uint64_t RedisSelect::readData()
2130
{

common/redisselect.h

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class RedisSelect : public Selectable
2020
bool hasCachedData() override;
2121
bool initializedWithData() override;
2222
void updateAfterRead() override;
23+
int getDbConnectorId() override;
24+
std::string getDbNamespace() override;
2325

2426
/* Create a new redisContext, SELECT DB and SUBSCRIBE */
2527
void subscribe(DBConnector* db, const std::string &channelName);

common/selectable.h

+10
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ class Selectable
5858
return m_priority;
5959
}
6060

61+
virtual int getDbConnectorId()
62+
{
63+
return 0;
64+
}
65+
66+
virtual std::string getDbNamespace()
67+
{
68+
return std::string();
69+
}
70+
6171
private:
6272

6373
friend class Select;

tests/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ tests_SOURCES = redis_ut.cpp \
2828
warm_restart_ut.cpp \
2929
redis_multi_db_ut.cpp \
3030
logger_ut.cpp \
31+
redis_multi_ns_ut.cpp \
3132
fdb_flush.cpp \
3233
main.cpp
3334

tests/main.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ using namespace swss;
77

88
string existing_file = "./tests/redis_multi_db_ut_config/database_config.json";
99
string nonexisting_file = "./tests/redis_multi_db_ut_config/database_config_nonexisting.json";
10+
string global_existing_file = "./tests/redis_multi_db_ut_config/database_global.json";
11+
12+
#define TEST_DB "APPL_DB"
13+
#define TEST_NAMESPACE "asic0"
14+
#define INVALID_NAMESPACE "invalid"
1015

1116
class SwsscommonEnvironment : public ::testing::Environment {
1217
public:
@@ -32,6 +37,39 @@ class SwsscommonEnvironment : public ::testing::Environment {
3237
SonicDBConfig::initialize(existing_file);
3338
cout<<"INIT: load local db config file, isInit = "<<SonicDBConfig::isInit()<<endl;
3439
EXPECT_TRUE(SonicDBConfig::isInit());
40+
41+
// Test the database_global.json file
42+
// by default , global_init should be false
43+
cout<<"Default : isGlobalInit = "<<SonicDBConfig::isGlobalInit()<<endl;
44+
EXPECT_FALSE(SonicDBConfig::isGlobalInit());
45+
46+
// Call an API which actually needs the data populated by SonicDBConfig::initializeGlobalConfig
47+
try
48+
{
49+
cout<<"INIT: Invoking SonicDBConfig::getDbId(APPL_DB, asic0)"<<endl;
50+
SonicDBConfig::getDbId(TEST_DB, TEST_NAMESPACE);
51+
}
52+
catch (exception &e)
53+
{
54+
EXPECT_TRUE(strstr(e.what(), "Initialize global DB config using API SonicDBConfig::initializeGlobalConfig"));
55+
}
56+
57+
// load local global file, init should be true
58+
SonicDBConfig::initializeGlobalConfig(global_existing_file);
59+
cout<<"INIT: load global db config file, isInit = "<<SonicDBConfig::isGlobalInit()<<endl;
60+
EXPECT_TRUE(SonicDBConfig::isGlobalInit());
61+
62+
// Call an API with wrong namespace passed
63+
try
64+
{
65+
cout<<"INIT: Invoking SonicDBConfig::getDbId(APPL_DB, invalid)"<<endl;
66+
SonicDBConfig::getDbId(TEST_DB, INVALID_NAMESPACE);
67+
}
68+
catch (exception &e)
69+
{
70+
EXPECT_TRUE(strstr(e.what(), "Namespace invalid is not a valid namespace name in config file"));
71+
}
72+
3573
}
3674
};
3775

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"INSTANCES": {
3+
"redis":{
4+
"hostname" : "127.0.0.1",
5+
"port": 6379,
6+
"unix_socket_path": "/var/run/redis0/redis.sock"
7+
}
8+
},
9+
"DATABASES" : {
10+
"APPL_DB" : {
11+
"id" : 0,
12+
"separator": ":",
13+
"instance" : "redis"
14+
},
15+
"ASIC_DB" : {
16+
"id" : 1,
17+
"separator": ":",
18+
"instance" : "redis"
19+
},
20+
"COUNTERS_DB" : {
21+
"id" : 2,
22+
"separator": ":",
23+
"instance" : "redis"
24+
},
25+
"LOGLEVEL_DB" : {
26+
"id" : 3,
27+
"separator": ":",
28+
"instance" : "redis"
29+
},
30+
"CONFIG_DB" : {
31+
"id" : 4,
32+
"separator": "|",
33+
"instance" : "redis"
34+
},
35+
"PFC_WD_DB" : {
36+
"id" : 5,
37+
"separator": ":",
38+
"instance" : "redis"
39+
},
40+
"FLEX_COUNTER_DB" : {
41+
"id" : 5,
42+
"separator": ":",
43+
"instance" : "redis"
44+
},
45+
"STATE_DB" : {
46+
"id" : 6,
47+
"separator": "|",
48+
"instance" : "redis"
49+
},
50+
"SNMP_OVERLAY_DB" : {
51+
"id" : 7,
52+
"separator": "|",
53+
"instance" : "redis"
54+
},
55+
"ASIC_DB2" : {
56+
"id" : 10,
57+
"separator": ":",
58+
"instance" : "redis"
59+
},
60+
"COUNTERS_DB2" : {
61+
"id" : 11,
62+
"separator": ":",
63+
"instance" : "redis"
64+
},
65+
"FLEX_COUNTER_DB2" : {
66+
"id" : 12,
67+
"separator": ":",
68+
"instance" : "redis"
69+
},
70+
"STATE_DB2" : {
71+
"id" : 13,
72+
"separator": "|",
73+
"instance" : "redis"
74+
},
75+
"TEST_DB" : {
76+
"id" : 15,
77+
"separator": ":",
78+
"instance" : "redis"
79+
}
80+
},
81+
"VERSION" : "1.0"
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"INSTANCES": {
3+
"redis":{
4+
"hostname" : "127.0.0.1",
5+
"port": 6379,
6+
"unix_socket_path": "/var/run/redis1/redis.sock"
7+
}
8+
},
9+
"DATABASES" : {
10+
"APPL_DB" : {
11+
"id" : 0,
12+
"separator": ":",
13+
"instance" : "redis"
14+
},
15+
"ASIC_DB" : {
16+
"id" : 1,
17+
"separator": ":",
18+
"instance" : "redis"
19+
},
20+
"COUNTERS_DB" : {
21+
"id" : 2,
22+
"separator": ":",
23+
"instance" : "redis"
24+
},
25+
"LOGLEVEL_DB" : {
26+
"id" : 3,
27+
"separator": ":",
28+
"instance" : "redis"
29+
},
30+
"CONFIG_DB" : {
31+
"id" : 4,
32+
"separator": "|",
33+
"instance" : "redis"
34+
},
35+
"PFC_WD_DB" : {
36+
"id" : 5,
37+
"separator": ":",
38+
"instance" : "redis"
39+
},
40+
"FLEX_COUNTER_DB" : {
41+
"id" : 5,
42+
"separator": ":",
43+
"instance" : "redis"
44+
},
45+
"STATE_DB" : {
46+
"id" : 6,
47+
"separator": "|",
48+
"instance" : "redis"
49+
},
50+
"SNMP_OVERLAY_DB" : {
51+
"id" : 7,
52+
"separator": "|",
53+
"instance" : "redis"
54+
},
55+
"ASIC_DB2" : {
56+
"id" : 10,
57+
"separator": ":",
58+
"instance" : "redis"
59+
},
60+
"COUNTERS_DB2" : {
61+
"id" : 11,
62+
"separator": ":",
63+
"instance" : "redis"
64+
},
65+
"FLEX_COUNTER_DB2" : {
66+
"id" : 12,
67+
"separator": ":",
68+
"instance" : "redis"
69+
},
70+
"STATE_DB2" : {
71+
"id" : 13,
72+
"separator": "|",
73+
"instance" : "redis"
74+
},
75+
"TEST_DB" : {
76+
"id" : 15,
77+
"separator": ":",
78+
"instance" : "redis"
79+
}
80+
},
81+
"VERSION" : "1.0"
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"INCLUDES" : [
3+
{
4+
"include" : "database_config.json"
5+
},
6+
{
7+
"namespace" : "asic0",
8+
"include" : "../redis_multi_db_ut_config/database_config0.json"
9+
},
10+
{
11+
"namespace" : "asic1",
12+
"include" : "../redis_multi_db_ut_config/database_config1.json"
13+
}
14+
],
15+
"VERSION" : "1.0"
16+
}

0 commit comments

Comments
 (0)