VOL-2868 Remove all uses of Proxy.RegisterCallback(...)

Change-Id: I05d47a9915071adb80ebc3c5f9b129ed6c36b54b
diff --git a/Makefile b/Makefile
index d5cf486..271ba44 100644
--- a/Makefile
+++ b/Makefile
@@ -143,7 +143,7 @@
 	@rm -rf ./sca-report
 	@mkdir -p ./sca-report
 	@echo "Running static code analysis..."
-	@${GOLANGCI_LINT} run --deadline=4m --out-format junit-xml ./... | tee ./sca-report/sca-report.xml
+	@${GOLANGCI_LINT} run --deadline=6m --out-format junit-xml ./... | tee ./sca-report/sca-report.xml
 	@echo ""
 	@echo "Static code analysis OK"
 
diff --git a/rw_core/core/adapter_manager.go b/rw_core/core/adapter_manager.go
index 712f51d..383600d 100644
--- a/rw_core/core/adapter_manager.go
+++ b/rw_core/core/adapter_manager.go
@@ -18,8 +18,8 @@
 
 import (
 	"context"
+	"errors"
 	"fmt"
-	"reflect"
 	"sync"
 	"time"
 
@@ -75,12 +75,6 @@
 	return aa.adapter
 }
 
-func (aa *AdapterAgent) updateAdapter(adapter *voltha.Adapter) {
-	aa.lock.Lock()
-	defer aa.lock.Unlock()
-	aa.adapter = adapter
-}
-
 func (aa *AdapterAgent) updateDeviceType(deviceType *voltha.DeviceType) {
 	aa.lock.Lock()
 	defer aa.lock.Unlock()
@@ -108,8 +102,6 @@
 	adapterAgents               map[string]*AdapterAgent
 	deviceTypeToAdapterMap      map[string]string
 	clusterDataProxy            *model.Proxy
-	adapterProxy                *model.Proxy
-	deviceTypeProxy             *model.Proxy
 	deviceMgr                   *DeviceManager
 	coreInstanceID              string
 	exitChannel                 chan int
@@ -141,21 +133,6 @@
 		return err
 	}
 
-	//// Create the proxies
-	aMgr.adapterProxy, err = aMgr.clusterDataProxy.CreateProxy(ctx, "/adapters", false)
-	if err != nil {
-		logger.Errorw("Failed-to-create-adapter-proxy", log.Fields{"error": err})
-		return err
-	}
-	aMgr.deviceTypeProxy, err = aMgr.clusterDataProxy.CreateProxy(ctx, "/device_types", false)
-	if err != nil {
-		logger.Errorw("Failed-to-create-device-proxy", log.Fields{"error": err})
-		return err
-	}
-
-	// Register the callbacks
-	aMgr.adapterProxy.RegisterCallback(model.PostUpdate, aMgr.adapterUpdated)
-	aMgr.deviceTypeProxy.RegisterCallback(model.PostUpdate, aMgr.deviceTypesUpdated)
 	probe.UpdateStatusFromContext(ctx, "adapter-manager", probe.ServiceStatusRunning)
 	logger.Info("adapter-manager-started")
 	return nil
@@ -224,8 +201,6 @@
 	defer aMgr.lockAdaptersMap.Unlock()
 	logger.Debugw("adding-adapter", log.Fields{"adapter": adapter})
 	if _, exist := aMgr.adapterAgents[adapter.Id]; !exist {
-		clonedAdapter := (proto.Clone(adapter)).(*voltha.Adapter)
-		aMgr.adapterAgents[adapter.Id] = newAdapterAgent(clonedAdapter, nil)
 		if saveToDb {
 			// Save the adapter to the KV store - first check if it already exist
 			kvAdapter, err := aMgr.clusterDataProxy.Get(context.Background(), "/adapters/"+adapter.Id, 0, false, "")
@@ -234,7 +209,7 @@
 				return err
 			}
 			if kvAdapter == nil {
-				added, err := aMgr.clusterDataProxy.AddWithID(context.Background(), "/adapters", adapter.Id, clonedAdapter, "")
+				added, err := aMgr.clusterDataProxy.AddWithID(context.Background(), "/adapters", adapter.Id, adapter, "")
 				if err != nil {
 					logger.Errorw("failed-to-save-adapter-to-cluster-proxy", log.Fields{"error": err})
 					return err
@@ -242,11 +217,13 @@
 				if added == nil {
 					//TODO:  Errors when saving to KV would require a separate go routine to be launched and try the saving again
 					logger.Errorw("failed-to-save-adapter", log.Fields{"adapter": adapter})
-				} else {
-					logger.Debugw("adapter-saved-to-KV-Store", log.Fields{"adapter": adapter})
+					return errors.New("failed-to-save-adapter")
 				}
+				logger.Debugw("adapter-saved-to-KV-Store", log.Fields{"adapter": adapter})
 			}
 		}
+		clonedAdapter := (proto.Clone(adapter)).(*voltha.Adapter)
+		aMgr.adapterAgents[adapter.Id] = newAdapterAgent(clonedAdapter, nil)
 	}
 	return nil
 }
@@ -260,18 +237,9 @@
 	defer aMgr.lockAdaptersMap.Unlock()
 	aMgr.lockdDeviceTypeToAdapterMap.Lock()
 	defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
-	for _, deviceType := range deviceTypes.Items {
-		clonedDType := (proto.Clone(deviceType)).(*voltha.DeviceType)
-		if adapterAgent, exist := aMgr.adapterAgents[clonedDType.Adapter]; exist {
-			adapterAgent.updateDeviceType(clonedDType)
-		} else {
-			logger.Debugw("adapter-not-exist", log.Fields{"deviceTypes": deviceTypes, "adapterId": clonedDType.Adapter})
-			aMgr.adapterAgents[clonedDType.Adapter] = newAdapterAgent(&voltha.Adapter{Id: clonedDType.Adapter}, deviceTypes)
-		}
-		aMgr.deviceTypeToAdapterMap[clonedDType.Id] = clonedDType.Adapter
-	}
+
 	if saveToDb {
-		// Save the device types to the KV store as well
+		// Save the device types to the KV store
 		for _, deviceType := range deviceTypes.Items {
 			dType, err := aMgr.clusterDataProxy.Get(context.Background(), "/device_types/"+deviceType.Id, 0, false, "")
 			if err != nil {
@@ -288,12 +256,23 @@
 				}
 				if added == nil {
 					logger.Errorw("failed-to-save-deviceType", log.Fields{"deviceType": deviceType})
-				} else {
-					logger.Debugw("device-type-saved-to-KV-Store", log.Fields{"deviceType": deviceType})
+					return errors.New("failed-to-save-deviceType")
 				}
+				logger.Debugw("device-type-saved-to-KV-Store", log.Fields{"deviceType": deviceType})
 			}
 		}
 	}
+	// and save locally
+	for _, deviceType := range deviceTypes.Items {
+		clonedDType := (proto.Clone(deviceType)).(*voltha.DeviceType)
+		if adapterAgent, exist := aMgr.adapterAgents[clonedDType.Adapter]; exist {
+			adapterAgent.updateDeviceType(clonedDType)
+		} else {
+			logger.Debugw("adapter-not-exist", log.Fields{"deviceTypes": deviceTypes, "adapterId": clonedDType.Adapter})
+			aMgr.adapterAgents[clonedDType.Adapter] = newAdapterAgent(&voltha.Adapter{Id: clonedDType.Adapter}, deviceTypes)
+		}
+		aMgr.deviceTypeToAdapterMap[clonedDType.Id] = clonedDType.Adapter
+	}
 	return nil
 }
 
@@ -320,40 +299,6 @@
 	return nil
 }
 
-//updateAdapter updates an adapter if it exist.  Otherwise, it creates it.
-func (aMgr *AdapterManager) updateAdapter(adapter *voltha.Adapter) {
-	aMgr.lockAdaptersMap.Lock()
-	defer aMgr.lockAdaptersMap.Unlock()
-	aMgr.updateAdapterWithoutLock(adapter)
-}
-
-func (aMgr *AdapterManager) updateAdapterWithoutLock(adapter *voltha.Adapter) {
-	if adapterAgent, ok := aMgr.adapterAgents[adapter.Id]; ok {
-		adapterAgent.updateAdapter(adapter)
-	} else {
-		aMgr.adapterAgents[adapter.Id] = newAdapterAgent(adapter, nil)
-	}
-}
-
-//updateDeviceType updates an adapter if it exist.  Otherwise, it creates it.
-func (aMgr *AdapterManager) updateDeviceType(deviceType *voltha.DeviceType) {
-	aMgr.lockAdaptersMap.Lock()
-	defer aMgr.lockAdaptersMap.Unlock()
-	aMgr.lockdDeviceTypeToAdapterMap.Lock()
-	defer aMgr.lockdDeviceTypeToAdapterMap.Unlock()
-	aMgr.updateDeviceTypeWithoutLock(deviceType)
-}
-
-func (aMgr *AdapterManager) updateDeviceTypeWithoutLock(deviceType *voltha.DeviceType) {
-	if adapterAgent, exist := aMgr.adapterAgents[deviceType.Adapter]; exist {
-		adapterAgent.updateDeviceType(deviceType)
-	} else {
-		aMgr.adapterAgents[deviceType.Adapter] = newAdapterAgent(&voltha.Adapter{Id: deviceType.Adapter},
-			&voltha.DeviceTypes{Items: []*voltha.DeviceType{deviceType}})
-	}
-	aMgr.deviceTypeToAdapterMap[deviceType.Id] = deviceType.Adapter
-}
-
 func (aMgr *AdapterManager) registerAdapter(adapter *voltha.Adapter, deviceTypes *voltha.DeviceTypes) (*voltha.CoreInstance, error) {
 	logger.Debugw("registerAdapter", log.Fields{"adapter": adapter, "deviceTypes": deviceTypes.Items})
 
@@ -421,69 +366,3 @@
 	}
 	return nil
 }
-
-//adapterUpdated is a callback invoked when an adapter change has been noticed
-func (aMgr *AdapterManager) adapterUpdated(ctx context.Context, args ...interface{}) interface{} {
-	logger.Debugw("updateAdapter-callback", log.Fields{"argsLen": len(args)})
-
-	var previousData *voltha.Adapters
-	var latestData *voltha.Adapters
-
-	var ok bool
-	if previousData, ok = args[0].(*voltha.Adapters); !ok {
-		logger.Errorw("invalid-args", log.Fields{"args0": args[0]})
-		return nil
-	}
-	if latestData, ok = args[1].(*voltha.Adapters); !ok {
-		logger.Errorw("invalid-args", log.Fields{"args1": args[1]})
-		return nil
-	}
-
-	if previousData != nil && latestData != nil {
-		if reflect.DeepEqual(previousData.Items, latestData.Items) {
-			logger.Debug("update-not-required")
-			return nil
-		}
-	}
-
-	if latestData != nil {
-		for _, adapter := range latestData.Items {
-			aMgr.updateAdapter(adapter)
-		}
-	}
-
-	return nil
-}
-
-//deviceTypesUpdated is a callback invoked when a device type change has been noticed
-func (aMgr *AdapterManager) deviceTypesUpdated(ctx context.Context, args ...interface{}) interface{} {
-	logger.Debugw("deviceTypesUpdated-callback", log.Fields{"argsLen": len(args)})
-
-	var previousData *voltha.DeviceTypes
-	var latestData *voltha.DeviceTypes
-
-	var ok bool
-	if previousData, ok = args[0].(*voltha.DeviceTypes); !ok {
-		logger.Errorw("invalid-args", log.Fields{"args0": args[0]})
-		return nil
-	}
-
-	if latestData, ok = args[1].(*voltha.DeviceTypes); !ok {
-		logger.Errorw("invalid-args", log.Fields{"args1": args[1]})
-		return nil
-	}
-
-	if previousData != nil && latestData != nil {
-		if reflect.DeepEqual(previousData.Items, latestData.Items) {
-			logger.Debug("update-not-required")
-			return nil
-		}
-	}
-
-	if latestData != nil {
-		for _, dType := range latestData.Items {
-			aMgr.updateDeviceType(dType)
-		}
-	}
-	return nil
-}
diff --git a/rw_core/core/device_agent.go b/rw_core/core/device_agent.go
index 37a79c8..4c2b9f6 100755
--- a/rw_core/core/device_agent.go
+++ b/rw_core/core/device_agent.go
@@ -48,7 +48,6 @@
 	adapterMgr       *AdapterManager
 	deviceMgr        *DeviceManager
 	clusterDataProxy *model.Proxy
-	deviceProxy      *model.Proxy
 	exitChannel      chan int
 	device           *voltha.Device
 	requestQueue     *coreutils.RequestQueue
@@ -143,11 +142,6 @@
 		}
 		agent.device = device
 	}
-	var err error
-	if agent.deviceProxy, err = agent.clusterDataProxy.CreateProxy(ctx, "/devices/"+agent.deviceID, false); err != nil {
-		return nil, err
-	}
-	agent.deviceProxy.RegisterCallback(model.PostUpdate, agent.processUpdate)
 
 	startSucceeded = true
 	logger.Debugw("device-agent-started", log.Fields{"device-id": agent.deviceID})
@@ -168,11 +162,6 @@
 
 	logger.Infow("stopping-device-agent", log.Fields{"deviceId": agent.deviceID, "parentId": agent.parentID})
 
-	// First unregister any callbacks
-	if agent.deviceProxy != nil {
-		agent.deviceProxy.UnregisterCallback(model.PostUpdate, agent.processUpdate)
-	}
-
 	//	Remove the device from the KV store
 	removed, err := agent.clusterDataProxy.Remove(ctx, "/devices/"+agent.deviceID, "")
 	if err != nil {
@@ -298,10 +287,7 @@
 
 	// Update the Admin State and set the operational state to activating before sending the request to the
 	// Adapters
-	cloned.AdminState = voltha.AdminState_ENABLED
-	cloned.OperStatus = voltha.OperStatus_ACTIVATING
-
-	if err := agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, ""); err != nil {
+	if err := agent.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_ENABLED, cloned.ConnectStatus, voltha.OperStatus_ACTIVATING); err != nil {
 		return err
 	}
 
@@ -768,9 +754,7 @@
 	}
 
 	// Update the Admin State and operational state before sending the request out
-	cloned.AdminState = voltha.AdminState_DISABLED
-	cloned.OperStatus = voltha.OperStatus_UNKNOWN
-	if err := agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, ""); err != nil {
+	if err := agent.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_DISABLED, cloned.ConnectStatus, voltha.OperStatus_UNKNOWN); err != nil {
 		return err
 	}
 
@@ -816,8 +800,7 @@
 
 	// No check is required when deleting a device.  Changing the state to DELETE will trigger the removal of this
 	// device by the state machine
-	cloned.AdminState = voltha.AdminState_DELETED
-	if err := agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, ""); err != nil {
+	if err := agent.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_DELETED, cloned.ConnectStatus, cloned.OperStatus); err != nil {
 		return err
 	}
 
@@ -887,14 +870,7 @@
 	cloned := agent.getDeviceWithoutLock()
 	cloned.PmConfigs = proto.Clone(pmConfigs).(*voltha.PmConfigs)
 	updateCtx := context.WithValue(ctx, model.RequestTimestamp, time.Now().UnixNano())
-	afterUpdate, err := agent.clusterDataProxy.Update(updateCtx, "/devices/"+agent.deviceID, cloned, false, "")
-	if err != nil {
-		return err
-	}
-	if afterUpdate == nil {
-		return status.Errorf(codes.Internal, "pm-kv-update-failed-for-device-id-%s", agent.deviceID)
-	}
-	return nil
+	return agent.updateDeviceInStoreWithoutLock(updateCtx, cloned, false, "")
 }
 
 func (agent *DeviceAgent) listPmConfigs(ctx context.Context) (*voltha.PmConfigs, error) {
@@ -934,16 +910,15 @@
 		// Save the image
 		clonedImg := proto.Clone(img).(*voltha.ImageDownload)
 		clonedImg.DownloadState = voltha.ImageDownload_DOWNLOAD_REQUESTED
-		cloned := proto.Clone(device).(*voltha.Device)
-		if cloned.ImageDownloads == nil {
-			cloned.ImageDownloads = []*voltha.ImageDownload{clonedImg}
+		if device.ImageDownloads == nil {
+			device.ImageDownloads = []*voltha.ImageDownload{clonedImg}
 		} else {
-			cloned.ImageDownloads = append(cloned.ImageDownloads, clonedImg)
+			device.ImageDownloads = append(device.ImageDownloads, clonedImg)
 		}
-		cloned.AdminState = voltha.AdminState_DOWNLOADING_IMAGE
-		if err := agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, ""); err != nil {
+		if err := agent.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_DOWNLOADING_IMAGE, device.ConnectStatus, device.OperStatus); err != nil {
 			return nil, err
 		}
+
 		// Send the request to the adapter
 		subCtx, cancel := context.WithTimeout(context.Background(), agent.defaultTimeout)
 		ch, err := agent.adapterProxy.downloadImage(ctx, cloned, clonedImg)
@@ -982,8 +957,7 @@
 	}
 
 	// Update image download state
-	cloned := proto.Clone(device).(*voltha.Device)
-	for _, image := range cloned.ImageDownloads {
+	for _, image := range device.ImageDownloads {
 		if image.Id == img.Id && image.Name == img.Name {
 			image.DownloadState = voltha.ImageDownload_DOWNLOAD_CANCELLED
 		}
@@ -991,8 +965,7 @@
 
 	if device.AdminState == voltha.AdminState_DOWNLOADING_IMAGE {
 		// Set the device to Enabled
-		cloned.AdminState = voltha.AdminState_ENABLED
-		if err := agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, ""); err != nil {
+		if err := agent.updateDeviceStateInStoreWithoutLock(ctx, device, voltha.AdminState_ENABLED, device.ConnectStatus, device.OperStatus); err != nil {
 			return nil, err
 		}
 		subCtx, cancel := context.WithTimeout(context.Background(), agent.defaultTimeout)
@@ -1029,8 +1002,7 @@
 		}
 	}
 	// Set the device to downloading_image
-	cloned.AdminState = voltha.AdminState_DOWNLOADING_IMAGE
-	if err := agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, ""); err != nil {
+	if err := agent.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_DOWNLOADING_IMAGE, cloned.ConnectStatus, cloned.OperStatus); err != nil {
 		return nil, err
 	}
 
@@ -1137,13 +1109,9 @@
 	if (img.DownloadState != voltha.ImageDownload_DOWNLOAD_REQUESTED &&
 		img.DownloadState != voltha.ImageDownload_DOWNLOAD_STARTED) ||
 		(img.ImageState != voltha.ImageDownload_IMAGE_ACTIVATING) {
-		cloned.AdminState = voltha.AdminState_ENABLED
+		return agent.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_ENABLED, cloned.ConnectStatus, cloned.OperStatus)
 	}
-
-	if err := agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, ""); err != nil {
-		return err
-	}
-	return nil
+	return agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, "")
 }
 
 func (agent *DeviceAgent) getImageDownload(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
@@ -1278,37 +1246,6 @@
 	return nil
 }
 
-// processUpdate is a respCallback invoked whenever there is a change on the device manages by this device agent
-func (agent *DeviceAgent) processUpdate(ctx context.Context, args ...interface{}) interface{} {
-	//// Run this respCallback in its own go routine
-	go func(args ...interface{}) interface{} {
-		var previous *voltha.Device
-		var current *voltha.Device
-		var ok bool
-		if len(args) == 2 {
-			if previous, ok = args[0].(*voltha.Device); !ok {
-				logger.Errorw("invalid-callback-type", log.Fields{"data": args[0]})
-				return nil
-			}
-			if current, ok = args[1].(*voltha.Device); !ok {
-				logger.Errorw("invalid-callback-type", log.Fields{"data": args[1]})
-				return nil
-			}
-		} else {
-			logger.Errorw("too-many-args-in-callback", log.Fields{"len": len(args)})
-			return nil
-		}
-		// Perform the state transition in it's own go routine
-		if err := agent.deviceMgr.processTransition(context.Background(), previous, current); err != nil {
-			logger.Errorw("failed-process-transition", log.Fields{"device-id": previous.Id,
-				"previous-admin-state": previous.AdminState, "current-admin-state": current.AdminState})
-		}
-		return nil
-	}(args...)
-
-	return nil
-}
-
 // updatePartialDeviceData updates a subset of a device that an Adapter can update.
 // TODO:  May need a specific proto to handle only a subset of a device that can be changed by an adapter
 func (agent *DeviceAgent) mergeDeviceInfoFromAdapter(device *voltha.Device) (*voltha.Device, error) {
@@ -1353,18 +1290,19 @@
 
 	cloned := agent.getDeviceWithoutLock()
 
+	newConnStatus, newOperStatus := cloned.ConnectStatus, cloned.OperStatus
 	// Ensure the enums passed in are valid - they will be invalid if they are not set when this function is invoked
 	if s, ok := voltha.ConnectStatus_Types_value[connStatus.String()]; ok {
 		logger.Debugw("updateDeviceStatus-conn", log.Fields{"ok": ok, "val": s})
-		cloned.ConnectStatus = connStatus
+		newConnStatus = connStatus
 	}
 	if s, ok := voltha.OperStatus_Types_value[operStatus.String()]; ok {
 		logger.Debugw("updateDeviceStatus-oper", log.Fields{"ok": ok, "val": s})
-		cloned.OperStatus = operStatus
+		newOperStatus = operStatus
 	}
 	logger.Debugw("updateDeviceStatus", log.Fields{"deviceId": cloned.Id, "operStatus": cloned.OperStatus, "connectStatus": cloned.ConnectStatus})
 	// Store the device
-	return agent.updateDeviceInStoreWithoutLock(ctx, cloned, false, "")
+	return agent.updateDeviceStateInStoreWithoutLock(ctx, cloned, cloned.AdminState, newConnStatus, newOperStatus)
 }
 
 func (agent *DeviceAgent) updatePortsOperState(ctx context.Context, operStatus voltha.OperStatus_Types) error {
@@ -1563,13 +1501,36 @@
 	return nil
 }
 
+func (agent *DeviceAgent) updateDeviceStateInStoreWithoutLock(
+	ctx context.Context,
+	device *voltha.Device,
+	adminState voltha.AdminState_Types,
+	connectStatus voltha.ConnectStatus_Types,
+	operStatus voltha.OperStatus_Types,
+) error {
+	previousState := getDeviceStates(device)
+	device.AdminState, device.ConnectStatus, device.OperStatus = adminState, connectStatus, operStatus
+
+	if err := agent.updateDeviceInStoreWithoutLock(ctx, device, false, ""); err != nil {
+		return err
+	}
+
+	// process state transition in its own thread
+	go func() {
+		if err := agent.deviceMgr.processTransition(context.Background(), device, previousState); err != nil {
+			log.Errorw("failed-process-transition", log.Fields{"deviceId": device.Id, "previousAdminState": previousState.Admin, "currentAdminState": device.AdminState})
+		}
+	}()
+	return nil
+}
+
 //This is an update operation to model without Lock.This function must never be invoked by another function unless the latter holds a lock on the device.
 // It is an internal helper function.
 func (agent *DeviceAgent) updateDeviceInStoreWithoutLock(ctx context.Context, device *voltha.Device, strict bool, txid string) error {
 	updateCtx := context.WithValue(ctx, model.RequestTimestamp, time.Now().UnixNano())
 	afterUpdate, err := agent.clusterDataProxy.Update(updateCtx, "/devices/"+agent.deviceID, device, strict, txid)
 	if err != nil {
-		return status.Errorf(codes.Internal, "failed-update-device:%s", agent.deviceID)
+		return status.Errorf(codes.Internal, "failed-update-device:%s: %s", agent.deviceID, err)
 	}
 	if afterUpdate == nil {
 		return status.Errorf(codes.Internal, "failed-update-device:%s", agent.deviceID)
@@ -1577,7 +1538,6 @@
 	logger.Debugw("updated-device-in-store", log.Fields{"deviceId: ": agent.deviceID})
 
 	agent.device = proto.Clone(device).(*voltha.Device)
-
 	return nil
 }
 
diff --git a/rw_core/core/device_manager.go b/rw_core/core/device_manager.go
index 1a1b773..b88f38b 100755
--- a/rw_core/core/device_manager.go
+++ b/rw_core/core/device_manager.go
@@ -247,7 +247,7 @@
 }
 
 // RunPostDeviceDelete removes any reference of this device
-func (dMgr *DeviceManager) RunPostDeviceDelete(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dMgr *DeviceManager) RunPostDeviceDelete(ctx context.Context, cDevice *voltha.Device) error {
 	logger.Infow("RunPostDeviceDelete", log.Fields{"deviceId": cDevice.Id})
 	dMgr.stopManagingDevice(ctx, cDevice.Id)
 	return nil
@@ -1027,17 +1027,26 @@
 	return childDevice, nil
 }
 
-func (dMgr *DeviceManager) processTransition(ctx context.Context, previous *voltha.Device, current *voltha.Device) error {
-	// This will be triggered on every update to the device.
-	handlers := dMgr.stateTransitions.GetTransitionHandler(previous, current)
+func (dMgr *DeviceManager) processTransition(ctx context.Context, device *voltha.Device, previousState *DeviceState) error {
+	// This will be triggered on every state update
+	logger.Debugw("state-transition", log.Fields{
+		"device":           device.Id,
+		"prev-admin-state": previousState.Admin,
+		"prev-oper-state":  previousState.Operational,
+		"prev-conn-state":  previousState.Connection,
+		"curr-admin-state": device.AdminState,
+		"curr-oper-state":  device.OperStatus,
+		"curr-conn-state":  device.ConnectStatus,
+	})
+	handlers := dMgr.stateTransitions.GetTransitionHandler(device, previousState)
 	if handlers == nil {
-		logger.Debugw("no-op-transition", log.Fields{"deviceId": current.Id})
+		logger.Debugw("no-op-transition", log.Fields{"deviceId": device.Id})
 		return nil
 	}
-	logger.Debugw("handler-found", log.Fields{"num-expectedHandlers": len(handlers), "isParent": current.Root, "current-data": current})
+	logger.Debugw("handler-found", log.Fields{"num-expectedHandlers": len(handlers), "isParent": device.Root, "current-data": device, "previous-state": previousState})
 	for _, handler := range handlers {
 		logger.Debugw("running-handler", log.Fields{"handler": funcName(handler)})
-		if err := handler(ctx, current, previous); err != nil {
+		if err := handler(ctx, device); err != nil {
 			logger.Warnw("handler-failed", log.Fields{"handler": funcName(handler), "error": err})
 			return err
 		}
@@ -1083,7 +1092,7 @@
 }
 
 // CreateLogicalDevice creates logical device in core
-func (dMgr *DeviceManager) CreateLogicalDevice(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dMgr *DeviceManager) CreateLogicalDevice(ctx context.Context, cDevice *voltha.Device) error {
 	logger.Info("CreateLogicalDevice")
 	// Verify whether the logical device has already been created
 	if cDevice.ParentId != "" {
@@ -1099,7 +1108,7 @@
 }
 
 // DeleteLogicalDevice deletes logical device from core
-func (dMgr *DeviceManager) DeleteLogicalDevice(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dMgr *DeviceManager) DeleteLogicalDevice(ctx context.Context, cDevice *voltha.Device) error {
 	logger.Info("DeleteLogicalDevice")
 	var err error
 	if err = dMgr.logicalDeviceMgr.deleteLogicalDevice(ctx, cDevice); err != nil {
@@ -1130,7 +1139,7 @@
 }
 
 // DeleteLogicalPorts removes the logical ports associated with that deviceId
-func (dMgr *DeviceManager) DeleteLogicalPorts(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dMgr *DeviceManager) DeleteLogicalPorts(ctx context.Context, cDevice *voltha.Device) error {
 	logger.Debugw("delete-all-logical-ports", log.Fields{"device-id": cDevice.Id})
 	if err := dMgr.logicalDeviceMgr.deleteLogicalPorts(ctx, cDevice.Id); err != nil {
 		// Just log the error.   The logical device or port may already have been deleted before this callback is invoked.
@@ -1159,7 +1168,7 @@
 		logger.Warnw("failed-getting-device", log.Fields{"deviceId": parentDeviceID, "error": err})
 		return err
 	}
-	return dMgr.DisableAllChildDevices(ctx, parentDevice, nil)
+	return dMgr.DisableAllChildDevices(ctx, parentDevice)
 }
 
 //childDevicesDetected is invoked by an adapter when child devices are found, typically after after a
@@ -1209,7 +1218,7 @@
 */
 
 //DisableAllChildDevices is invoked as a callback when the parent device is disabled
-func (dMgr *DeviceManager) DisableAllChildDevices(ctx context.Context, parentCurrDevice *voltha.Device, parentPrevDevice *voltha.Device) error {
+func (dMgr *DeviceManager) DisableAllChildDevices(ctx context.Context, parentCurrDevice *voltha.Device) error {
 	logger.Debug("DisableAllChildDevices")
 	var childDeviceIds []string
 	var err error
@@ -1231,7 +1240,7 @@
 }
 
 //DeleteAllChildDevices is invoked as a callback when the parent device is deleted
-func (dMgr *DeviceManager) DeleteAllChildDevices(ctx context.Context, parentCurrDevice *voltha.Device, parentPrevDevice *voltha.Device) error {
+func (dMgr *DeviceManager) DeleteAllChildDevices(ctx context.Context, parentCurrDevice *voltha.Device) error {
 	logger.Debug("DeleteAllChildDevices")
 	var childDeviceIds []string
 	var err error
@@ -1254,7 +1263,7 @@
 }
 
 //DeleteAllUNILogicalPorts is invoked as a callback when the parent device is deleted
-func (dMgr *DeviceManager) DeleteAllUNILogicalPorts(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error {
+func (dMgr *DeviceManager) DeleteAllUNILogicalPorts(ctx context.Context, curr *voltha.Device) error {
 	logger.Debugw("delete-all-uni-logical-ports", log.Fields{"parent-device-id": curr.Id})
 	if err := dMgr.logicalDeviceMgr.deleteAllUNILogicalPorts(ctx, curr); err != nil {
 		// Just log the error and let the remaining pipeline proceed - ports may already have been deleted
@@ -1264,7 +1273,7 @@
 }
 
 //DeleteAllLogicalPorts is invoked as a callback when the parent device's connection status moves to UNREACHABLE
-func (dMgr *DeviceManager) DeleteAllLogicalPorts(ctx context.Context, parentDevice *voltha.Device, prev *voltha.Device) error {
+func (dMgr *DeviceManager) DeleteAllLogicalPorts(ctx context.Context, parentDevice *voltha.Device) error {
 	logger.Debugw("delete-all-logical-ports", log.Fields{"parent-device-id": parentDevice.Id})
 	if err := dMgr.logicalDeviceMgr.deleteAllLogicalPorts(ctx, parentDevice); err != nil {
 		// Just log error as logical device may already have been deleted
@@ -1274,7 +1283,7 @@
 }
 
 //DeleteAllDeviceFlows is invoked as a callback when the parent device's connection status moves to UNREACHABLE
-func (dMgr *DeviceManager) DeleteAllDeviceFlows(ctx context.Context, parentDevice *voltha.Device, prev *voltha.Device) error {
+func (dMgr *DeviceManager) DeleteAllDeviceFlows(ctx context.Context, parentDevice *voltha.Device) error {
 	logger.Debugw("delete-all-device-flows", log.Fields{"parent-device-id": parentDevice.Id})
 	if agent := dMgr.getDeviceAgent(ctx, parentDevice.Id); agent != nil {
 		if err := agent.deleteAllFlows(ctx); err != nil {
@@ -1319,7 +1328,7 @@
 }
 
 // SetupUNILogicalPorts creates UNI ports on the logical device that represents a child UNI interface
-func (dMgr *DeviceManager) SetupUNILogicalPorts(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dMgr *DeviceManager) SetupUNILogicalPorts(ctx context.Context, cDevice *voltha.Device) error {
 	logger.Info("addUNILogicalPort")
 	if err := dMgr.logicalDeviceMgr.setupUNILogicalPorts(ctx, cDevice); err != nil {
 		logger.Warnw("addUNILogicalPort-error", log.Fields{"device": cDevice, "err": err})
@@ -1432,15 +1441,12 @@
 	return nil, status.Errorf(codes.NotFound, "%s", deviceID)
 }
 
-func (dMgr *DeviceManager) NotifyInvalidTransition(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dMgr *DeviceManager) NotifyInvalidTransition(_ context.Context, device *voltha.Device) error {
 	logger.Errorw("NotifyInvalidTransition", log.Fields{
-		"device":           cDevice.Id,
-		"prev-admin-state": pDevice.AdminState,
-		"prev-oper-state":  pDevice.OperStatus,
-		"prev-conn-state":  pDevice.ConnectStatus,
-		"curr-admin-state": cDevice.AdminState,
-		"curr-oper-state":  cDevice.OperStatus,
-		"curr-conn-state":  cDevice.ConnectStatus,
+		"device":           device.Id,
+		"curr-admin-state": device.AdminState,
+		"curr-oper-state":  device.OperStatus,
+		"curr-conn-state":  device.ConnectStatus,
 	})
 	//TODO: notify over kafka?
 	return nil
@@ -1516,7 +1522,7 @@
 }
 
 // childDeviceLost  calls parent adapter to delete child device and all its references
-func (dMgr *DeviceManager) ChildDeviceLost(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error {
+func (dMgr *DeviceManager) ChildDeviceLost(ctx context.Context, curr *voltha.Device) error {
 	logger.Debugw("childDeviceLost", log.Fields{"child-device-id": curr.Id, "parent-device-id": curr.ParentId})
 	if parentAgent := dMgr.getDeviceAgent(ctx, curr.ParentId); parentAgent != nil {
 		if err := parentAgent.ChildDeviceLost(ctx, curr); err != nil {
diff --git a/rw_core/core/device_state_transitions.go b/rw_core/core/device_state_transitions.go
index b8acafc..5c55b7c 100644
--- a/rw_core/core/device_state_transitions.go
+++ b/rw_core/core/device_state_transitions.go
@@ -68,7 +68,7 @@
 }
 
 // TransitionHandler function type which takes the current and previous device info as input parameter
-type TransitionHandler func(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
+type TransitionHandler func(context.Context, *voltha.Device) error
 
 // Transition represent transition related attributes
 type Transition struct {
@@ -284,11 +284,10 @@
 	return transition.handlers, m
 }
 
-// GetTransitionHandler returns transition handler
-func (tMap *TransitionMap) GetTransitionHandler(pDevice *voltha.Device, cDevice *voltha.Device) []TransitionHandler {
+// GetTransitionHandler returns transition handler & a flag that's set if the transition is invalid
+func (tMap *TransitionMap) GetTransitionHandler(device *voltha.Device, pState *DeviceState) []TransitionHandler {
 	//1. Get the previous and current set of states
-	pState := getDeviceStates(pDevice)
-	cState := getDeviceStates(cDevice)
+	cState := getDeviceStates(device)
 
 	// Do nothing is there are no states change
 	if *pState == *cState {
@@ -297,11 +296,11 @@
 
 	//logger.Infow("DeviceType", log.Fields{"device": pDevice})
 	deviceType := parent
-	if !pDevice.Root {
+	if !device.Root {
 		logger.Info("device is child")
 		deviceType = child
 	}
-	logger.Infof("deviceType:%d-deviceId:%s-previous:%v-current:%v", deviceType, pDevice.Id, pState, cState)
+	logger.Infof("deviceType:%d-deviceId:%s-previous:%v-current:%v", deviceType, device.Id, pState, cState)
 
 	//2. Go over transition array to get the right transition
 	var currentMatch []TransitionHandler
diff --git a/rw_core/core/device_state_transitions_test.go b/rw_core/core/device_state_transitions_test.go
index f7e94fb..464ca42 100644
--- a/rw_core/core/device_state_transitions_test.go
+++ b/rw_core/core/device_state_transitions_test.go
@@ -52,159 +52,167 @@
 	}
 }
 
-func assertInvalidTransition(t *testing.T, from *voltha.Device, to *voltha.Device) {
-	handlers := transitionMap.GetTransitionHandler(from, to)
+func getDeviceState(admin voltha.AdminState_Types, conn voltha.ConnectStatus_Types, oper voltha.OperStatus_Types) *DeviceState {
+	return &DeviceState{
+		Admin:       admin,
+		Connection:  conn,
+		Operational: oper,
+	}
+}
+
+func assertInvalidTransition(t *testing.T, device *voltha.Device, previousState *DeviceState) {
+	handlers := transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.NotifyInvalidTransition).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 }
 
-func assertNoOpTransition(t *testing.T, from *voltha.Device, to *voltha.Device) {
-	handlers := transitionMap.GetTransitionHandler(from, to)
+func assertNoOpTransition(t *testing.T, device *voltha.Device, previousState *DeviceState) {
+	handlers := transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 0, len(handlers))
 }
 
 func TestValidTransitions(t *testing.T) {
-	from := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	to := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	handlers := transitionMap.GetTransitionHandler(from, to)
+	previousState := getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	device := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
+	handlers := transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	to = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	to = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
-	to = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
+	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
-	to = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
+	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_DISCOVERED)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_DISCOVERED)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
-	to = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
+	device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
-	from = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
 
-	to = getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_FAILED)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
+	device = getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_FAILED)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 3, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.ChildDeviceLost).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 	assert.True(t, reflect.ValueOf(tdm.DeleteLogicalPorts).Pointer() == reflect.ValueOf(handlers[1]).Pointer())
 	assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[2]).Pointer())
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	to = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
+	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 4, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.DeleteAllLogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 	assert.True(t, reflect.ValueOf(tdm.DeleteLogicalDevice).Pointer() == reflect.ValueOf(handlers[1]).Pointer())
 	assert.True(t, reflect.ValueOf(tdm.DeleteAllChildDevices).Pointer() == reflect.ValueOf(handlers[2]).Pointer())
 	assert.True(t, reflect.ValueOf(tdm.DeleteAllDeviceFlows).Pointer() == reflect.ValueOf(handlers[3]).Pointer())
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
-	handlers = transitionMap.GetTransitionHandler(from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
+	handlers = transitionMap.GetTransitionHandler(device, previousState)
 	assert.Equal(t, 1, len(handlers))
 	assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
 
 	var deleteDeviceTest = struct {
-		from                   []*voltha.Device
-		to                     []*voltha.Device
+		previousStates         []*DeviceState
+		devices                []*voltha.Device
 		expectedParentHandlers []TransitionHandler
 		expectedChildHandlers  []TransitionHandler
 	}{
-		from: []*voltha.Device{
-			getDevice(false, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_FAILED),
-			getDevice(false, voltha.AdminState_UNKNOWN, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
-			getDevice(false, voltha.AdminState_DOWNLOADING_IMAGE, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
-			getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
-			getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE),
-			getDevice(false, voltha.AdminState_DISABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN),
-			getDevice(false, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN),
+		previousStates: []*DeviceState{
+			getDeviceState(voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_FAILED),
+			getDeviceState(voltha.AdminState_UNKNOWN, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
+			getDeviceState(voltha.AdminState_DOWNLOADING_IMAGE, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
+			getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
+			getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE),
+			getDeviceState(voltha.AdminState_DISABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN),
+			getDeviceState(voltha.AdminState_DISABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN),
 		},
-		to: []*voltha.Device{
+		devices: []*voltha.Device{
 			getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
 			getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN),
 			getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_FAILED),
@@ -225,12 +233,11 @@
 	}
 
 	testName := "delete-parent-device-post-provisioning"
-	for _, from := range deleteDeviceTest.from {
-		from.Root = true
-		for _, to := range deleteDeviceTest.to {
-			to.Root = true
+	for _, previousState := range deleteDeviceTest.previousStates {
+		for _, device := range deleteDeviceTest.devices {
+			device.Root = true
 			t.Run(testName, func(t *testing.T) {
-				handlers = transitionMap.GetTransitionHandler(from, to)
+				handlers = transitionMap.GetTransitionHandler(device, previousState)
 				assert.Equal(t, 6, len(handlers))
 				for idx, expHandler := range deleteDeviceTest.expectedParentHandlers {
 					assert.True(t, reflect.ValueOf(expHandler).Pointer() == reflect.ValueOf(handlers[idx]).Pointer())
@@ -240,12 +247,11 @@
 	}
 
 	testName = "delete-child-device"
-	for _, from := range deleteDeviceTest.from {
-		from.Root = false
-		for _, to := range deleteDeviceTest.to {
-			to.Root = false
+	for _, deviceState := range deleteDeviceTest.previousStates {
+		for _, device := range deleteDeviceTest.devices {
+			device.Root = false
 			t.Run(testName, func(t *testing.T) {
-				handlers = transitionMap.GetTransitionHandler(from, to)
+				handlers = transitionMap.GetTransitionHandler(device, deviceState)
 				assert.Equal(t, 3, len(handlers))
 				for idx, expHandler := range deleteDeviceTest.expectedChildHandlers {
 					assert.True(t, reflect.ValueOf(expHandler).Pointer() == reflect.ValueOf(handlers[idx]).Pointer())
@@ -256,59 +262,59 @@
 }
 
 func TestInvalidTransitions(t *testing.T) {
-	from := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
-	to := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	assertInvalidTransition(t, from, to)
+	previousState := getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
+	device := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	assertInvalidTransition(t, device, previousState)
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	to = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertInvalidTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertInvalidTransition(t, device, previousState)
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_UNKNOWN, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertInvalidTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_UNKNOWN, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertInvalidTransition(t, device, previousState)
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_DOWNLOADING_IMAGE, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertInvalidTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_DOWNLOADING_IMAGE, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertInvalidTransition(t, device, previousState)
 
-	from = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_UNKNOWN, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertInvalidTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_UNKNOWN, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertInvalidTransition(t, device, previousState)
 
-	from = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertInvalidTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertInvalidTransition(t, device, previousState)
 
-	from = getDevice(true, voltha.AdminState_DOWNLOADING_IMAGE, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertInvalidTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_DOWNLOADING_IMAGE, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertInvalidTransition(t, device, previousState)
 }
 
 func TestNoOpTransitions(t *testing.T) {
-	from := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertNoOpTransition(t, from, to)
+	previousState := getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertNoOpTransition(t, device, previousState)
 
-	from = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertNoOpTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertNoOpTransition(t, device, previousState)
 
-	from = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertNoOpTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertNoOpTransition(t, device, previousState)
 
-	from = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	to = getDevice(false, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
-	assertNoOpTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	device = getDevice(false, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+	assertNoOpTransition(t, device, previousState)
 
-	from = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
-	to = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_DISCOVERED)
-	assertNoOpTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
+	device = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_DISCOVERED)
+	assertNoOpTransition(t, device, previousState)
 
-	from = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_DISCOVERED)
-	to = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING)
-	assertNoOpTransition(t, from, to)
+	previousState = getDeviceState(voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_DISCOVERED)
+	device = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING)
+	assertNoOpTransition(t, device, previousState)
 }
 
 func TestMatch(t *testing.T) {
diff --git a/rw_core/core/logical_device_agent.go b/rw_core/core/logical_device_agent.go
index 64237d3..2616540 100644
--- a/rw_core/core/logical_device_agent.go
+++ b/rw_core/core/logical_device_agent.go
@@ -49,11 +49,6 @@
 	clusterDataProxy   *model.Proxy
 	exitChannel        chan int
 	deviceRoutes       *route.DeviceRoutes
-	flowProxy          *model.Proxy
-	groupProxy         *model.Proxy
-	meterProxy         *model.Proxy
-	ldProxy            *model.Proxy
-	portProxies        map[string]*model.Proxy
 	lockDeviceRoutes   sync.RWMutex
 	logicalPortsNo     map[uint32]bool //value is true for NNI port
 	lockLogicalPortsNo sync.RWMutex
@@ -76,7 +71,6 @@
 	agent.clusterDataProxy = cdProxy
 	agent.ldeviceMgr = ldeviceMgr
 	agent.flowDecomposer = fd.NewFlowDecomposer(agent.deviceMgr)
-	agent.portProxies = make(map[string]*model.Proxy)
 	agent.logicalPortsNo = make(map[uint32]bool)
 	agent.defaultTimeout = timeout
 	agent.requestQueue = coreutils.NewRequestQueue()
@@ -165,45 +159,6 @@
 		agent.addLogicalPortsToMap(ld.Ports)
 	}
 
-	var err error
-	agent.flowProxy, err = agent.clusterDataProxy.CreateProxy(
-		ctx,
-		fmt.Sprintf("/logical_devices/%s/flows", agent.logicalDeviceID),
-		false)
-	if err != nil {
-		return err
-	}
-	agent.meterProxy, err = agent.clusterDataProxy.CreateProxy(
-		ctx,
-		fmt.Sprintf("/logical_devices/%s/meters", agent.logicalDeviceID),
-		false)
-	if err != nil {
-		logger.Errorw("failed-to-create-meter-proxy", log.Fields{"error": err})
-		return err
-	}
-	agent.groupProxy, err = agent.clusterDataProxy.CreateProxy(
-		ctx,
-		fmt.Sprintf("/logical_devices/%s/flow_groups", agent.logicalDeviceID),
-		false)
-	if err != nil {
-		logger.Errorw("failed-to-create-group-proxy", log.Fields{"error": err})
-		return err
-	}
-	agent.ldProxy, err = agent.clusterDataProxy.CreateProxy(
-		ctx,
-		fmt.Sprintf("/logical_devices/%s", agent.logicalDeviceID),
-		false)
-	if err != nil {
-		logger.Errorw("failed-to-create-logical-device-proxy", log.Fields{"error": err})
-		return err
-	}
-	// TODO:  Use a port proxy once the POST_ADD is fixed
-	if agent.ldProxy != nil {
-		agent.ldProxy.RegisterCallback(model.PostUpdate, agent.portUpdated)
-	} else {
-		return status.Error(codes.Internal, "logical-device-proxy-null")
-	}
-
 	// Setup the device routes. Building routes may fail if the pre-conditions are not satisfied (e.g. no PON ports present)
 	if loadFromDB {
 		go func() {
@@ -451,18 +406,19 @@
 	}
 	defer agent.requestQueue.RequestComplete()
 	// Get the latest logical device info
-	cloned := agent.getLogicalDeviceWithoutLock()
-	for idx, lPort := range cloned.Ports {
-		if lPort.DeviceId == deviceID && lPort.DevicePortNo == portNo {
+	original := agent.getLogicalDeviceWithoutLock()
+	updatedPorts := clonePorts(original.Ports)
+	for _, port := range updatedPorts {
+		if port.DeviceId == deviceID && port.DevicePortNo == portNo {
 			if operStatus == voltha.OperStatus_ACTIVE {
-				cloned.Ports[idx].OfpPort.Config = cloned.Ports[idx].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-				cloned.Ports[idx].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
+				port.OfpPort.Config = port.OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
 			} else {
-				cloned.Ports[idx].OfpPort.Config = cloned.Ports[idx].OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-				cloned.Ports[idx].OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
+				port.OfpPort.Config = port.OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
 			}
 			// Update the logical device
-			if err := agent.updateLogicalDeviceWithoutLock(ctx, cloned); err != nil {
+			if err := agent.updateLogicalDevicePortsWithoutLock(ctx, original, updatedPorts); err != nil {
 				logger.Errorw("error-updating-logical-device", log.Fields{"error": err})
 				return err
 			}
@@ -480,21 +436,21 @@
 	}
 	defer agent.requestQueue.RequestComplete()
 	// Get the latest logical device info
-	cloned := agent.getLogicalDeviceWithoutLock()
-	for _, lport := range cloned.Ports {
-		if lport.DeviceId == device.Id {
+	original := agent.getLogicalDeviceWithoutLock()
+	updatedPorts := clonePorts(original.Ports)
+	for _, port := range updatedPorts {
+		if port.DeviceId == device.Id {
 			if state == voltha.OperStatus_ACTIVE {
-				lport.OfpPort.Config = lport.OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-				lport.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
+				port.OfpPort.Config = port.OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LIVE)
 			} else {
-				lport.OfpPort.Config = lport.OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-				lport.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
+				port.OfpPort.Config = port.OfpPort.Config | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+				port.OfpPort.State = uint32(ofp.OfpPortState_OFPPS_LINK_DOWN)
 			}
-
 		}
 	}
 	// Updating the logical device will trigger the poprt change events to be populated to the controller
-	if err := agent.updateLogicalDeviceWithoutLock(ctx, cloned); err != nil {
+	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, original, updatedPorts); err != nil {
 		logger.Warnw("logical-device-update-failed", log.Fields{"ldeviceId": agent.logicalDeviceID, "error": err})
 		return err
 	}
@@ -529,14 +485,9 @@
 	}
 	defer agent.requestQueue.RequestComplete()
 	// Get the latest logical device info
-	ld := agent.getLogicalDeviceWithoutLock()
+	cloned := agent.getLogicalDeviceWithoutLock()
 
-	cloned := (proto.Clone(ld)).(*voltha.LogicalDevice)
-	var updateLogicalPorts []*voltha.LogicalPort
-	// Update an empty ports slice to remove all the ports
-	cloned.Ports = updateLogicalPorts
-
-	if err := agent.updateLogicalDeviceWithoutLock(ctx, cloned); err != nil {
+	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, cloned, []*voltha.LogicalPort{}); err != nil {
 		logger.Warnw("logical-device-update-failed", log.Fields{"ldeviceId": agent.logicalDeviceID, "error": err})
 		return err
 	}
@@ -553,18 +504,16 @@
 	// Get the latest logical device info
 	ld := agent.getLogicalDeviceWithoutLock()
 
-	cloned := (proto.Clone(ld)).(*voltha.LogicalDevice)
 	updateLogicalPorts := []*voltha.LogicalPort{}
-	for _, lport := range cloned.Ports {
+	for _, lport := range ld.Ports {
 		// Save NNI ports only
 		if agent.isNNIPort(lport.DevicePortNo) {
 			updateLogicalPorts = append(updateLogicalPorts, lport)
 		}
 	}
-	if len(updateLogicalPorts) < len(cloned.Ports) {
-		cloned.Ports = updateLogicalPorts
+	if len(updateLogicalPorts) < len(ld.Ports) {
 		// Updating the logical device will trigger the port change events to be populated to the controller
-		if err := agent.updateLogicalDeviceWithoutLock(ctx, cloned); err != nil {
+		if err := agent.updateLogicalDevicePortsWithoutLock(ctx, ld, updateLogicalPorts); err != nil {
 			return err
 		}
 	} else {
@@ -573,6 +522,21 @@
 	return nil
 }
 
+func clonePorts(ports []*voltha.LogicalPort) []*voltha.LogicalPort {
+	return proto.Clone(&voltha.LogicalPorts{Items: ports}).(*voltha.LogicalPorts).Items
+}
+
+//updateLogicalDevicePortsWithoutLock updates the
+func (agent *LogicalDeviceAgent) updateLogicalDevicePortsWithoutLock(ctx context.Context, device *voltha.LogicalDevice, newPorts []*voltha.LogicalPort) error {
+	oldPorts := device.Ports
+	device.Ports = newPorts
+	if err := agent.updateLogicalDeviceWithoutLock(ctx, device); err != nil {
+		return err
+	}
+	agent.portUpdated(oldPorts, newPorts)
+	return nil
+}
+
 //updateLogicalDeviceWithoutLock updates the model with the logical device.  It clones the logicaldevice before saving it
 func (agent *LogicalDeviceAgent) updateLogicalDeviceWithoutLock(ctx context.Context, logicalDevice *voltha.LogicalDevice) error {
 	updateCtx := context.WithValue(ctx, model.RequestTimestamp, time.Now().UnixNano())
@@ -1425,11 +1389,14 @@
 		}
 	}
 	if index >= 0 {
-		copy(logicalDevice.Ports[index:], logicalDevice.Ports[index+1:])
-		logicalDevice.Ports[len(logicalDevice.Ports)-1] = nil
-		logicalDevice.Ports = logicalDevice.Ports[:len(logicalDevice.Ports)-1]
+		clonedPorts := clonePorts(logicalDevice.Ports)
+		if index < len(clonedPorts)-1 {
+			copy(clonedPorts[index:], clonedPorts[index+1:])
+		}
+		clonedPorts[len(clonedPorts)-1] = nil
+		clonedPorts = clonedPorts[:len(clonedPorts)-1]
 		logger.Debugw("logical-port-deleted", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
-		if err := agent.updateLogicalDeviceWithoutLock(ctx, logicalDevice); err != nil {
+		if err := agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts); err != nil {
 			logger.Errorw("logical-device-update-failed", log.Fields{"logicalDeviceId": agent.logicalDeviceID})
 			return err
 		}
@@ -1465,10 +1432,8 @@
 			lPortsNoToDelete = append(lPortsNoToDelete, logicalPort.DevicePortNo)
 		}
 	}
-	logicalDevice.Ports = lPortstoKeep
-
 	logger.Debugw("deleted-logical-ports", log.Fields{"ports": lPortstoKeep})
-	if err := agent.updateLogicalDeviceWithoutLock(ctx, logicalDevice); err != nil {
+	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, lPortstoKeep); err != nil {
 		logger.Errorw("logical-device-update-failed", log.Fields{"logical-device-id": agent.logicalDeviceID})
 		return err
 	}
@@ -1502,8 +1467,9 @@
 		}
 	}
 	if index >= 0 {
-		logicalDevice.Ports[index].OfpPort.Config = logicalDevice.Ports[index].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-		return agent.updateLogicalDeviceWithoutLock(ctx, logicalDevice)
+		clonedPorts := clonePorts(logicalDevice.Ports)
+		clonedPorts[index].OfpPort.Config = clonedPorts[index].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+		return agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts)
 	}
 	return status.Errorf(codes.NotFound, "Port %s on Logical Device %s", lPortID, agent.logicalDeviceID)
 }
@@ -1525,8 +1491,9 @@
 		}
 	}
 	if index >= 0 {
-		logicalDevice.Ports[index].OfpPort.Config = (logicalDevice.Ports[index].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)) | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
-		return agent.updateLogicalDeviceWithoutLock(ctx, logicalDevice)
+		clonedPorts := clonePorts(logicalDevice.Ports)
+		clonedPorts[index].OfpPort.Config = (clonedPorts[index].OfpPort.Config & ^uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)) | uint32(ofp.OfpPortConfig_OFPPC_PORT_DOWN)
+		return agent.updateLogicalDevicePortsWithoutLock(ctx, logicalDevice, clonedPorts)
 	}
 	return status.Errorf(codes.NotFound, "Port %s on Logical Device %s", lPortID, agent.logicalDeviceID)
 }
@@ -1716,29 +1683,14 @@
 // portUpdated is invoked when a port is updated on the logical device.  Until
 // the POST_ADD notification is fixed, we will use the logical device to
 // update that data.
-func (agent *LogicalDeviceAgent) portUpdated(ctx context.Context, args ...interface{}) interface{} {
-	logger.Debugw("portUpdated-callback", log.Fields{"argsLen": len(args)})
-
-	var oldLD *voltha.LogicalDevice
-	var newlD *voltha.LogicalDevice
-
-	var ok bool
-	if oldLD, ok = args[0].(*voltha.LogicalDevice); !ok {
-		logger.Errorw("invalid-args", log.Fields{"args0": args[0]})
-		return nil
-	}
-	if newlD, ok = args[1].(*voltha.LogicalDevice); !ok {
-		logger.Errorw("invalid-args", log.Fields{"args1": args[1]})
-		return nil
-	}
-
-	if reflect.DeepEqual(oldLD.Ports, newlD.Ports) {
+func (agent *LogicalDeviceAgent) portUpdated(oldPorts, newPorts []*voltha.LogicalPort) interface{} {
+	if reflect.DeepEqual(oldPorts, newPorts) {
 		logger.Debug("ports-have-not-changed")
 		return nil
 	}
 
 	// Get the difference between the two list
-	newPorts, changedPorts, deletedPorts := diff(oldLD.Ports, newlD.Ports)
+	newPorts, changedPorts, deletedPorts := diff(oldPorts, newPorts)
 
 	// Send the port change events to the OF controller
 	for _, newP := range newPorts {
@@ -1806,13 +1758,13 @@
 
 	ld := agent.getLogicalDeviceWithoutLock()
 
-	cloned := (proto.Clone(ld)).(*voltha.LogicalDevice)
-	if cloned.Ports == nil {
-		cloned.Ports = make([]*voltha.LogicalPort, 0)
+	clonedPorts := clonePorts(ld.Ports)
+	if clonedPorts == nil {
+		clonedPorts = make([]*voltha.LogicalPort, 0)
 	}
-	cloned.Ports = append(cloned.Ports, lp)
+	clonedPorts = append(clonedPorts, lp)
 
-	if err = agent.updateLogicalDeviceWithoutLock(ctx, cloned); err != nil {
+	if err = agent.updateLogicalDevicePortsWithoutLock(ctx, ld, clonedPorts); err != nil {
 		logger.Errorw("error-updating-logical-device", log.Fields{"error": err})
 		return false, err
 	}
@@ -1883,12 +1835,12 @@
 	portCap.Port.OfpPort.PortNo = port.PortNo
 	portCap.Port.DeviceId = childDevice.Id
 	portCap.Port.DevicePortNo = port.PortNo
-	cloned := (proto.Clone(ldevice)).(*voltha.LogicalDevice)
-	if cloned.Ports == nil {
-		cloned.Ports = make([]*voltha.LogicalPort, 0)
+	clonedPorts := clonePorts(ldevice.Ports)
+	if clonedPorts == nil {
+		clonedPorts = make([]*voltha.LogicalPort, 0)
 	}
-	cloned.Ports = append(cloned.Ports, portCap.Port)
-	if err := agent.updateLogicalDeviceWithoutLock(ctx, cloned); err != nil {
+	clonedPorts = append(clonedPorts, portCap.Port)
+	if err := agent.updateLogicalDevicePortsWithoutLock(ctx, ldevice, clonedPorts); err != nil {
 		return false, err
 	}
 	// Update the device graph with this new logical port
diff --git a/rw_core/coreif/device_manager_if.go b/rw_core/coreif/device_manager_if.go
index f828ab0..5e98438 100644
--- a/rw_core/coreif/device_manager_if.go
+++ b/rw_core/coreif/device_manager_if.go
@@ -29,16 +29,16 @@
 type DeviceManager interface {
 	GetDevice(context.Context, string) (*voltha.Device, error)
 	IsRootDevice(string) (bool, error)
-	NotifyInvalidTransition(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	CreateLogicalDevice(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	SetupUNILogicalPorts(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	DisableAllChildDevices(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	DeleteLogicalDevice(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	DeleteLogicalPorts(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	DeleteAllChildDevices(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	RunPostDeviceDelete(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	ChildDeviceLost(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	DeleteAllUNILogicalPorts(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	DeleteAllLogicalPorts(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
-	DeleteAllDeviceFlows(ctx context.Context, curr *voltha.Device, prev *voltha.Device) error
+	NotifyInvalidTransition(ctx context.Context, curr *voltha.Device) error
+	CreateLogicalDevice(ctx context.Context, curr *voltha.Device) error
+	SetupUNILogicalPorts(ctx context.Context, curr *voltha.Device) error
+	DisableAllChildDevices(ctx context.Context, curr *voltha.Device) error
+	DeleteLogicalDevice(ctx context.Context, curr *voltha.Device) error
+	DeleteLogicalPorts(ctx context.Context, curr *voltha.Device) error
+	DeleteAllChildDevices(ctx context.Context, curr *voltha.Device) error
+	RunPostDeviceDelete(ctx context.Context, curr *voltha.Device) error
+	ChildDeviceLost(ctx context.Context, curr *voltha.Device) error
+	DeleteAllUNILogicalPorts(ctx context.Context, curr *voltha.Device) error
+	DeleteAllLogicalPorts(ctx context.Context, curr *voltha.Device) error
+	DeleteAllDeviceFlows(ctx context.Context, curr *voltha.Device) error
 }
diff --git a/rw_core/mocks/device_manager.go b/rw_core/mocks/device_manager.go
index 7fb2983..9b9a589 100644
--- a/rw_core/mocks/device_manager.go
+++ b/rw_core/mocks/device_manager.go
@@ -39,61 +39,61 @@
 }
 
 // NotifyInvalidTransition -
-func (dm *DeviceManager) NotifyInvalidTransition(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) NotifyInvalidTransition(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // CreateLogicalDevice -
-func (dm *DeviceManager) CreateLogicalDevice(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) CreateLogicalDevice(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // SetupUNILogicalPorts -
-func (dm *DeviceManager) SetupUNILogicalPorts(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) SetupUNILogicalPorts(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // DisableAllChildDevices -
-func (dm *DeviceManager) DisableAllChildDevices(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) DisableAllChildDevices(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // DeleteLogicalDevice -
-func (dm *DeviceManager) DeleteLogicalDevice(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) DeleteLogicalDevice(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // DeleteLogicalPorts -
-func (dm *DeviceManager) DeleteLogicalPorts(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) DeleteLogicalPorts(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // DeleteAllChildDevices -
-func (dm *DeviceManager) DeleteAllChildDevices(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) DeleteAllChildDevices(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // DeleteAllUNILogicalPorts -
-func (dm *DeviceManager) DeleteAllUNILogicalPorts(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) DeleteAllUNILogicalPorts(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // DeleteAllLogicalPorts -
-func (dm *DeviceManager) DeleteAllLogicalPorts(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) DeleteAllLogicalPorts(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // DeleteAllDeviceFlows -
-func (dm *DeviceManager) DeleteAllDeviceFlows(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) DeleteAllDeviceFlows(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // RunPostDeviceDelete -
-func (dm *DeviceManager) RunPostDeviceDelete(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) RunPostDeviceDelete(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }
 
 // childDeviceLost -
-func (dm *DeviceManager) ChildDeviceLost(ctx context.Context, cDevice *voltha.Device, pDevice *voltha.Device) error {
+func (dm *DeviceManager) ChildDeviceLost(ctx context.Context, cDevice *voltha.Device) error {
 	return nil
 }