VOL-4670: Fix for flowIDsForGem cache in openolt adapter
          resource manager is not updated on adapter restarts

- The cache flowIDsForGem is empty on adapter restarts.
  So use GetFlowIDsForGem API to update the cache and use it.

VOL-4672: Stale etcd data in openolt adapter after olt device delete

- If OLT device is getting deleted ignore ChildDeviceLost processing.
  The ChildDeviceLost could create entries already cleaned up by
  OLT device delete processing under some race conditions.

Change-Id: I535d9c968acb6bcee897fea49c78362230a52ac9
diff --git a/VERSION b/VERSION
index af8c8ec..f8b9971 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-4.2.2
+4.2.3-dev
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 78e2eb3..bfdd3ee 100644
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -2495,6 +2495,13 @@
 // ChildDeviceLost deletes ONU and clears pon resources related to it.
 func (dh *DeviceHandler) ChildDeviceLost(ctx context.Context, pPortNo uint32, onuID uint32, onuSn string) error {
 	logger.Debugw(ctx, "child-device-lost", log.Fields{"parent-device-id": dh.device.Id})
+	if dh.getDeviceDeletionInProgressFlag() {
+		// Given that the OLT device itself is getting deleted, everything will be cleaned up in the DB and the OLT
+		// will reboot, so everything will be reset on the pOLT too.
+		logger.Infow(ctx, "olt-device-delete-in-progress-not-handling-child-device-lost",
+			log.Fields{"parent-device-id": dh.device.Id, "pon-port": pPortNo, "onuID": onuID, "onuSN": onuSn})
+		return nil
+	}
 	intfID := plt.PortNoToIntfID(pPortNo, voltha.Port_PON_OLT)
 	onuKey := dh.formOnuKey(intfID, onuID)
 
diff --git a/internal/pkg/core/openolt_flowmgr.go b/internal/pkg/core/openolt_flowmgr.go
index 06ad2c0..3d5b490 100644
--- a/internal/pkg/core/openolt_flowmgr.go
+++ b/internal/pkg/core/openolt_flowmgr.go
@@ -1954,12 +1954,18 @@
 	case *tp_pb.TechProfileInstance:
 		for _, gemPort := range techprofileInst.UpstreamGemPortAttributeList {
 			gemPortID := gemPort.GemportId
-			used := f.resourceMgr.IsGemPortUsedByAnotherFlow(gemPortID, flowID)
-			if used {
-				flowIDs, err := f.resourceMgr.GetFlowIDsForGem(ctx, gemPortID)
-				if err != nil {
-					return err
+			flowIDs, err := f.resourceMgr.GetFlowIDsForGem(ctx, gemPortID)
+			if err != nil {
+				return err
+			}
+			used := false
+			for _, id := range flowIDs {
+				if flowID != id {
+					used = true
+					break
 				}
+			}
+			if used {
 				for i, flowIDinMap := range flowIDs {
 					if flowIDinMap == flowID {
 						flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
diff --git a/internal/pkg/resourcemanager/resourcemanager.go b/internal/pkg/resourcemanager/resourcemanager.go
index 9566637..af281f4 100755
--- a/internal/pkg/resourcemanager/resourcemanager.go
+++ b/internal/pkg/resourcemanager/resourcemanager.go
@@ -1236,29 +1236,27 @@
 }
 
 // IsGemPortUsedByAnotherFlow returns true if given gem is used by another flow
-func (rsrcMgr *OpenOltResourceMgr) IsGemPortUsedByAnotherFlow(gemPortID uint32, flowID uint64) bool {
-	rsrcMgr.flowIDsForGemLock.RLock()
-	flowIDList := rsrcMgr.flowIDsForGem[gemPortID]
-	rsrcMgr.flowIDsForGemLock.RUnlock()
+func (rsrcMgr *OpenOltResourceMgr) IsGemPortUsedByAnotherFlow(ctx context.Context, gemPortID uint32, flowID uint64) (bool, error) {
+	flowIDList, err := rsrcMgr.GetFlowIDsForGem(ctx, gemPortID)
+	if err != nil {
+		return false, err
+	}
 	for _, id := range flowIDList {
 		if flowID != id {
-			return true
+			return true, nil
 		}
 	}
-	return false
+	return false, nil
 }
 
 // RegisterFlowIDForGem updates both cache and KV store for flowIDsForGem map
 func (rsrcMgr *OpenOltResourceMgr) RegisterFlowIDForGem(ctx context.Context, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
-	// get from cache
-	rsrcMgr.flowIDsForGemLock.RLock()
-	flowIDs, ok := rsrcMgr.flowIDsForGem[gemPortID]
-	rsrcMgr.flowIDsForGemLock.RUnlock()
-	if !ok {
-		flowIDs = []uint64{flowFromCore.Id}
-	} else {
-		flowIDs = appendUnique64bit(flowIDs, flowFromCore.Id)
+	flowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, gemPortID)
+	if err != nil {
+		return err
 	}
+
+	flowIDs = appendUnique64bit(flowIDs, flowFromCore.Id)
 	// update the flowids for a gem to the KVstore
 	return rsrcMgr.UpdateFlowIDsForGem(ctx, gemPortID, flowIDs)
 }