+
+class SDLWrapper:
+ """
+ This is a wrapper around the expected SDL Python interface.
+ The usage of POLICY_DATA will be replaced with SDL when SDL for python is available.
+ The eventual SDL API is expected to be very close to what is here.
+
+ We use msgpack for binary (de)serialization: https://msgpack.org/index.html
+ """
+
+ def __init__(self):
+ self.POLICY_DATA = {}
+
+ def set(self, key, value):
+ """set a key"""
+ self.POLICY_DATA[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)
+ 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)}
+
+ def delete(self, key):
+ """ delete a key"""
+ del self.POLICY_DATA[key]
+
+
+SDL = SDLWrapper()
+
+TYPE_PREFIX = "a1.policy_type."
+INSTANCE_PREFIX = "a1.policy_instance."
+HANDLER_PREFIX = "a1.policy_handler."
+
+
+# Internal helpers
+
+
+def _generate_type_key(policy_type_id):
+ """
+ generate a key for a policy type
+ """
+ return "{0}{1}".format(TYPE_PREFIX, policy_type_id)
+
+
+def _generate_instance_key(policy_type_id, policy_instance_id):
+ """
+ generate a key for a policy instance
+ """
+ return "{0}{1}.{2}".format(INSTANCE_PREFIX, policy_type_id, policy_instance_id)
+
+
+def _generate_handler_prefix(policy_type_id, policy_instance_id):
+ """
+ generate the prefix to a handler key
+ """
+ return "{0}{1}.{2}.".format(HANDLER_PREFIX, policy_type_id, policy_instance_id)
+
+
+def _generate_handler_key(policy_type_id, policy_instance_id, handler_id):
+ """
+ generate a key for a policy handler
+ """
+ return "{0}{1}".format(_generate_handler_prefix(policy_type_id, policy_instance_id), handler_id)
+
+
+def _get_statuses(policy_type_id, policy_instance_id):
+ """
+ shared helper to get statuses for an instance
+ """
+ instance_is_valid(policy_type_id, policy_instance_id)
+ prefixes_for_handler = "{0}{1}.{2}.".format(HANDLER_PREFIX, policy_type_id, policy_instance_id)
+ return list(SDL.find_and_get(prefixes_for_handler).values())
+
+
+def _get_instance_list(policy_type_id):
+ """
+ shared helper to get instance list for a type
+ """
+ type_is_valid(policy_type_id)
+ prefixes_for_type = "{0}{1}.".format(INSTANCE_PREFIX, policy_type_id)
+ instancekeys = SDL.find_and_get(prefixes_for_type).keys()
+ return [k.split(prefixes_for_type)[1] for k in instancekeys]
+
+
+def _clear_handlers(policy_type_id, policy_instance_id):
+ """
+ delete all the handlers for a policy instance
+ """
+ all_handlers_pref = _generate_handler_prefix(policy_type_id, policy_instance_id)
+ keys = SDL.find_and_get(all_handlers_pref)
+ for k in keys:
+ SDL.delete(k)
+