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
}