[VOL-4487] openonuAdapterGo - reconciling not working after ONU device disable

Change-Id: Ie816790f688b8bd4f2fd65454ec68ab32e7d85e7
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index 4274e90..27c0f52 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -843,16 +843,16 @@
 	_ = dh.createInterface(ctx, &onuIndication)
 }
 
-func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) {
+func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
 	logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
 
+	continueWithFlowConfig := false
+
 	pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
 	if pDevEntry == nil {
 		logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
-		if !dh.IsSkipOnuConfigReconciling() {
-			dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
-		}
-		return
+		dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
+		return continueWithFlowConfig
 	}
 	dh.pOnuTP.LockTpProcMutex()
 	defer dh.pOnuTP.UnlockTpProcMutex()
@@ -863,10 +863,8 @@
 		pDevEntry.MutexPersOnuConfig.RUnlock()
 		logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
 			log.Fields{"device-id": dh.DeviceID})
-		if !dh.IsSkipOnuConfigReconciling() {
-			dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
-		}
-		return
+		dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
+		return continueWithFlowConfig
 	}
 	flowsFound := false
 	techProfsFound := false
@@ -874,7 +872,7 @@
 outerLoop:
 	for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
 		//TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
-		if len(uniData.PersTpPathMap) == 0 {
+		if !dh.anyTpPathExists(uniData.PersTpPathMap) {
 			logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
 				log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
 			continue
@@ -898,11 +896,16 @@
 					UniId:          uint32(uniData.PersUniID),
 				})
 			if err != nil || iaTechTpInst == nil {
+				// TODO: During the absence of the ONU adapter there seem to have been TP specific configurations!
+				// The no longer available TPs 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.
 				logger.Errorw(ctx, "error fetching tp instance",
-					log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID, "err": err})
+					log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
+						"device-id": dh.DeviceID, "err": err})
 				techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
 				break outerLoop
 			}
+			continueWithFlowConfig = true // valid TP found - try flow configuration later
 			var tpInst tech_profile.TechProfileInstance
 			switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
 			case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
@@ -944,6 +947,8 @@
 
 	//had to move techProf/flow result evaluation into separate function due to SCA complexity limit
 	dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
+
+	return continueWithFlowConfig
 }
 
 func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
@@ -951,9 +956,7 @@
 	if !abTechProfsFound {
 		logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
 			log.Fields{"device-id": dh.DeviceID})
-		if !dh.IsSkipOnuConfigReconciling() {
-			dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
-		}
+		dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
 		return
 	}
 	if abTechProfInstLoadFailed {
@@ -966,9 +969,7 @@
 	if !abFlowsFound {
 		logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
 			log.Fields{"device-id": dh.DeviceID})
-		if !dh.IsSkipOnuConfigReconciling() {
-			dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
-		}
+		dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
 	}
 }
 
@@ -978,14 +979,7 @@
 	pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
 	if pDevEntry == nil {
 		logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
-		if !dh.IsSkipOnuConfigReconciling() {
-			dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
-		}
-		//else we don't stop the device handler reconciling in constellation with omci configuration
-		//  to avoid unintented state update to rwCore due to still running background processes
-		//  such is e.g. possible in TT scenarios with multiple techProfiles as currently the end of processing
-		//  of all techProfiles is not awaited (ready on first TP done event)
-		//  (applicable to all according code points below)
+		dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
 		return
 	}
 
@@ -994,9 +988,7 @@
 		pDevEntry.MutexPersOnuConfig.RUnlock()
 		logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
 			log.Fields{"device-id": dh.DeviceID})
-		if !dh.IsSkipOnuConfigReconciling() {
-			dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
-		}
+		dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
 		return
 	}
 	flowsFound := false
@@ -1010,7 +1002,7 @@
 				log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
 			continue
 		}
-		if len(uniData.PersTpPathMap) == 0 {
+		if !dh.anyTpPathExists(uniData.PersTpPathMap) {
 			logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
 				log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
 			// It doesn't make sense to configure any flows if no TPs are available
@@ -1027,9 +1019,7 @@
 		if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
 			logger.Errorw(ctx, "reconciling - OnuUniPort data not found  - terminate reconcilement",
 				log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
-			if !dh.IsSkipOnuConfigReconciling() {
-				dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
-			}
+			dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
 			return
 		}
 		//needed to split up function due to sca complexity
@@ -1049,9 +1039,7 @@
 	if !flowsFound {
 		logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
 			log.Fields{"device-id": dh.DeviceID})
-		if !dh.IsSkipOnuConfigReconciling() {
-			dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
-		}
+		dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
 		return
 	}
 
@@ -4418,3 +4406,13 @@
 func (dh *deviceHandler) GetUniPortMask() int {
 	return dh.pOpenOnuAc.config.UniPortMask
 }
+
+func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
+	tpPathFound := false
+	for _, tpPath := range aTpPathMap {
+		if tpPath != "" {
+			tpPathFound = true
+		}
+	}
+	return tpPathFound
+}