1 # ==================================================================================
2 # Copyright (c) 2020 Nokia
3 # Copyright (c) 2020 AT&T Intellectual Property.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 # ==================================================================================
23 from ricsdl.syncstorage import SyncStorage
27 Provides convenient wrapper methods for using the SDL Python interface.
28 Optionally uses msgpack for binary (de)serialization:
29 see https://msgpack.org/index.html
31 Published as a standalone module (and kept separate from the Xapp
32 framework classes) so these features can be used outside Xapps.
35 def __init__(self, use_fake_sdl=False):
41 use_fake_sdl: bool (optional, default False)
42 if this is True, then use SDL's in-memory backend,
43 which is very useful for testing since it allows use
44 of SDL without a running SDL or Redis instance.
45 This can be used while developing an xapp and also
46 for monkeypatching during unit testing; e.g., the xapp
47 framework unit tests do this.
50 self._sdl = SyncStorage(fake_db_backend="dict")
52 self._sdl = SyncStorage()
55 def set(self, ns, key, value, usemsgpack=True):
57 Stores a key-value pair,
58 optionally serializing the value to bytes using msgpack.
60 TODO: discuss whether usemsgpack should *default* to True or
61 False here. This seems like a usage statistic question (that we
62 don't have enough data for yet). Are more uses for an xapp to
63 write/read their own data, or will more xapps end up reading data
64 written by some other thing? I think it's too early to know.
73 Object or byte array to store. See the `usemsgpack` parameter.
74 usemsgpack: boolean (optional, default is True)
75 Determines whether the value is serialized using msgpack before storing.
76 If usemsgpack is True, the msgpack function `packb` is invoked
77 on the value to yield a byte array that is then sent to SDL.
78 Stated differently, if usemsgpack is True, the value can be anything
79 that is serializable by msgpack.
80 If usemsgpack is False, the value must be bytes.
83 value = msgpack.packb(value, use_bin_type=True)
84 self._sdl.set(ns, {key: value})
86 def get(self, ns, key, usemsgpack=True):
88 Gets the value for the specified namespace and key,
89 optionally deserializing stored bytes using msgpack.
97 usemsgpack: boolean (optional, default is True)
98 If usemsgpack is True, the byte array stored by SDL is deserialized
99 using msgpack to yield the original object that was stored.
100 If usemsgpack is False, the byte array stored by SDL is returned
101 without further processing.
106 See the usemsgpack parameter for an explanation of the returned value type.
107 Answers None if the key is not found.
110 ret_dict = self._sdl.get(ns, {key})
112 result = ret_dict[key]
114 result = msgpack.unpackb(result, raw=False)
117 def find_and_get(self, ns, prefix, usemsgpack=True):
119 Gets all key-value pairs in the specified namespace
120 with keys that start with the specified prefix,
121 optionally deserializing stored bytes using msgpack.
129 usemsgpack: boolean (optional, default is True)
130 If usemsgpack is True, every byte array stored by SDL is deserialized
131 using msgpack to yield the original value that was stored.
132 If usemsgpack is False, every byte array stored by SDL is returned
133 without further processing.
137 Dictionary of key-value pairs
138 Each key has the specified prefix.
139 See the usemsgpack parameter for an explanation of the returned value types.
140 Answers an empty dictionary if no keys matched the prefix.
143 # note: SDL "*" usage is inconsistent with real python regex, where it would be ".*"
144 ret_dict = self._sdl.find_and_get(ns, "{0}*".format(prefix))
146 ret_dict = {k: msgpack.unpackb(v, raw=False) for k, v in ret_dict.items()}
149 def delete(self, ns, key):
151 Deletes the key-value pair with the specified key in the specified namespace.
160 self._sdl.remove(ns, {key})
163 def healthcheck(self):
165 Checks if the sdl connection is healthy.
171 return self._sdl.is_active()
172 #if self._sdl.is_active():