A1 v2.1.0
[ric-plt/a1.git] / a1 / data.py
index d25f519..1f09691 100644 (file)
@@ -1,6 +1,14 @@
+"""
+Represents A1s database and database access functions.
+In the future, this may change to use a different backend, possibly dramatically.
+Hopefully, the access functions are a good api so nothing else has to change when this happens
+
+For now, the database is in memory.
+We use dict data structures (KV) with the expectation of having to move this into Redis
+"""
 # ==================================================================================
-#       Copyright (c) 2019 Nokia
-#       Copyright (c) 2018-2019 AT&T Intellectual Property.
+#       Copyright (c) 2019-2020 Nokia
+#       Copyright (c) 2018-2020 AT&T Intellectual Property.
 #
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 # ==================================================================================
-
-"""
-Represents A1s database and database access functions.
-In the future, this may change to use a different backend, possibly dramatically.
-Hopefully, the access functions are a good api so nothing else has to change when this happens
-
-For now, the database is in memory.
-We use dict data structures (KV) with the expectation of having to move this into Redis
-"""
 import os
 import time
 from threading import Thread
 import msgpack
+from mdclogpy import Logger
+
+from ricsdl.syncstorage import SyncStorage
+
 from a1.exceptions import PolicyTypeNotFound, PolicyInstanceNotFound, PolicyTypeAlreadyExists, CantDeleteNonEmptyType
-from a1 import get_module_logger
 
-logger = get_module_logger(__name__)
+mdc_logger = Logger(name=__name__)
 
 
 INSTANCE_DELETE_NO_RESP_TTL = int(os.environ.get("INSTANCE_DELETE_NO_RESP_TTL", 5))
 INSTANCE_DELETE_RESP_TTL = int(os.environ.get("INSTANCE_DELETE_RESP_TTL", 5))
 
+A1NS = "A1m_ns"
+
 
 class SDLWrapper:
     """
@@ -47,25 +51,30 @@ class SDLWrapper:
     """
 
     def __init__(self):
-        self.POLICY_DATA = {}
+        self.sdl = SyncStorage()
 
     def set(self, key, value):
         """set a key"""
-        self.POLICY_DATA[key] = msgpack.packb(value, use_bin_type=True)
+        self.sdl.set(A1NS, {key: msgpack.packb(value, use_bin_type=True)})
 
     def get(self, key):
         """get a key"""
-        if key in self.POLICY_DATA:
-            return msgpack.unpackb(self.POLICY_DATA[key], raw=False)
+        ret_dict = self.sdl.get(A1NS, {key})
+        if key in ret_dict:
+            return msgpack.unpackb(ret_dict[key], raw=False)
+
         return None
 
     def find_and_get(self, prefix):
         """get all k v pairs that start with prefix"""
-        return {k: msgpack.unpackb(v, raw=False) for k, v in self.POLICY_DATA.items() if k.startswith(prefix)}
+        ret_dict = self.sdl.find_and_get(A1NS, "{0}".format(prefix), atomic=True)
+        found = {k: msgpack.unpackb(v, raw=False) for k, v in ret_dict.items()}
+        # TODO: upgrade to sdl 2.0.0 which does the sorting for us
+        return {k: found[k] for k in sorted(found)}
 
     def delete(self, key):
         """ delete a key"""
-        del self.POLICY_DATA[key]
+        self.sdl.remove(A1NS, {key})
 
 
 SDL = SDLWrapper()
@@ -182,8 +191,7 @@ def _delete_after(policy_type_id, policy_instance_id, ttl):
     _clear_handlers(policy_type_id, policy_instance_id)  # delete all the handlers
     SDL.delete(_generate_instance_key(policy_type_id, policy_instance_id))  # delete instance
     SDL.delete(_generate_instance_metadata_key(policy_type_id, policy_instance_id))  # delete instance metadata
-    logger.debug("type %s instance %s deleted", policy_type_id, policy_instance_id)
-    raise PolicyInstanceNotFound()
+    mdc_logger.debug("type {0} instance {1} deleted".format(policy_type_id, policy_instance_id))
 
 
 # Types