@@ -16,17 +16,11 @@ using namespace std;
16
16
17
17
namespace swss {
18
18
19
- void SonicDBConfig::initialize (const string &file)
19
+ void SonicDBConfig::parseDatabaseConfig (const string &file,
20
+ std::unordered_map<std::string, RedisInstInfo> &inst_entry,
21
+ std::unordered_map<std::string, SonicDBInfo> &db_entry,
22
+ std::unordered_map<int , std::string> &separator_entry)
20
23
{
21
-
22
- SWSS_LOG_ENTER ();
23
-
24
- if (m_init)
25
- {
26
- SWSS_LOG_ERROR (" SonicDBConfig already initialized" );
27
- throw runtime_error (" SonicDBConfig already initialized" );
28
- }
29
-
30
24
ifstream i (file);
31
25
if (i.good ())
32
26
{
@@ -40,7 +34,7 @@ void SonicDBConfig::initialize(const string &file)
40
34
string socket = it.value ().at (" unix_socket_path" );
41
35
string hostname = it.value ().at (" hostname" );
42
36
int port = it.value ().at (" port" );
43
- m_inst_info [instName] = {socket, { hostname, port} };
37
+ inst_entry [instName] = {socket, hostname, port};
44
38
}
45
39
46
40
for (auto it = j[" DATABASES" ].begin (); it!= j[" DATABASES" ].end (); it++)
@@ -49,12 +43,12 @@ void SonicDBConfig::initialize(const string &file)
49
43
string instName = it.value ().at (" instance" );
50
44
int dbId = it.value ().at (" id" );
51
45
string separator = it.value ().at (" separator" );
52
- m_db_info [dbName] = {instName, dbId, separator};
46
+ db_entry [dbName] = {instName, dbId, separator};
53
47
54
- m_db_separator .emplace (dbId, separator);
48
+ separator_entry .emplace (dbId, separator);
55
49
}
56
- m_init = true ;
57
50
}
51
+
58
52
catch (domain_error& e)
59
53
{
60
54
SWSS_LOG_ERROR (" key doesn't exist in json object, NULL value has no iterator >> %s\n " , e.what ());
@@ -73,32 +67,152 @@ void SonicDBConfig::initialize(const string &file)
73
67
}
74
68
}
75
69
76
- string SonicDBConfig::getDbInst (const string &dbName)
70
+ void SonicDBConfig::initializeGlobalConfig (const string &file)
71
+ {
72
+ std::string local_file, dir_name, ns_name;
73
+ std::unordered_map<std::string, SonicDBInfo> db_entry;
74
+ std::unordered_map<std::string, RedisInstInfo> inst_entry;
75
+ std::unordered_map<int , std::string> separator_entry;
76
+
77
+ SWSS_LOG_ENTER ();
78
+
79
+ if (m_global_init)
80
+ {
81
+ SWSS_LOG_ERROR (" SonicDBConfig Global config is already initialized" );
82
+ return ;
83
+ }
84
+
85
+
86
+ ifstream i (file);
87
+ if (i.good ())
88
+ {
89
+ local_file = dir_name = std::string ();
90
+
91
+ // Get the directory name from the file path given as input.
92
+ std::string::size_type pos = file.rfind (" /" );
93
+ if ( pos != std::string::npos)
94
+ {
95
+ dir_name = file.substr (0 ,pos+1 );
96
+ }
97
+
98
+ try
99
+ {
100
+ json j;
101
+ i >> j;
102
+
103
+ for (auto & element : j[" INCLUDES" ])
104
+ {
105
+ local_file.append (dir_name);
106
+ local_file.append (element[" include" ]);
107
+
108
+ if (element[" namespace" ].empty ())
109
+ {
110
+ // If database_config.json is already initlized via SonicDBConfig::initialize
111
+ // skip initializing it here again.
112
+ if (m_init)
113
+ {
114
+ local_file.clear ();
115
+ continue ;
116
+ }
117
+ ns_name = EMPTY_NAMESPACE;
118
+ }
119
+ else
120
+ {
121
+ ns_name = element[" namespace" ];
122
+ }
123
+
124
+ parseDatabaseConfig (local_file, inst_entry, db_entry, separator_entry);
125
+ m_inst_info[ns_name] = inst_entry;
126
+ m_db_info[ns_name] = db_entry;
127
+ m_db_separator[ns_name] = separator_entry;
128
+
129
+ inst_entry.clear ();
130
+ db_entry.clear ();
131
+ separator_entry.clear ();
132
+ local_file.clear ();
133
+ }
134
+ }
135
+
136
+ catch (domain_error& e)
137
+ {
138
+ SWSS_LOG_ERROR (" key doesn't exist in json object, NULL value has no iterator >> %s\n " , e.what ());
139
+ throw runtime_error (" key doesn't exist in json object, NULL value has no iterator >> " + string (e.what ()));
140
+ }
141
+ catch (exception &e)
142
+ {
143
+ SWSS_LOG_ERROR (" Sonic database config file syntax error >> %s\n " , e.what ());
144
+ throw runtime_error (" Sonic database config file syntax error >> " + string (e.what ()));
145
+ }
146
+ }
147
+ else
148
+ {
149
+ SWSS_LOG_ERROR (" Sonic database global config file doesn't exist at %s\n " , file.c_str ());
150
+ throw runtime_error (" Sonic database global config file doesn't exist at " + file);
151
+ }
152
+
153
+ // Set it as the global config file is already parsed and init done.
154
+ m_global_init = true ;
155
+
156
+ // Make regular init also done
157
+ m_init = true ;
158
+ }
159
+
160
+ void SonicDBConfig::initialize (const string &file, const string &nameSpace)
161
+ {
162
+ std::unordered_map<std::string, SonicDBInfo> db_entry;
163
+ std::unordered_map<std::string, RedisInstInfo> inst_entry;
164
+ std::unordered_map<int , std::string> separator_entry;
165
+
166
+ SWSS_LOG_ENTER ();
167
+
168
+ if (m_init)
169
+ {
170
+ SWSS_LOG_ERROR (" SonicDBConfig already initialized" );
171
+ throw runtime_error (" SonicDBConfig already initialized" );
172
+ }
173
+
174
+ // namespace string is empty, use the file given as input to parse.
175
+ if (nameSpace.empty ())
176
+ {
177
+ parseDatabaseConfig (file, inst_entry, db_entry, separator_entry);
178
+ m_inst_info[EMPTY_NAMESPACE] = inst_entry;
179
+ m_db_info[EMPTY_NAMESPACE] = db_entry;
180
+ m_db_separator[EMPTY_NAMESPACE] = separator_entry;
181
+ }
182
+ else
183
+ // namespace is not empty, use DEFAULT_SONIC_DB_GLOBAL_CONFIG_FILE.
184
+ initializeGlobalConfig ();
185
+
186
+ // Set it as the config file is already parsed and init done.
187
+ m_init = true ;
188
+ }
189
+
190
+ string SonicDBConfig::getDbInst (const string &dbName, const string &nameSpace)
77
191
{
78
192
if (!m_init)
79
- initialize ();
80
- return m_db_info.at (dbName).instName ;
193
+ initialize (DEFAULT_SONIC_DB_CONFIG_FILE, nameSpace );
194
+ return m_db_info[nameSpace] .at (dbName).instName ;
81
195
}
82
196
83
- int SonicDBConfig::getDbId (const string &dbName)
197
+ int SonicDBConfig::getDbId (const string &dbName, const string &nameSpace )
84
198
{
85
199
if (!m_init)
86
- initialize ();
87
- return m_db_info.at (dbName).dbId ;
200
+ initialize (DEFAULT_SONIC_DB_CONFIG_FILE, nameSpace );
201
+ return m_db_info[nameSpace] .at (dbName).dbId ;
88
202
}
89
203
90
- string SonicDBConfig::getSeparator (const string &dbName)
204
+ string SonicDBConfig::getSeparator (const string &dbName, const string &nameSpace )
91
205
{
92
206
if (!m_init)
93
- initialize ();
94
- return m_db_info.at (dbName).separator ;
207
+ initialize (DEFAULT_SONIC_DB_CONFIG_FILE, nameSpace );
208
+ return m_db_info[nameSpace] .at (dbName).separator ;
95
209
}
96
210
97
- string SonicDBConfig::getSeparator (int dbId)
211
+ string SonicDBConfig::getSeparator (int dbId, const string &nameSpace )
98
212
{
99
213
if (!m_init)
100
- initialize ();
101
- return m_db_separator.at (dbId);
214
+ initialize (DEFAULT_SONIC_DB_CONFIG_FILE, nameSpace );
215
+ return m_db_separator[nameSpace] .at (dbId);
102
216
}
103
217
104
218
string SonicDBConfig::getSeparator (const DBConnector* db)
@@ -109,42 +223,61 @@ string SonicDBConfig::getSeparator(const DBConnector* db)
109
223
}
110
224
111
225
string dbName = db->getDbName ();
226
+ string nameSpace = db->getNamespace ();
112
227
if (dbName.empty ())
113
228
{
114
- return getSeparator (db->getDbId ());
229
+ return getSeparator (db->getDbId (), nameSpace );
115
230
}
116
231
else
117
232
{
118
- return getSeparator (dbName);
233
+ return getSeparator (dbName, nameSpace );
119
234
}
120
235
}
121
236
122
- string SonicDBConfig::getDbSock (const string &dbName)
237
+ string SonicDBConfig::getDbSock (const string &dbName, const string &nameSpace )
123
238
{
124
239
if (!m_init)
125
- initialize ();
126
- return m_inst_info.at (getDbInst (dbName)).first ;
240
+ initialize (DEFAULT_SONIC_DB_CONFIG_FILE, nameSpace );
241
+ return m_inst_info[nameSpace] .at (getDbInst (dbName)).unixSocketPath ;
127
242
}
128
243
129
- string SonicDBConfig::getDbHostname (const string &dbName)
244
+ string SonicDBConfig::getDbHostname (const string &dbName, const string &nameSpace )
130
245
{
131
246
if (!m_init)
132
- initialize ();
133
- return m_inst_info.at (getDbInst (dbName)).second . first ;
247
+ initialize (DEFAULT_SONIC_DB_CONFIG_FILE, nameSpace );
248
+ return m_inst_info[nameSpace] .at (getDbInst (dbName)).hostname ;
134
249
}
135
250
136
- int SonicDBConfig::getDbPort (const string &dbName)
251
+ int SonicDBConfig::getDbPort (const string &dbName, const string &nameSpace )
137
252
{
138
253
if (!m_init)
139
- initialize ();
140
- return m_inst_info.at (getDbInst (dbName)).second .second ;
254
+ initialize (DEFAULT_SONIC_DB_CONFIG_FILE, nameSpace);
255
+ return m_inst_info[nameSpace].at (getDbInst (dbName)).port ;
256
+ }
257
+
258
+ vector<string> SonicDBConfig::getNamespaces ()
259
+ {
260
+ vector<string> list;
261
+
262
+ if (!m_global_init)
263
+ initializeGlobalConfig ();
264
+
265
+ // This API returns back non-empty namespaces.
266
+ for (auto it = m_inst_info.cbegin (); it != m_inst_info.cend (); ++it) {
267
+ if (!((it->first ).empty ()))
268
+ list.push_back (it->first );
269
+ }
270
+
271
+ return list;
141
272
}
142
273
143
274
constexpr const char *SonicDBConfig::DEFAULT_SONIC_DB_CONFIG_FILE;
144
- unordered_map<string, pair<string, pair<string, int >>> SonicDBConfig::m_inst_info;
145
- unordered_map<string, SonicDBInfo> SonicDBConfig::m_db_info;
146
- unordered_map<int , string> SonicDBConfig::m_db_separator;
275
+ constexpr const char *SonicDBConfig::DEFAULT_SONIC_DB_GLOBAL_CONFIG_FILE;
276
+ unordered_map<string, unordered_map<string, RedisInstInfo>> SonicDBConfig::m_inst_info;
277
+ unordered_map<string, unordered_map<string, SonicDBInfo>> SonicDBConfig::m_db_info;
278
+ unordered_map<string, unordered_map<int , string>> SonicDBConfig::m_db_separator;
147
279
bool SonicDBConfig::m_init = false ;
280
+ bool SonicDBConfig::m_global_init = false ;
148
281
149
282
constexpr const char *DBConnector::DEFAULT_UNIXSOCKET;
150
283
@@ -164,7 +297,8 @@ DBConnector::~DBConnector()
164
297
165
298
DBConnector::DBConnector (int dbId, const string& hostname, int port,
166
299
unsigned int timeout) :
167
- m_dbId (dbId)
300
+ m_dbId (dbId),
301
+ m_namespace (EMPTY_NAMESPACE)
168
302
{
169
303
struct timeval tv = {0 , (suseconds_t )timeout * 1000 };
170
304
@@ -181,7 +315,8 @@ DBConnector::DBConnector(int dbId, const string& hostname, int port,
181
315
}
182
316
183
317
DBConnector::DBConnector (int dbId, const string& unixPath, unsigned int timeout) :
184
- m_dbId (dbId)
318
+ m_dbId (dbId),
319
+ m_namespace (EMPTY_NAMESPACE)
185
320
{
186
321
struct timeval tv = {0 , (suseconds_t )timeout * 1000 };
187
322
@@ -192,30 +327,31 @@ DBConnector::DBConnector(int dbId, const string& unixPath, unsigned int timeout)
192
327
193
328
if (m_conn->err )
194
329
throw system_error (make_error_code (errc::address_not_available),
195
- " Unable to connect to redis (unixs -socket)" );
330
+ " Unable to connect to redis (unix -socket)" );
196
331
197
332
select (this );
198
333
}
199
334
200
- DBConnector::DBConnector (const string& dbName, unsigned int timeout, bool isTcpConn)
201
- : m_dbId(SonicDBConfig::getDbId(dbName))
335
+ DBConnector::DBConnector (const string& dbName, unsigned int timeout, bool isTcpConn, const string& nameSpace )
336
+ : m_dbId(SonicDBConfig::getDbId(dbName, nameSpace ))
202
337
, m_dbName(dbName)
338
+ , m_namespace(nameSpace)
203
339
{
204
340
struct timeval tv = {0 , (suseconds_t )timeout * 1000 };
205
341
206
342
if (timeout)
207
343
{
208
344
if (isTcpConn)
209
- m_conn = redisConnectWithTimeout (SonicDBConfig::getDbHostname (dbName).c_str (), SonicDBConfig::getDbPort (dbName), tv);
345
+ m_conn = redisConnectWithTimeout (SonicDBConfig::getDbHostname (dbName, nameSpace ).c_str (), SonicDBConfig::getDbPort (dbName, nameSpace ), tv);
210
346
else
211
- m_conn = redisConnectUnixWithTimeout (SonicDBConfig::getDbSock (dbName).c_str (), tv);
347
+ m_conn = redisConnectUnixWithTimeout (SonicDBConfig::getDbSock (dbName, nameSpace ).c_str (), tv);
212
348
}
213
349
else
214
350
{
215
351
if (isTcpConn)
216
- m_conn = redisConnect (SonicDBConfig::getDbHostname (dbName).c_str (), SonicDBConfig::getDbPort (dbName));
352
+ m_conn = redisConnect (SonicDBConfig::getDbHostname (dbName, nameSpace ).c_str (), SonicDBConfig::getDbPort (dbName, nameSpace ));
217
353
else
218
- m_conn = redisConnectUnix (SonicDBConfig::getDbSock (dbName).c_str ());
354
+ m_conn = redisConnectUnix (SonicDBConfig::getDbSock (dbName, nameSpace ).c_str ());
219
355
}
220
356
221
357
if (m_conn->err )
@@ -240,19 +376,15 @@ string DBConnector::getDbName() const
240
376
return m_dbName;
241
377
}
242
378
379
+ string DBConnector::getNamespace () const
380
+ {
381
+ return m_namespace;
382
+ }
383
+
243
384
DBConnector *DBConnector::newConnector (unsigned int timeout) const
244
385
{
245
386
DBConnector *ret;
246
- if (getContext ()->connection_type == REDIS_CONN_TCP)
247
- ret = new DBConnector (getDbId (),
248
- getContext ()->tcp .host ,
249
- getContext ()->tcp .port ,
250
- timeout);
251
- else
252
- ret = new DBConnector (getDbId (),
253
- getContext ()->unix_sock .path ,
254
- timeout);
255
- ret->m_dbName = m_dbName;
387
+ ret = new DBConnector (getDbName (), timeout, (getContext ()->connection_type == REDIS_CONN_TCP), getNamespace ());
256
388
return ret;
257
389
}
258
390
0 commit comments