VOL-1344:
1) Place all of resource manager and tech profile KV store data under /service/voltha
2) Ensure flow_ids are released on the KV store when device is deleted
3) Ensure pon resources are re-used on voltha restart
4) Few other code re-organization and bug fixes

Change-Id: Ia7bc8062d88b7a8eec5d4b87209536d81b115575
diff --git a/common/pon_resource_manager/resource_kv_store.py b/common/pon_resource_manager/resource_kv_store.py
index a1a5c14..307b0cd 100644
--- a/common/pon_resource_manager/resource_kv_store.py
+++ b/common/pon_resource_manager/resource_kv_store.py
@@ -21,7 +21,7 @@
 from voltha.core.config.config_backend import EtcdStore

 

 # KV store uses this prefix to store resource info

-PATH_PREFIX = 'resource_manager/{}'

+PATH_PREFIX = 'service/voltha/resource_manager/{}'

 

 

 class ResourceKvStore(object):

diff --git a/common/pon_resource_manager/resource_manager.py b/common/pon_resource_manager/resource_manager.py
index a88b407..bdb45ee 100644
--- a/common/pon_resource_manager/resource_manager.py
+++ b/common/pon_resource_manager/resource_manager.py
@@ -578,7 +578,17 @@
                          else False
         """
         status = False
-
+        known_resource_types = [PONResourceManager.ONU_ID,
+                                PONResourceManager.ALLOC_ID,
+                                PONResourceManager.GEMPORT_ID,
+                                PONResourceManager.FLOW_ID]
+        if resource_type not in known_resource_types:
+            self._log.error("unknown-resource-type",
+                            resource_type=resource_type)
+            return status
+        if release_content is None:
+            self._log.debug("nothing-to-release")
+            return status
         # delegate to the master instance if sharing enabled across instances
         shared_resource_mgr = self.shared_resource_mgrs[self.shared_idx_by_type[resource_type]]
         if shared_resource_mgr is not None and shared_resource_mgr is not self:
@@ -590,17 +600,13 @@
 
         try:
             resource = self._get_resource(path)
-            if resource is not None and (
-                    resource_type == PONResourceManager.ONU_ID or
-                    resource_type == PONResourceManager.FLOW_ID):
-                self._release_id(resource, release_content)
-            elif resource is not None and (
-                    resource_type == PONResourceManager.ALLOC_ID or
-                    resource_type == PONResourceManager.GEMPORT_ID):
+            if resource is None:
+                raise Exception("get-resource-failed")
+            if isinstance(release_content, list):
                 for content in release_content:
                     self._release_id(resource, content)
             else:
-                raise Exception("get-resource-failed")
+                self._release_id(resource, release_content)
 
             self._log.debug("Free-" + resource_type + "-success", path=path)
 
@@ -673,16 +679,40 @@
         :param pon_intf_onu_id: reference of PON interface id and onu id
         """
         # remove pon_intf_onu_id tuple to alloc_ids map
-        alloc_id_path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
-            self.device_id, str(pon_intf_onu_id)
-        )
-        self._kv_store.remove_from_kv_store(alloc_id_path)
+        try:
+            alloc_id_path = PONResourceManager.ALLOC_ID_RESOURCE_MAP_PATH.format(
+                self.device_id, str(pon_intf_onu_id)
+            )
+            self._kv_store.remove_from_kv_store(alloc_id_path)
+        except Exception as e:
+            self._log.error("error-removing-alloc-id", e=e)
 
-        # remove pon_intf_onu_id tuple to gemport_ids map
-        gemport_id_path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
-            self.device_id, str(pon_intf_onu_id)
-        )
-        self._kv_store.remove_from_kv_store(gemport_id_path)
+        try:
+            # remove pon_intf_onu_id tuple to gemport_ids map
+            gemport_id_path = PONResourceManager.GEMPORT_ID_RESOURCE_MAP_PATH.format(
+                self.device_id, str(pon_intf_onu_id)
+            )
+            self._kv_store.remove_from_kv_store(gemport_id_path)
+        except Exception as e:
+            self._log.error("error-removing-gem-ports", e=e)
+
+        flow_id_path = PONResourceManager.FLOW_ID_RESOURCE_MAP_PATH.format(
+            self.device_id, str(pon_intf_onu_id))
+        flow_ids = self._kv_store.get_from_kv_store(flow_id_path)
+
+        if flow_ids and isinstance(flow_ids, list):
+            for flow_id in flow_ids:
+                try:
+                    flow_id_info_path = PONResourceManager.FLOW_ID_INFO_PATH.format(
+                                        self.device_id, str(pon_intf_onu_id), flow_id)
+                    self._kv_store.remove_from_kv_store(flow_id_info_path)
+                except Exception as e:
+                    self._log.error("error-removing-flow-info", flow_id=flow_id, e=e)
+                    continue
+        try:
+            self._kv_store.remove_from_kv_store(flow_id_path)
+        except Exception as e:
+            self._log.error("error-removing-flow-ids", e=e)
 
     def get_current_alloc_ids_for_onu(self, pon_intf_onu_id):
         """
diff --git a/common/tech_profile/tech_profile.py b/common/tech_profile/tech_profile.py
index c3a9993..150667e 100644
--- a/common/tech_profile/tech_profile.py
+++ b/common/tech_profile/tech_profile.py
@@ -24,7 +24,6 @@
 from voltha.registry import registry

 from voltha.adapters.openolt.protos import openolt_pb2

 

-

 # logger

 log = structlog.get_logger()

 

@@ -126,7 +125,7 @@
     pbits = ['0b11111111']

 

     # Tech profile path prefix in kv store

-    KV_STORE_TECH_PROFILE_PATH_PREFIX = 'voltha/technology_profiles'

+    KV_STORE_TECH_PROFILE_PATH_PREFIX = 'service/voltha/technology_profiles'

 

     # Tech profile path in kv store

     TECH_PROFILE_PATH = '{}/{}'  # <technology>/<table_id>

@@ -174,13 +173,13 @@
                 host, port = self.args.etcd.split(':', 1)

                 self._kv_store = EtcdStore(

                     host, port, TechProfile.

-                        KV_STORE_TECH_PROFILE_PATH_PREFIX)

+                    KV_STORE_TECH_PROFILE_PATH_PREFIX)

             elif self.args.backend == 'consul':

                 # KV store's IP Address and PORT

                 host, port = self.args.consul.split(':', 1)

                 self._kv_store = ConsulStore(

                     host, port, TechProfile.

-                        KV_STORE_TECH_PROFILE_PATH_PREFIX)

+                    KV_STORE_TECH_PROFILE_PATH_PREFIX)

 

             # self.tech_profile_instance_store = dict()

         except Exception as e:

@@ -257,17 +256,14 @@
                       path=path, tech_profile_instance=None, exception=e)

             return None

 

-    def delete_tech_profile_instance(self, table_id, uni_port_name):

-        # path to delete tech profile instance json from kv store

-        path = TechProfile.TECH_PROFILE_INSTANCE_PATH.format(

-            self.resource_mgr.technology, table_id, uni_port_name)

+    def delete_tech_profile_instance(self, tp_path):

 

         try:

-            del self._kv_store[path]

-            log.debug("Delete-tech-profile-instance-success", path=path)

+            del self._kv_store[tp_path]

+            log.debug("Delete-tech-profile-instance-success", path=tp_path)

             return True

         except Exception as e:

-            log.debug("Delete-tech-profile-instance-failed", path=path,

+            log.debug("Delete-tech-profile-instance-failed", path=tp_path,

                       exception=e)

             return False

 

@@ -537,7 +533,7 @@
 

             gemport_list = list()

             if isinstance(gem_ports, int):

-               gemport_list.append(gem_ports)

+                gemport_list.append(gem_ports)

             elif isinstance(gem_ports, list):

                 for gem in gem_ports:

                     gemport_list.append(gem)