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
28 This is a wrapper around the SDL Python interface.
30 We do not embed the below directly in the Xapp classes because
31 this SDL wrapper is useful for other python apps, for example A1
32 Mediator uses this verbatim. Therefore, we leave this here as a
33 seperate instantiable object so it can be used outside of xapps
34 too. One could argue this get moved into *sdl itself*.
36 We currently use msgpack for binary (de)serialization:
37 https://msgpack.org/index.html
40 def __init__(self, use_fake_sdl=False):
47 if this is True (default: False), then SDLs "fake dict
48 backend" is used, which is very useful for testing since
49 it allows you to use SDL without any SDL or Redis deployed at
50 all. This can be used while developing your xapp, and also
51 for monkeypatching during unit testing (e.g., the xapp
52 framework unit tests do this).
55 self._sdl = SyncStorage(fake_db_backend="dict")
57 self._sdl = SyncStorage()
59 def set(self, ns, key, value, usemsgpack=True):
63 TODO: discuss whether usemsgpack should *default* to True or
64 False here. This seems like a usage statistic question (that we
65 don't have enough data for yet). Are more uses for an xapp to
66 write/read their own data, or will more xapps end up reading data
67 written by some other thing? I think it's too early to know
68 this. So we go with True as the very first user of this, a1, does
69 this. I'm open to changing this default to False later with
79 if usemsgpack is True, value can be anything serializable by msgpack
80 if usemsgpack is False, value must be bytes
81 usemsgpack: boolean (optional)
82 determines whether the value is serialized using msgpack
85 self._sdl.set(ns, {key: msgpack.packb(value, use_bin_type=True)})
87 self._sdl.set(ns, {key: value})
89 def get(self, ns, key, usemsgpack=True):
99 usemsgpack: boolean (optional)
100 if usemsgpack is True, the value is deserialized using msgpack
101 if usemsgpack is False, the value is returned as raw bytes
105 None (if not exist) or see above; depends on usemsgpack
107 ret_dict = self._sdl.get(ns, {key})
110 return msgpack.unpackb(ret_dict[key], raw=False)
115 def find_and_get(self, ns, prefix, usemsgpack=True):
117 get all k v pairs that start with prefix
127 usemsgpack: boolean (optional)
128 if usemsgpack is True, the value returned is a dict where each value has been deserialized using msgpack
129 if usemsgpack is False, the value returned is as a dict mapping keys to raw bytes
133 {} (if no keys match) or see above; depends on usemsgpack
136 # note: SDL "*" usage is inconsistent with real python regex, where it would be ".*"
137 ret_dict = self._sdl.find_and_get(ns, "{0}*".format(prefix))
139 return {k: msgpack.unpackb(v, raw=False) for k, v in ret_dict.items()}
142 def delete(self, ns, key):
153 self._sdl.remove(ns, {key})
155 def healthcheck(self):
157 checks if the sdl connection is healthy
163 return self._sdl.is_active()