Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance SDK to read from any DB by name #49

Merged
merged 1 commit into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions src/swsssdk/config/database.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,41 @@
"SonicV1Connector": {
"db_map": {
"IF_COUNTER_DB": {
"db": 0
"db": 0,
"separator": ":"
},
"LLDP_COUNTER_DB": {
"db": 1
"db": 1,
"separator": ":"
}
}
},
"SonicV2Connector": {
"db_map": {
"APPL_DB": {
"db": 0
"db": 0,
"separator": ":"
},
"ASIC_DB": {
"db": 1
"db": 1,
"separator": ":"
},
"COUNTERS_DB": {
"db": 2
"db": 2,
"separator": ":"
},
"CONFIG_DB": {
"db": 4
"db": 4,
"separator": "|"
},
"STATE_DB": {
"db": 6
"db": 6,
"separator": "|"
},
"SNMP_OVERLAY_DB": {
"db": 7
"db": 7,
"separator": "|"

}
}
}
Expand Down
57 changes: 44 additions & 13 deletions src/swsssdk/configdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ def __init__(self, **kwargs):
self.handlers = {}

def __wait_for_db_init(self):
client = self.redis_clients[self.CONFIG_DB]
client = self.redis_clients[self.db_name]
pubsub = client.pubsub()
initialized = client.get(self.INIT_INDICATOR)
if not initialized:
pattern = "__keyspace@{}__:{}".format(self.db_map[self.CONFIG_DB]['db'], self.INIT_INDICATOR)
pattern = "__keyspace@{}__:{}".format(self.db_map[self.db_name]['db'], self.INIT_INDICATOR)
pubsub.psubscribe(pattern)
for item in pubsub.listen():
if item['type'] == 'pmessage':
Expand All @@ -53,11 +53,16 @@ def __wait_for_db_init(self):
pubsub.punsubscribe(pattern)


def connect(self, wait_for_init=True, retry_on=False):
SonicV2Connector.connect(self, self.CONFIG_DB, retry_on)
def db_connect(self, dbname, wait_for_init=False, retry_on=False):
self.db_name = dbname
self.KEY_SEPARATOR = self.TABLE_NAME_SEPARATOR = self.db_map[self.db_name]['separator']
SonicV2Connector.connect(self, self.db_name, retry_on)
if wait_for_init:
self.__wait_for_db_init()

def connect(self, wait_for_init=True, retry_on=False):
self.db_connect('CONFIG_DB', wait_for_init, retry_on)

def subscribe(self, table, handler):
"""Set a handler to handle config change in certain table.
Note that a single handler can be registered to different tables by
Expand All @@ -84,15 +89,15 @@ def __fire(self, table, key, data):
def listen(self):
"""Start listen Redis keyspace events and will trigger corresponding handlers when content of a table changes.
"""
self.pubsub = self.redis_clients[self.CONFIG_DB].pubsub()
self.pubsub.psubscribe("__keyspace@{}__:*".format(self.db_map[self.CONFIG_DB]['db']))
self.pubsub = self.redis_clients[self.db_name].pubsub()
self.pubsub.psubscribe("__keyspace@{}__:*".format(self.db_map[self.db_name]['db']))
for item in self.pubsub.listen():
if item['type'] == 'pmessage':
key = item['channel'].split(':', 1)[1]
try:
(table, row) = key.split(self.TABLE_NAME_SEPARATOR, 1)
if self.handlers.has_key(table):
client = self.redis_clients[self.CONFIG_DB]
client = self.redis_clients[self.db_name]
data = self.__raw_to_typed(client.hgetall(key))
self.__fire(table, row, data)
except ValueError:
Expand Down Expand Up @@ -166,7 +171,7 @@ def set_entry(self, table, key, data):
Pass None as data will delete the entry.
"""
key = self.serialize_key(key)
client = self.redis_clients[self.CONFIG_DB]
client = self.redis_clients[self.db_name]
_hash = '{}{}{}'.format(table.upper(), self.TABLE_NAME_SEPARATOR, key)
if data == None:
client.delete(_hash)
Expand All @@ -188,7 +193,7 @@ def mod_entry(self, table, key, data):
Pass None as data will delete the entry.
"""
key = self.serialize_key(key)
client = self.redis_clients[self.CONFIG_DB]
client = self.redis_clients[self.db_name]
_hash = '{}{}{}'.format(table.upper(), self.TABLE_NAME_SEPARATOR, key)
if data == None:
client.delete(_hash)
Expand All @@ -205,10 +210,36 @@ def get_entry(self, table, key):
Empty dictionary if table does not exist or entry does not exist.
"""
key = self.serialize_key(key)
client = self.redis_clients[self.CONFIG_DB]
client = self.redis_clients[self.db_name]
_hash = '{}{}{}'.format(table.upper(), self.TABLE_NAME_SEPARATOR, key)
return self.__raw_to_typed(client.hgetall(_hash))

def get_keys(self, table, split=True):
"""Read all keys of a table from config db.
Args:
table: Table name.
split: split the first part and return second.
Useful for keys with two parts <tablename>:<key>
Returns:
List of keys.
"""
client = self.redis_clients[self.db_name]
pattern = '{}{}*'.format(table.upper(), self.TABLE_NAME_SEPARATOR)
keys = client.keys(pattern)
data = []
for key in keys:
try:
if PY3K:
key = key.decode('utf-8')
if split:
(_, row) = key.split(self.TABLE_NAME_SEPARATOR, 1)
data.append(self.deserialize_key(row))
else:
data.append(self.deserialize_key(key))
except ValueError:
pass #Ignore non table-formated redis entries
return data

def get_table(self, table):
"""Read an entire table from config db.
Args:
Expand All @@ -219,7 +250,7 @@ def get_table(self, table):
or { ('l1_key', 'l2_key', ...): {'column_key': value, ...}, ...} for a multi-key table.
Empty dictionary if table does not exist.
"""
client = self.redis_clients[self.CONFIG_DB]
client = self.redis_clients[self.db_name]
pattern = '{}{}*'.format(table.upper(), self.TABLE_NAME_SEPARATOR)
keys = client.keys(pattern)
data = {}
Expand All @@ -243,7 +274,7 @@ def delete_table(self, table):
Args:
table: Table name.
"""
client = self.redis_clients[self.CONFIG_DB]
client = self.redis_clients[self.db_name]
pattern = '{}{}*'.format(table.upper(), self.TABLE_NAME_SEPARATOR)
keys = client.keys(pattern)
data = {}
Expand Down Expand Up @@ -276,7 +307,7 @@ def get_config(self):
...
}
"""
client = self.redis_clients[self.CONFIG_DB]
client = self.redis_clients[self.db_name]
keys = client.keys('*')
data = {}
for key in keys:
Expand Down