1 # Copyright (c) 2019 AT&T Intellectual Property.
2 # Copyright (c) 2018-2019 Nokia.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 # This source code is part of the near-RT RIC (RAN Intelligent Controller)
18 # platform project (RICP).
22 """The module provides fake implementation of Shared Data Layer (SDL) database backend interface."""
24 from typing import (Dict, Set, List, Union)
25 from ricsdl.configuration import _Configuration
26 from .dbbackend_abc import DbBackendAbc
27 from .dbbackend_abc import DbBackendLockAbc
30 class FakeDictBackend(DbBackendAbc):
32 A class providing fake implementation of database backend of Shared Data Layer (SDL).
33 This class does not provide working database solution, this class can be used in testing
34 purposes only. Implementation does not provide shared database resource, SDL client sees
35 only its local local 'fake' database, which is a simple Python dictionary. Also keys are
36 stored in database under the same namespace.
39 configuration (_Configuration): SDL configuration, containing credentials to connect to
40 Redis database backend.
42 def __init__(self, configuration: _Configuration) -> None:
45 self._configuration = configuration
54 def is_connected(self):
60 def set(self, ns: str, data_map: Dict[str, bytes]) -> None:
61 self._db.update(data_map.copy())
63 def set_if(self, ns: str, key: str, old_data: bytes, new_data: bytes) -> bool:
64 if key not in self._db:
66 db_data = self._db[key]
67 if db_data == old_data:
68 self._db[key] = new_data
72 def set_if_not_exists(self, ns: str, key: str, data: bytes) -> bool:
73 if key not in self._db:
78 def get(self, ns: str, keys: List[str]) -> Dict[str, bytes]:
85 def find_keys(self, ns: str, key_pattern: str) -> List[str]:
88 if fnmatch.fnmatch(k, key_pattern):
92 def find_and_get(self, ns: str, key_pattern: str) -> Dict[str, bytes]:
94 for key, val in self._db.items():
95 if fnmatch.fnmatch(key, key_pattern):
99 def remove(self, ns: str, keys: List[str]) -> None:
101 self._db.pop(key, None)
103 def remove_if(self, ns: str, key: str, data: bytes) -> bool:
105 db_data = self._db[key]
111 def add_member(self, ns: str, group: str, members: Set[bytes]) -> None:
112 if group in self._db:
113 self._db[group] = self._db[group] | members.copy()
115 self._db[group] = members.copy()
117 def remove_member(self, ns: str, group: str, members: Set[bytes]) -> None:
118 if group not in self._db:
120 for member in members:
121 self._db[group].discard(member)
123 def remove_group(self, ns: str, group: str) -> None:
124 self._db.pop(group, None)
126 def get_members(self, ns: str, group: str) -> Set[bytes]:
127 return self._db.get(group, set())
129 def is_member(self, ns: str, group: str, member: bytes) -> bool:
130 if group not in self._db:
132 if member in self._db[group]:
136 def group_size(self, ns: str, group: str) -> int:
137 if group not in self._db:
139 return len(self._db[group])
142 class FakeDictBackendLock(DbBackendLockAbc):
144 A class providing fake implementation of database backend lock of Shared Data Layer (SDL).
145 This class does not provide working database solution, this class can be used in testing
146 purposes only. Implementation does not provide shared database resource, SDL client sees
147 only its local local 'fake' database, which is a simple Python dictionary. Also keys are
148 stored in database under the same namespace.
150 ns (str): Namespace under which this lock is targeted.
151 name (str): Lock name, identifies the lock key in a Redis database backend.
152 expiration (int, float): Lock expiration time after which the lock is removed if it hasn't
153 been released earlier by a 'release' method.
154 redis_backend (FakeBackend): Database backend object containing fake databese connection.
157 def __init__(self, ns: str, name: str, expiration: Union[int, float],
158 redis_backend: FakeDictBackend) -> None:
159 super().__init__(ns, name)
162 self._lock_name = name
163 self._lock_expiration = expiration
164 self.redis_backend = redis_backend
169 "lock DB type": "FAKE DB",
170 "lock namespace": self._ns,
171 "lock name": self._lock_name,
172 "lock status": self._lock_status_to_string()
176 def acquire(self, retry_interval: Union[int, float] = 0.1,
177 retry_timeout: Union[int, float] = 10) -> bool:
183 def release(self) -> None:
186 def refresh(self) -> None:
189 def get_validity_time(self) -> Union[int, float]:
190 return self._lock_expiration
192 def _lock_status_to_string(self) -> str: