[VOL-4621] OpenOnuGo: MIB audit leads to unexpected oper_state RECONCILING_FAILED

Change-Id: I2d77eab670b6f2ed97d1062af5f2f035bdbd6e92
diff --git a/VERSION b/VERSION
index 45929fe..8a9f876 100755
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.2-dev270
+2.2.2-dev271
diff --git a/internal/pkg/mib/mib_sync.go b/internal/pkg/mib/mib_sync.go
index 88fa8c6..a1cc82c 100755
--- a/internal/pkg/mib/mib_sync.go
+++ b/internal/pkg/mib/mib_sync.go
@@ -287,47 +287,7 @@
 func (oo *OnuDeviceEntry) enterVerifyingAndStoringTPsState(ctx context.Context, e *fsm.Event) {
 	logger.Debugw(ctx, "MibSync FSM", log.Fields{"Start verifying and storing TPs in State": e.FSM.Current(), "device-id": oo.deviceID})
 
-	allTpInstPresent := true
-	oo.MutexPersOnuConfig.Lock()
-	oo.MutexReconciledTpInstances.Lock()
-	for indexUni, uniData := range oo.SOnuPersistentData.PersUniConfig {
-		uniID := uniData.PersUniID
-		oo.ReconciledTpInstances[uniID] = make(map[uint8]inter_adapter.TechProfileDownloadMessage)
-		for tpID, tpPath := range uniData.PersTpPathMap {
-			if tpPath != "" {
-				// Request the TP instance from the openolt adapter
-				iaTechTpInst, err := oo.baseDeviceHandler.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
-				if err == nil && iaTechTpInst != nil {
-					logger.Debugw(ctx, "reconciling - store Tp instance", log.Fields{"uniID": uniID, "tpID": tpID,
-						"*iaTechTpInst": iaTechTpInst, "device-id": oo.deviceID})
-					oo.ReconciledTpInstances[uniID][tpID] = *iaTechTpInst
-				} else {
-					// During the absence of the ONU adapter there seem to have been TP specific configurations!
-					// The no longer available TP and the associated flows must be deleted from the ONU KV store
-					// and after a MIB reset a new reconciling attempt with OMCI configuration must be started.
-					allTpInstPresent = false
-					logger.Infow(ctx, "reconciling - can't get tp instance - delete tp and associated flows",
-						log.Fields{"tp-id": tpID, "tpPath": tpPath, "uni-id": uniID, "device-id": oo.deviceID, "err": err})
-					delete(oo.SOnuPersistentData.PersUniConfig[indexUni].PersTpPathMap, tpID)
-					flowSlice := oo.SOnuPersistentData.PersUniConfig[indexUni].PersFlowParams
-					for indexFlow, flowData := range flowSlice {
-						if flowData.VlanRuleParams.TpID == tpID {
-							if len(flowSlice) == 1 {
-								flowSlice = []cmn.UniVlanFlowParams{}
-							} else {
-								flowSlice = append(flowSlice[:indexFlow], flowSlice[indexFlow+1:]...)
-							}
-							oo.SOnuPersistentData.PersUniConfig[indexUni].PersFlowParams = flowSlice
-						}
-					}
-				}
-			}
-		}
-	}
-	oo.MutexReconciledTpInstances.Unlock()
-	oo.MutexPersOnuConfig.Unlock()
-
-	if allTpInstPresent {
+	if oo.getAllStoredTpInstFromParentAdapter(ctx) {
 		logger.Debugw(ctx, "MibSync FSM", log.Fields{"reconciling - verifying TPs successful": e.FSM.Current(), "device-id": oo.deviceID})
 		go func() {
 			_ = oo.PMibUploadFsm.PFsm.Event(UlEvSuccess)
@@ -1093,9 +1053,24 @@
 			logger.Debugw(ctx, "MibSync FSM - mib reaudit - MDS check ok", log.Fields{"device-id": oo.deviceID})
 			_ = oo.PMibUploadFsm.PFsm.Event(UlEvSuccess)
 		} else {
-			logger.Errorw(ctx, "MibSync FSM - mib audit - MDS check failed for the second time - send ONU device event!",
+			logger.Errorw(ctx, "MibSync FSM - mib reaudit - MDS check failed for the second time - send ONU device event and reconcile!",
 				log.Fields{"device-id": oo.deviceID})
 			oo.SendOnuDeviceEvent(ctx, cmn.OnuMibAuditFailureMds, cmn.OnuMibAuditFailureMdsDesc)
+			// To reconcile ONU with active adapter later on, we have to retrieve TP instances from parent adapter.
+			// In the present use case inconsistencies between TP pathes stored in kv store and TP instances retrieved
+			// should not occur. Nevertheless, the respective code is inserted to catch the unlikely case.
+			if !oo.getAllStoredTpInstFromParentAdapter(ctx) {
+				logger.Debugw(ctx, "MibSync FSM - mib reaudit - inconsistencies between TP pathes stored in kv and parent adapter instances",
+					log.Fields{"device-id": oo.deviceID})
+				oo.baseDeviceHandler.SetReconcilingReasonUpdate(true)
+				go func() {
+					if err := oo.baseDeviceHandler.StorePersistentData(ctx); err != nil {
+						logger.Warnw(ctx,
+							"MibSync FSM - mib reaudit - store persistent data error - continue for now as there will be additional write attempts",
+							log.Fields{"device-id": oo.deviceID, "err": err})
+					}
+				}()
+			}
 			_ = oo.PMibUploadFsm.PFsm.Event(UlEvMismatch)
 		}
 	} else if oo.PMibUploadFsm.PFsm.Is(UlStExaminingMds) {
@@ -1213,6 +1188,50 @@
 	return restoredFromMibTemplate
 }
 
+func (oo *OnuDeviceEntry) getAllStoredTpInstFromParentAdapter(ctx context.Context) bool {
+
+	allTpInstPresent := true
+	oo.MutexPersOnuConfig.Lock()
+	oo.MutexReconciledTpInstances.Lock()
+	for indexUni, uniData := range oo.SOnuPersistentData.PersUniConfig {
+		uniID := uniData.PersUniID
+		oo.ReconciledTpInstances[uniID] = make(map[uint8]inter_adapter.TechProfileDownloadMessage)
+		for tpID, tpPath := range uniData.PersTpPathMap {
+			if tpPath != "" {
+				// Request the TP instance from the openolt adapter
+				iaTechTpInst, err := oo.baseDeviceHandler.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
+				if err == nil && iaTechTpInst != nil {
+					logger.Debugw(ctx, "reconciling - store Tp instance", log.Fields{"uniID": uniID, "tpID": tpID,
+						"*iaTechTpInst": iaTechTpInst, "device-id": oo.deviceID})
+					oo.ReconciledTpInstances[uniID][tpID] = *iaTechTpInst
+				} else {
+					// During the absence of the ONU adapter there seem to have been TP specific configurations!
+					// The no longer available TP and the associated flows must be deleted from the ONU KV store
+					// and after a MIB reset a new reconciling attempt with OMCI configuration must be started.
+					allTpInstPresent = false
+					logger.Infow(ctx, "reconciling - can't get tp instance - delete tp and associated flows",
+						log.Fields{"tp-id": tpID, "tpPath": tpPath, "uni-id": uniID, "device-id": oo.deviceID, "err": err})
+					delete(oo.SOnuPersistentData.PersUniConfig[indexUni].PersTpPathMap, tpID)
+					flowSlice := oo.SOnuPersistentData.PersUniConfig[indexUni].PersFlowParams
+					for indexFlow, flowData := range flowSlice {
+						if flowData.VlanRuleParams.TpID == tpID {
+							if len(flowSlice) == 1 {
+								flowSlice = []cmn.UniVlanFlowParams{}
+							} else {
+								flowSlice = append(flowSlice[:indexFlow], flowSlice[indexFlow+1:]...)
+							}
+							oo.SOnuPersistentData.PersUniConfig[indexUni].PersFlowParams = flowSlice
+						}
+					}
+				}
+			}
+		}
+	}
+	oo.MutexReconciledTpInstances.Unlock()
+	oo.MutexPersOnuConfig.Unlock()
+	return allTpInstPresent
+}
+
 //CancelProcessing terminates potentially running reconciling processes and stops the FSM
 func (oo *OnuDeviceEntry) CancelProcessing(ctx context.Context) {