blob: 8805bdd58de5bc99cb8fd72535b51d19168da5fa [file] [log] [blame]
Timo Tietavainendada8462019-11-27 11:50:01 +02001# Copyright (c) 2019 AT&T Intellectual Property.
2# Copyright (c) 2018-2019 Nokia.
3#
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
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
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.
15
16#
17# This source code is part of the near-RT RIC (RAN Intelligent Controller)
18# platform project (RICP).
19#
20
21
22"""The module provides Shared Data Layer (SDL) database backend interface."""
23
Timothy Ebidoa4392392020-08-12 10:49:26 +090024from typing import (Callable, Dict, Set, List, Optional, Tuple, Union)
Timo Tietavainendada8462019-11-27 11:50:01 +020025from abc import ABC, abstractmethod
26
27
28class DbBackendAbc(ABC):
29 """An abstract Shared Data Layer (SDL) class providing database backend interface."""
30
31 @abstractmethod
Timo Tietavainenc979c0d2020-01-21 21:57:17 +020032 def is_connected(self):
33 """Test database backend connection."""
34 pass
35
36 @abstractmethod
Timo Tietavainendada8462019-11-27 11:50:01 +020037 def close(self):
38 """Close database backend connection."""
39 pass
40
41 @abstractmethod
42 def set(self, ns: str, data_map: Dict[str, bytes]) -> None:
43 """Write key value data mapping to database under a namespace."""
44 pass
45
46 @abstractmethod
47 def set_if(self, ns: str, key: str, old_data: bytes, new_data: bytes) -> bool:
48 """"Write key value to database under a namespace if the old value is expected one."""
49 pass
50
51 @abstractmethod
52 def set_if_not_exists(self, ns: str, key: str, data: bytes) -> bool:
53 """"Write key value to database under a namespace if key doesn't exist."""
54 pass
55
56 @abstractmethod
57 def get(self, ns: str, keys: List[str]) -> Dict[str, bytes]:
58 """"Return values of the keys under a namespace."""
59 pass
60
61 @abstractmethod
Timo Tietavainen276ed3c2019-12-15 20:16:23 +020062 def find_keys(self, ns: str, key_pattern: str) -> List[str]:
Timo Tietavainendada8462019-11-27 11:50:01 +020063 """"Return all the keys matching search pattern under a namespace in database."""
64 pass
65
66 @abstractmethod
Timo Tietavainen276ed3c2019-12-15 20:16:23 +020067 def find_and_get(self, ns: str, key_pattern: str) -> Dict[str, bytes]:
Timo Tietavainendada8462019-11-27 11:50:01 +020068 """
69 Return all the keys with their values matching search pattern under a namespace in
70 database.
71 """
72 pass
73
74 @abstractmethod
75 def remove(self, ns: str, keys: List[str]) -> None:
76 """Remove keys and their data from database."""
77 pass
78
79 @abstractmethod
80 def remove_if(self, ns: str, key: str, data: bytes) -> bool:
81 """
82 Remove key and its data from database if if the current data value is expected
83 one.
84 """
85 pass
86
87 @abstractmethod
88 def add_member(self, ns: str, group: str, members: Set[bytes]) -> None:
89 """Add new members to a group under a namespace in database."""
90 pass
91
92 @abstractmethod
93 def remove_member(self, ns: str, group: str, members: Set[bytes]) -> None:
94 """Remove members from a group under a namespace in database."""
95 pass
96
97 @abstractmethod
98 def remove_group(self, ns: str, group: str) -> None:
99 """Remove a group under a namespace in database along with it's members."""
100 pass
101
102 @abstractmethod
103 def get_members(self, ns: str, group: str) -> Set[bytes]:
104 """Get all the members of a group under a namespace in database."""
105 pass
106
107 @abstractmethod
108 def is_member(self, ns: str, group: str, member: bytes) -> bool:
109 """Validate if a given member is in the group under a namespace in database."""
110 pass
111
112 @abstractmethod
113 def group_size(self, ns: str, group: str) -> int:
114 """Return the number of members in a group under a namespace in database."""
115 pass
116
Timothy Ebidoa4392392020-08-12 10:49:26 +0900117 @abstractmethod
118 def set_and_publish(self, ns: str, channels_and_events: Dict[str, List[str]],
119 data_map: Dict[str, bytes]) -> None:
120 """Publish event to channel after writing data."""
121 pass
122
123 @abstractmethod
124 def set_if_and_publish(self, ns: str, channels_and_events: Dict[str, List[str]], key: str,
125 old_data: bytes, new_data: bytes) -> bool:
126 """
127 Publish event to channel after writing key value to database under a namespace
128 if the old value is expected one.
129 """
130 pass
131
132 @abstractmethod
133 def set_if_not_exists_and_publish(self, ns: str, channels_and_events: Dict[str, List[str]],
134 key: str, data: bytes) -> bool:
135 """"
136 Publish event to channel after writing key value to database under a namespace if
137 key doesn't exist.
138 """
139 pass
140
141 @abstractmethod
142 def remove_and_publish(self, ns: str, channels_and_events: Dict[str, List[str]],
143 keys: List[str]) -> None:
144 """Publish event to channel after removing data."""
145 pass
146
147 @abstractmethod
148 def remove_if_and_publish(self, ns: str, channels_and_events: Dict[str, List[str]], key: str,
149 data: bytes) -> bool:
150 """
151 Publish event to channel after removing key and its data from database if the
152 current data value is expected one.
153 """
154 pass
155
156 @abstractmethod
157 def remove_all_and_publish(self, ns: str, channels_and_events: Dict[str, List[str]]) -> None:
158 """
159 Publish event to channel after removing all keys in namespace.
160 """
161 pass
162
163 @abstractmethod
Timo Tietavainenf5af9042021-06-10 15:54:37 +0300164 def subscribe_channel(self, ns: str, cb: Callable[[str, List[str]], None],
Timothy Ebidoa4392392020-08-12 10:49:26 +0900165 channels: List[str]) -> None:
166 """
167 This takes a callback function and one or many channels to be subscribed.
168 When an event is received for the given channel, the given callback function
Timo Tietavainenf5af9042021-06-10 15:54:37 +0300169 shall be called with channel and notification(s) as parameter.
Timothy Ebidoa4392392020-08-12 10:49:26 +0900170 """
171 pass
172
173 @abstractmethod
174 def unsubscribe_channel(self, ns: str, channels: List[str]) -> None:
175 """Unsubscribes from channel and removes set callback function."""
176 pass
177
178 @abstractmethod
179 def start_event_listener(self) -> None:
180 """
181 start_event_listener creates an event loop in a separate thread for handling
182 notifications from subscriptions.
183 """
184 pass
185
186 @abstractmethod
Timo Tietavainenf5af9042021-06-10 15:54:37 +0300187 def handle_events(self) -> Optional[Tuple[str, List[str]]]:
Timothy Ebidoa4392392020-08-12 10:49:26 +0900188 """
189 handle_events is a non-blocking function that returns a tuple containing channel
Timo Tietavainendb775392021-06-09 05:56:54 +0300190 name and message(s) received from notification.
Timothy Ebidoa4392392020-08-12 10:49:26 +0900191 """
192 pass
193
Timo Tietavainendada8462019-11-27 11:50:01 +0200194
195class DbBackendLockAbc(ABC):
196 """
197 An abstract Shared Data Layer (SDL) class providing database backend lock interface.
198 Args:
199 ns (str): Namespace under which this lock is targeted.
200 name (str): Lock name, identifies the lock key in a database backend.
201 """
202 def __init__(self, ns: str, name: str) -> None:
203 self._ns = ns
204 self._lock_name = name
205 super().__init__()
206
207 @abstractmethod
208 def acquire(self, retry_interval: Union[int, float] = 0.1,
209 retry_timeout: Union[int, float] = 10) -> bool:
210 """Acquire a database lock."""
211 pass
212
213 @abstractmethod
214 def release(self) -> None:
215 """Release a database lock."""
216 pass
217
218 @abstractmethod
219 def refresh(self) -> None:
220 """Refresh the remaining validity time of the database lock back to a initial value."""
221 pass
222
223 @abstractmethod
224 def get_validity_time(self) -> Union[int, float]:
225 """Return remaining validity time of the lock in seconds."""
226 pass