Once the ONU is marked as down, all the TP states are cleared in
'update_interface' method. Post this if it receives any Gem Port
or Tcont Delete message from the openolt adapter, they are not
honored. This information is not cleared from internal cache
in such scenarios. This leads issues to subsequent TP Add failures
(once the ONU comes back up), because the data on the ONU and
in internal cache are out-of-sync.
If Tcont/Gem Port delete arrives to openonu adapter from
openolt adapter, clear it from internal cache no matter what.
Openolt adapter is the authority of all the PON resources
and makes it is simpler for openonu adapter to just honor
the request related to these resources rather than using
complex intelligence.

Change-Id: I9326f9fa8438e5bb95746ee3c8bfb98c14033184
diff --git a/VERSION b/VERSION
index 59aa62c..7bf4b6a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.4.5
+2.4.6
diff --git a/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py b/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
index a159a91..5326d53 100644
--- a/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
+++ b/python/adapters/brcm_openomci_onu/brcm_openomci_onu_handler.py
@@ -683,14 +683,43 @@
                 self.log.error("mcast-vlan-not-configured-yet-failing-mcast-service-conf", uni_id=uni_id, tp_id=tp_id,
                                retry=retry_count)
 
+    def _clear_alloc_id_gem_port_from_internal_cache(self, alloc_id=None, gem_port_id=None):
+        tcont = None
+        gem_port = None
+        if alloc_id is not None:
+            self.log.debug("current-cached-tconts", tconts=list(self.pon_port.tconts.values()))
+            for tc in list(self.pon_port.tconts.values()):
+                if tc.alloc_id == alloc_id:
+                    self.log.info("removing-tcont-from-internal-cache",
+                                  alloc_id=alloc_id)
+                    tcont = tc
+                    self.pon_port.remove_tcont(tc.alloc_id, False)
+
+        if gem_port_id is not None:
+            self.log.debug("current-cached-gem-ports", gem_ports=list(self.pon_port.gem_ports.values()))
+            for gp in list(self.pon_port.gem_ports.values()):
+                if gp.gem_id == gem_port_id:
+                    self.log.info("removing-gem-from-internal-cache",
+                                  gem_port_id=gem_port_id, direction=gp.direction)
+                    gem_port = gp
+                    self.pon_port.remove_gem_id(gp.gem_id, gp.direction, False)
+
+        return tcont, gem_port
+
     def delete_tech_profile(self, uni_id, tp_path, alloc_id=None, gem_port_id=None):
         try:
             tp_table_id = self.extract_tp_id_from_path(tp_path)
-            if not uni_id in self._tech_profile_download_done:
+            # Extract the current set of TCONT and GEM Ports from the Handler's pon_port that are
+            # relevant to this task's UNI. It won't change. But, the underlying pon_port may change
+            # due to additional tasks on different UNIs. So, it we cannot use the pon_port affter
+            # this initializer
+            tcont, gem_port = self._clear_alloc_id_gem_port_from_internal_cache(alloc_id, gem_port_id)
+
+            if uni_id not in self._tech_profile_download_done:
                 self.log.warn("tp-key-is-not-present", uni_id=uni_id)
                 return
 
-            if not tp_table_id in self._tech_profile_download_done[uni_id]:
+            if tp_table_id not in self._tech_profile_download_done[uni_id]:
                 self.log.warn("tp-id-is-not-present", uni_id=uni_id, tp_id=tp_table_id)
                 return
 
@@ -703,24 +732,6 @@
                 self.log.error("alloc-id-and-gem-port-id-are-none", uni_id=uni_id, tp_id=tp_table_id)
                 return
 
-            # Extract the current set of TCONT and GEM Ports from the Handler's pon_port that are
-            # relevant to this task's UNI. It won't change. But, the underlying pon_port may change
-            # due to additional tasks on different UNIs. So, it we cannot use the pon_port affter
-            # this initializer
-            tcont = None
-            self.log.debug("current-cached-tconts", tconts=list(self.pon_port.tconts.values()))
-            for tc in list(self.pon_port.tconts.values()):
-                if tc.alloc_id == alloc_id:
-                    tcont = tc
-                    self.pon_port.remove_tcont(tc.alloc_id, False)
-
-            gem_port = None
-            self.log.debug("current-cached-gem-ports", gem_ports=list(self.pon_port.gem_ports.values()))
-            for gp in list(self.pon_port.gem_ports.values()):
-                if gp.gem_id == gem_port_id:
-                    gem_port = gp
-                    self.pon_port.remove_gem_id(gp.gem_id, gp.direction, False)
-
             @inlineCallbacks
             def success(_results):
                 if gem_port_id:
diff --git a/python/adapters/brcm_openomci_onu/omci/brcm_tp_setup_task.py b/python/adapters/brcm_openomci_onu/omci/brcm_tp_setup_task.py
index fbbe86a..13be4f5 100644
--- a/python/adapters/brcm_openomci_onu/omci/brcm_tp_setup_task.py
+++ b/python/adapters/brcm_openomci_onu/omci/brcm_tp_setup_task.py
@@ -210,8 +210,16 @@
                         if not isinstance(v, dict):
                             continue
                         alloc_check = v.get('attributes', {}).get('alloc_id', 0)
-                        # Some onu report both to indicate an available tcont
-                        if alloc_check == 0xFF or alloc_check == 0xFFFF:
+                        if alloc_check == tcont.alloc_id:
+                            # If any Tcont entity already refers to the alloc-id we want to use,
+                            # lets choose that Tcont entity.
+                            # This Tcont will be re-added to ONU and that is fine. The ONU reports that
+                            # the entity already exists, which is not an error.
+                            free_entity_id = k
+                            self.log.debug("tcont-entity-already-exists-on-onu-for-this-alloc-id",
+                                           tcont_entity_id=k, alloc_id=tcont.alloc_id)
+                            break
+                        elif alloc_check == 0xFF or alloc_check == 0xFFFF:
                             free_entity_id = k
                             break