VOL-3504 Code changes to support force delete
Change-Id: I041ab2101a607b99e0372e432819a3f10f3a774c
diff --git a/VERSION b/VERSION
index 745ec0d..21f3dae 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.6.2-dev
+2.6.3-dev
diff --git a/go.mod b/go.mod
index 0401589..b84d647 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@
github.com/golang/protobuf v1.3.2
github.com/google/uuid v1.1.1
github.com/opencord/voltha-lib-go/v4 v4.0.2
- github.com/opencord/voltha-protos/v4 v4.0.2
+ github.com/opencord/voltha-protos/v4 v4.0.5
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
github.com/stretchr/testify v1.4.0
google.golang.org/grpc v1.24.0
diff --git a/go.sum b/go.sum
index 628d20e..df7b62a 100644
--- a/go.sum
+++ b/go.sum
@@ -202,6 +202,8 @@
github.com/opencord/voltha-lib-go/v4 v4.0.2/go.mod h1:QgdIa7PlU0jhZT3qCPtcVt8/CpingKm4dUEROBrUBZg=
github.com/opencord/voltha-protos/v4 v4.0.2 h1:SI25ljqftc8Tc28CgfqSE4IGCLJ5MgCmBQlE96hl9X8=
github.com/opencord/voltha-protos/v4 v4.0.2/go.mod h1:W/OIFIyvFh/C0vchRUuarIsMylEhzCRM9pNxLvkPtKc=
+github.com/opencord/voltha-protos/v4 v4.0.5 h1:aOCk7SbIZhM8uHtsqAEADvO3l0xQgDPytoKZKb5Y4Zg=
+github.com/opencord/voltha-protos/v4 v4.0.5/go.mod h1:W/OIFIyvFh/C0vchRUuarIsMylEhzCRM9pNxLvkPtKc=
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
diff --git a/rw_core/core/api/grpc_nbi_handler.go b/rw_core/core/api/grpc_nbi_handler.go
index e0933c3..ea4c757 100755
--- a/rw_core/core/api/grpc_nbi_handler.go
+++ b/rw_core/core/api/grpc_nbi_handler.go
@@ -112,6 +112,3 @@
func (handler *NBIHandler) UpdateMembership(context.Context, *voltha.Membership) (*empty.Empty, error) {
return nil, errUnimplemented
}
-func (handler *NBIHandler) ForceDeleteDevice(ctx context.Context, id *common.ID) (*empty.Empty, error) {
- return nil, errUnimplemented
-}
diff --git a/rw_core/core/api/grpc_nbi_handler_test.go b/rw_core/core/api/grpc_nbi_handler_test.go
index d6491c8..2891c36 100755
--- a/rw_core/core/api/grpc_nbi_handler_test.go
+++ b/rw_core/core/api/grpc_nbi_handler_test.go
@@ -353,6 +353,206 @@
err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
assert.Nil(t, err)
}
+func (nb *NBTest) enableDevice(t *testing.T, nbi *NBIHandler, oltDevice *voltha.Device) {
+ // Create a logical device monitor will automatically send trap and eapol flows to the devices being enables
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go nb.monitorLogicalDevice(t, nbi, 1, nb.numONUPerOLT, &wg, false, false)
+
+ // Enable the oltDevice
+ _, err := nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ // Wait for the logical device to be in the ready state
+ var vldFunction = func(ports []*voltha.LogicalPort) bool {
+ return len(ports) == nb.numONUPerOLT+1
+ }
+ err = waitUntilLogicalDevicePortsReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
+ assert.Nil(t, err)
+
+ // Verify that the devices have been setup correctly
+ nb.verifyDevices(t, nbi)
+
+ // Get latest oltDevice data
+ oltDevice, err = nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ // Verify that the logical device has been setup correctly
+ nb.verifyLogicalDevices(t, oltDevice, nbi)
+
+ // Wait until all flows has been sent to the devices successfully
+ wg.Wait()
+
+}
+func (nb *NBTest) testForceDeletePreProvDevice(t *testing.T, nbi *NBIHandler) {
+ // Create a valid device
+ oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+ assert.Nil(t, err)
+ assert.NotNil(t, oltDevice)
+ device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+ assert.NotNil(t, device)
+ assert.Equal(t, oltDevice.String(), device.String())
+
+ // Ensure we only have 1 device in the Core
+ devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
+ assert.Nil(t, err)
+ assert.NotNil(t, devices)
+ assert.Equal(t, 1, len(devices.Items))
+ assert.Equal(t, oltDevice.String(), devices.Items[0].String())
+
+ //Remove the device forcefully
+ _, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+ var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+ return devices != nil && len(devices.Items) == 0
+ }
+ err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+ assert.Nil(t, err)
+}
+
+func (nb *NBTest) testForceDeleteEnabledDevice(t *testing.T, nbi *NBIHandler) {
+ // Create a valid device
+ oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+ assert.Nil(t, err)
+ assert.NotNil(t, oltDevice)
+ device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+ assert.NotNil(t, device)
+ assert.Equal(t, oltDevice.String(), device.String())
+
+ nb.enableDevice(t, nbi, oltDevice)
+
+ //Remove the device forcefully
+ _, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+ var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+ return devices != nil && len(devices.Items) == 0
+ }
+ err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+ assert.Nil(t, err)
+}
+
+func (nb *NBTest) testDeletePreProvDevice(t *testing.T, nbi *NBIHandler) {
+ // Create a valid device
+ oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+ assert.Nil(t, err)
+ assert.NotNil(t, oltDevice)
+ device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+ assert.NotNil(t, device)
+ assert.Equal(t, oltDevice.String(), device.String())
+
+ // Ensure we only have 1 device in the Core
+ devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
+ assert.Nil(t, err)
+ assert.NotNil(t, devices)
+ assert.Equal(t, 1, len(devices.Items))
+ assert.Equal(t, oltDevice.String(), devices.Items[0].String())
+
+ //Remove the device forcefully
+ _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+ var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+ return devices != nil && len(devices.Items) == 0
+ }
+ err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+ assert.Nil(t, err)
+}
+
+func (nb *NBTest) testDeleteEnabledDevice(t *testing.T, nbi *NBIHandler) {
+ // Create a valid device
+ oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+ assert.Nil(t, err)
+ assert.NotNil(t, oltDevice)
+ device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+ assert.NotNil(t, device)
+ assert.Equal(t, oltDevice.String(), device.String())
+
+ nb.enableDevice(t, nbi, oltDevice)
+
+ //Remove the device
+ _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ //Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+ var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+ return devices != nil && len(devices.Items) == 0
+ }
+ err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+ assert.Nil(t, err)
+}
+
+func (nb *NBTest) testForceDeleteDeviceFailure(t *testing.T, nbi *NBIHandler) {
+ // Create a valid device
+ oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+ assert.Nil(t, err)
+ assert.NotNil(t, oltDevice)
+ device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+ assert.NotNil(t, device)
+ assert.Equal(t, oltDevice.String(), device.String())
+
+ nb.enableDevice(t, nbi, oltDevice)
+ nb.oltAdapter.SetDeleteAction(true)
+ //Remove the device
+ _, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ //Ensure there are no devices in the Core although delete was failed - wait until condition satisfied or timeout
+ var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+ return devices != nil && len(devices.Items) == 0
+ }
+ err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+ assert.Nil(t, err)
+
+}
+
+func (nb *NBTest) testDeleteDeviceFailure(t *testing.T, nbi *NBIHandler) {
+ // Create a valid device
+ oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+ assert.Nil(t, err)
+ assert.NotNil(t, oltDevice)
+ device, err := nbi.GetDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+ assert.NotNil(t, device)
+ assert.Equal(t, oltDevice.String(), device.String())
+
+ nb.enableDevice(t, nbi, oltDevice)
+
+ nb.oltAdapter.SetDeleteAction(true)
+ //Remove the device
+ _, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ //Ensure there are devices in the Core as delete was failed - wait until condition satisfied or timeout
+ var vFunction1 isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+ return devices != nil && len(devices.Items) == (nb.numONUPerOLT+1)
+ }
+ err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction1)
+ assert.Nil(t, err)
+
+ nb.oltAdapter.SetDeleteAction(false)
+
+ // Now Force Delete this device
+ _, err = nbi.ForceDeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+ assert.Nil(t, err)
+
+ //Ensure there are devices in the Core as delete was failed - wait until condition satisfied or timeout
+ var vFunction2 isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+ return devices != nil && len(devices.Items) == 0
+ }
+ err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction2)
+ assert.Nil(t, err)
+
+}
func (nb *NBTest) testEnableDevice(t *testing.T, nbi *NBIHandler) {
// Create a device that has no adapter registered
@@ -1235,37 +1435,46 @@
numberOfTestRuns := 2
for i := 1; i <= numberOfTestRuns; i++ {
- //3. Test create device
+
+ // 3. Test create device
nb.testCreateDevice(t, nbi)
- // 4. Test Enable a device
+ // 4. Test Delete Device Scenarios
+ nb.testForceDeletePreProvDevice(t, nbi)
+ nb.testDeletePreProvDevice(t, nbi)
+ nb.testForceDeleteEnabledDevice(t, nbi)
+ nb.testDeleteEnabledDevice(t, nbi)
+ nb.testForceDeleteDeviceFailure(t, nbi)
+ nb.testDeleteDeviceFailure(t, nbi)
+
+ // 5. Test Enable a device
nb.testEnableDevice(t, nbi)
- //// 5. Test disable and ReEnable a root device
+ // 6. Test disable and ReEnable a root device
nb.testDisableAndReEnableRootDevice(t, nbi)
- // 6. Test disable and Enable pon port of OLT device
+ // 7. Test disable and Enable pon port of OLT device
nb.testDisableAndEnablePort(t, nbi)
- // 7.Test Device unreachable when OLT is enabled
+ // 8.Test Device unreachable when OLT is enabled
nb.testDeviceRebootWhenOltIsEnabled(t, nbi)
- // 8. Test disable and delete all devices
+ // 9. Test disable and delete all devices
nb.testDisableAndDeleteAllDevice(t, nbi)
- // 9. Test enable and delete all devices
+ // 10. Test enable and delete all devices
nb.testEnableAndDeleteAllDevice(t, nbi)
- // 10. Test omci test
+ // 11. Test omci test
nb.testStartOmciTestAction(t, nbi)
- // 11. Remove all devices from tests above
+ // 12. Remove all devices from tests above
nb.deleteAllDevices(t, nbi)
- // 11. Test flow add failure
+ // 13. Test flow add failure
nb.testFlowAddFailure(t, nbi)
- // 12. Clean up
+ // 14. Clean up
nb.deleteAllDevices(t, nbi)
}
}
diff --git a/rw_core/core/device/agent.go b/rw_core/core/device/agent.go
index 4fc5197..a9767d4 100755
--- a/rw_core/core/device/agent.go
+++ b/rw_core/core/device/agent.go
@@ -25,18 +25,18 @@
"sync"
"time"
+ "github.com/gogo/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/empty"
+ "github.com/opencord/voltha-go/db/model"
"github.com/opencord/voltha-go/rw_core/core/adapter"
"github.com/opencord/voltha-go/rw_core/core/device/flow"
"github.com/opencord/voltha-go/rw_core/core/device/group"
"github.com/opencord/voltha-go/rw_core/core/device/port"
"github.com/opencord/voltha-go/rw_core/core/device/remote"
- "github.com/opencord/voltha-lib-go/v4/pkg/kafka"
-
- "github.com/gogo/protobuf/proto"
- "github.com/opencord/voltha-go/db/model"
+ "github.com/opencord/voltha-go/rw_core/core/device/transientstate"
coreutils "github.com/opencord/voltha-go/rw_core/utils"
+ "github.com/opencord/voltha-lib-go/v4/pkg/kafka"
"github.com/opencord/voltha-lib-go/v4/pkg/log"
ic "github.com/opencord/voltha-protos/v4/go/inter_container"
ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
@@ -63,9 +63,10 @@
stopOnce sync.Once
stopped bool
- flowLoader *flow.Loader
- groupLoader *group.Loader
- portLoader *port.Loader
+ flowLoader *flow.Loader
+ groupLoader *group.Loader
+ portLoader *port.Loader
+ transientStateLoader *transientstate.Loader
}
//newAgent creates a new device agent. The device will be initialized when start() is called.
@@ -76,21 +77,22 @@
}
return &Agent{
- deviceID: deviceID,
- adapterProxy: ap,
- isRootDevice: device.Root,
- parentID: device.ParentId,
- deviceType: device.Type,
- deviceMgr: deviceMgr,
- adapterMgr: deviceMgr.adapterMgr,
- exitChannel: make(chan int, 1),
- dbProxy: deviceProxy,
- defaultTimeout: timeout,
- device: proto.Clone(device).(*voltha.Device),
- requestQueue: coreutils.NewRequestQueue(),
- flowLoader: flow.NewLoader(dbPath.SubPath("flows").Proxy(deviceID)),
- groupLoader: group.NewLoader(dbPath.SubPath("groups").Proxy(deviceID)),
- portLoader: port.NewLoader(dbPath.SubPath("ports").Proxy(deviceID)),
+ deviceID: deviceID,
+ adapterProxy: ap,
+ isRootDevice: device.Root,
+ parentID: device.ParentId,
+ deviceType: device.Type,
+ deviceMgr: deviceMgr,
+ adapterMgr: deviceMgr.adapterMgr,
+ exitChannel: make(chan int, 1),
+ dbProxy: deviceProxy,
+ defaultTimeout: timeout,
+ device: proto.Clone(device).(*voltha.Device),
+ requestQueue: coreutils.NewRequestQueue(),
+ flowLoader: flow.NewLoader(dbPath.SubPath("flows").Proxy(deviceID)),
+ groupLoader: group.NewLoader(dbPath.SubPath("groups").Proxy(deviceID)),
+ portLoader: port.NewLoader(dbPath.SubPath("ports").Proxy(deviceID)),
+ transientStateLoader: transientstate.NewLoader(dbPath.SubPath("core").Proxy("transientstate"), deviceID),
}
}
@@ -128,6 +130,7 @@
agent.flowLoader.Load(ctx)
agent.groupLoader.Load(ctx)
agent.portLoader.Load(ctx)
+ agent.transientStateLoader.Load(ctx)
logger.Infow(ctx, "device-loaded-from-dB", log.Fields{"device-id": agent.deviceID})
} else {
@@ -169,7 +172,10 @@
defer agent.requestQueue.RequestComplete()
logger.Infow(ctx, "stopping-device-agent", log.Fields{"device-id": agent.deviceID, "parentId": agent.parentID})
-
+ // Remove the device transient loader
+ if err := agent.deleteTransientState(ctx); err != nil {
+ return err
+ }
// Remove the device from the KV store
if err := agent.dbProxy.Remove(ctx, agent.deviceID); err != nil {
return err
@@ -206,13 +212,15 @@
agent.flowLoader.Load(ctx)
agent.groupLoader.Load(ctx)
agent.portLoader.Load(ctx)
+ agent.transientStateLoader.Load(ctx)
+
logger.Debugw(ctx, "reconciled-device-agent-devicetype", log.Fields{"device-id": agent.deviceID, "type": agent.deviceType})
}
// onSuccess is a common callback for scenarios where we receive a nil response following a request to an adapter
// and the only action required is to publish a successful result on kafka
func (agent *Agent) onSuccess(ctx context.Context, rpc string, response interface{}, reqArgs ...interface{}) {
- logger.Debugw(ctx, "response successful", log.Fields{"rpc": rpc, "device-id": agent.deviceID})
+ logger.Debugw(ctx, "response-successful", log.Fields{"rpc": rpc, "device-id": agent.deviceID})
// TODO: Post success message onto kafka
}
@@ -244,6 +252,53 @@
}
}
+// onDeleteSuccess is a common callback for scenarios where we receive a nil response following a delete request
+// to an adapter.
+func (agent *Agent) onDeleteSuccess(ctx context.Context, rpc string, response interface{}, reqArgs ...interface{}) {
+ logger.Debugw(ctx, "response-successful", log.Fields{"rpc": rpc, "device-id": agent.deviceID})
+ if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+ logger.Errorw(ctx, "delete-device-failure", log.Fields{"device-id": agent.deviceID, "error": err, "args": reqArgs})
+ }
+ previousDeviceTransientState := agent.getTransientState()
+ newDevice := agent.cloneDeviceWithoutLock()
+ if err := agent.updateDeviceWithTransientStateAndReleaseLock(ctx, newDevice,
+ voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE, previousDeviceTransientState); err != nil {
+ logger.Errorw(ctx, "delete-device-failure", log.Fields{"device-id": agent.deviceID, "error": err, "args": reqArgs})
+ }
+}
+
+// onDeleteFailure is a common callback for scenarios where we receive an error response following a delete request
+// to an adapter and the only action required is to return the error response.
+func (agent *Agent) onDeleteFailure(ctx context.Context, rpc string, response interface{}, reqArgs ...interface{}) {
+ if res, ok := response.(error); ok {
+ logger.Errorw(ctx, "rpc-failed", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "error": res, "args": reqArgs})
+ } else {
+ logger.Errorw(ctx, "rpc-failed-invalid-error", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "args": reqArgs})
+ }
+ //Only updating of transient state is required, no transition.
+ if err := agent.updateTransientState(ctx, voltha.DeviceTransientState_DELETE_FAILED); err != nil {
+ logger.Errorw(ctx, "failed-to-update-transient-state-as-delete-failed", log.Fields{"device-id": agent.deviceID})
+ }
+
+}
+
+func (agent *Agent) waitForAdapterDeleteResponse(ctx context.Context, cancel context.CancelFunc, rpc string, ch chan *kafka.RpcResponse,
+ onSuccess coreutils.ResponseCallback, onFailure coreutils.ResponseCallback, reqArgs ...interface{}) {
+ defer cancel()
+ select {
+ case rpcResponse, ok := <-ch:
+ if !ok {
+ onFailure(ctx, rpc, status.Errorf(codes.Aborted, "channel-closed"), reqArgs)
+ } else if rpcResponse.Err != nil {
+ onFailure(ctx, rpc, rpcResponse.Err, reqArgs)
+ } else {
+ onSuccess(ctx, rpc, rpcResponse.Reply, reqArgs)
+ }
+ case <-ctx.Done():
+ onFailure(ctx, rpc, ctx.Err(), reqArgs)
+ }
+}
+
// getDeviceReadOnly returns a device which MUST NOT be modified, but is safe to keep forever.
func (agent *Agent) getDeviceReadOnly(ctx context.Context) (*voltha.Device, error) {
if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
@@ -278,12 +333,10 @@
agent.requestQueue.RequestComplete()
return status.Error(codes.FailedPrecondition, fmt.Sprintf("cannot-enable-an-already-enabled-device: %s", oldDevice.Id))
}
- if oldDevice.AdminState == voltha.AdminState_DELETED {
- // This is a temporary state when a device is deleted before it gets removed from the model.
+ if agent.isDeletionInProgress() {
agent.requestQueue.RequestComplete()
- return status.Error(codes.FailedPrecondition, fmt.Sprintf("cannot-enable-a-deleted-device: %s", oldDevice.Id))
+ return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device deletion is in progress.", agent.deviceID)
}
-
// First figure out which adapter will handle this device type. We do it at this stage as allow devices to be
// pre-provisioned with the required adapter not registered. At this stage, since we need to communicate
// with the adapter then we need to know the adapter that will handle this request
@@ -406,11 +459,14 @@
agent.requestQueue.RequestComplete()
return nil
}
- if cloned.AdminState == voltha.AdminState_PREPROVISIONED || cloned.AdminState == voltha.AdminState_DELETED {
+ if cloned.AdminState == voltha.AdminState_PREPROVISIONED {
agent.requestQueue.RequestComplete()
return status.Errorf(codes.FailedPrecondition, "deviceId:%s, invalid-admin-state:%s", agent.deviceID, cloned.AdminState)
}
-
+ if agent.isDeletionInProgress() {
+ agent.requestQueue.RequestComplete()
+ return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device deletion is in progress.", agent.deviceID)
+ }
// Update the Admin State and operational state before sending the request out
cloned.AdminState = voltha.AdminState_DISABLED
cloned.OperStatus = voltha.OperStatus_UNKNOWN
@@ -437,6 +493,9 @@
logger.Debugw(ctx, "rebootDevice", log.Fields{"device-id": agent.deviceID})
device := agent.getDeviceReadOnlyWithoutLock()
+ if agent.isDeletionInProgress() {
+ return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device deletion is in progress.", agent.deviceID)
+ }
subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
ch, err := agent.adapterProxy.RebootDevice(subCtx, device)
if err != nil {
@@ -447,32 +506,79 @@
return nil
}
+func (agent *Agent) deleteDeviceForce(ctx context.Context) error {
+ logger.Debugw(ctx, "deleteDeviceForce", log.Fields{"device-id": agent.deviceID})
+ if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
+ return err
+ }
+ // Get the device Transient state, return err if it is DELETING
+ previousDeviceTransientState := agent.getTransientState()
+
+ if agent.isStateDeleting(previousDeviceTransientState) {
+ agent.requestQueue.RequestComplete()
+ return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device Deletion is in progress",
+ agent.deviceID)
+ }
+ device := agent.cloneDeviceWithoutLock()
+ if err := agent.updateDeviceWithTransientStateAndReleaseLock(ctx, device, voltha.DeviceTransientState_FORCE_DELETING,
+ previousDeviceTransientState); err != nil {
+ return err
+ }
+ previousAdminState := device.AdminState
+ if previousAdminState != ic.AdminState_PREPROVISIONED {
+ subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
+ ch, err := agent.adapterProxy.DeleteDevice(subCtx, device)
+ if err != nil {
+ cancel()
+ return err
+ }
+ // Since it is a case of force delete, nothing needs to be done on adapter responses.
+ go agent.waitForAdapterResponse(subCtx, cancel, "deleteDeviceForce", ch, agent.onSuccess,
+ agent.onFailure)
+ }
+ return nil
+}
+
func (agent *Agent) deleteDevice(ctx context.Context) error {
logger.Debugw(ctx, "deleteDevice", log.Fields{"device-id": agent.deviceID})
if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
return err
}
+ // Get the device Transient state, return err if it is DELETING
+ previousDeviceTransientState := agent.getTransientState()
- cloned := agent.cloneDeviceWithoutLock()
- previousState := cloned.AdminState
+ if agent.isStateDeleting(previousDeviceTransientState) {
+ agent.requestQueue.RequestComplete()
+ return status.Errorf(codes.FailedPrecondition, "deviceId:%s, Device Deletion is in progress", agent.deviceID)
+ }
+ device := agent.cloneDeviceWithoutLock()
+ previousAdminState := device.AdminState
+ // Change the device transient state to DELETING_FROM_ADAPTER state till the device is removed from adapters.
+ currentDeviceTransientState := voltha.DeviceTransientState_DELETING_FROM_ADAPTER
- // 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.updateDeviceAndReleaseLock(ctx, cloned); err != nil {
+ if previousAdminState == ic.AdminState_PREPROVISIONED {
+ // Change the state to DELETING POST ADAPTER RESPONSE directly as adapters have no info of the device.
+ currentDeviceTransientState = voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE
+ }
+ if err := agent.updateDeviceWithTransientStateAndReleaseLock(ctx, device, currentDeviceTransientState,
+ previousDeviceTransientState); err != nil {
return err
}
-
// If the device was in pre-prov state (only parent device are in that state) then do not send the request to the
// adapter
- if previousState != ic.AdminState_PREPROVISIONED {
+ if previousAdminState != ic.AdminState_PREPROVISIONED {
subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
- ch, err := agent.adapterProxy.DeleteDevice(subCtx, cloned)
+ ch, err := agent.adapterProxy.DeleteDevice(subCtx, device)
if err != nil {
cancel()
+ //updating of transient state is required in error
+ if err := agent.updateTransientState(ctx, voltha.DeviceTransientState_DELETE_FAILED); err != nil {
+ logger.Errorw(ctx, "failed-to-update-transient-state-as-delete-failed", log.Fields{"device-id": agent.deviceID})
+ }
return err
}
- go agent.waitForAdapterResponse(subCtx, cancel, "deleteDevice", ch, agent.onSuccess, agent.onFailure)
+ go agent.waitForAdapterDeleteResponse(subCtx, cancel, "deleteDevice", ch, agent.onDeleteSuccess,
+ agent.onDeleteFailure)
}
return nil
}
@@ -654,7 +760,7 @@
// fail early if this agent is no longer valid
if agent.stopped {
agent.requestQueue.RequestComplete()
- return errors.New("device agent stopped")
+ return errors.New("device-agent-stopped")
}
// update in db
@@ -671,12 +777,52 @@
// release lock before processing transition
agent.requestQueue.RequestComplete()
- if err := agent.deviceMgr.stateTransitions.ProcessTransition(log.WithSpanFromContext(context.Background(), ctx), device, prevDevice); err != nil {
+ if err := agent.deviceMgr.stateTransitions.ProcessTransition(log.WithSpanFromContext(context.Background(), ctx),
+ device, prevDevice, voltha.DeviceTransientState_NONE, voltha.DeviceTransientState_NONE); err != nil {
logger.Errorw(ctx, "failed-process-transition", log.Fields{"device-id": device.Id, "previousAdminState": prevDevice.AdminState, "currentAdminState": device.AdminState})
}
return nil
}
+// This function updates the device transient in the DB through loader, releases the device lock, and runs any state transitions.
+// The calling function MUST hold the device lock. The caller MUST NOT modify the device after this is called.
+func (agent *Agent) updateDeviceWithTransientStateAndReleaseLock(ctx context.Context, device *voltha.Device,
+ transientState, prevTransientState voltha.DeviceTransientState_Types) error {
+ // fail early if this agent is no longer valid
+ if agent.stopped {
+ agent.requestQueue.RequestComplete()
+ return errors.New("device-agent-stopped")
+ }
+ //update device TransientState
+ if err := agent.updateTransientState(ctx, transientState); err != nil {
+ agent.requestQueue.RequestComplete()
+ return err
+ }
+ // update in db
+ if err := agent.dbProxy.Set(ctx, agent.deviceID, device); err != nil {
+ //Reverting TransientState update
+ err := agent.updateTransientState(ctx, prevTransientState)
+ logger.Errorw(ctx, "failed-to-revert-transient-state-update-on-error", log.Fields{"device-id": device.Id,
+ "previousTransientState": prevTransientState, "currentTransientState": transientState})
+ agent.requestQueue.RequestComplete()
+ return status.Errorf(codes.Internal, "failed-update-device:%s: %s", agent.deviceID, err)
+ }
+
+ logger.Debugw(ctx, "updated-device-in-store", log.Fields{"device-id: ": agent.deviceID})
+
+ prevDevice := agent.device
+ // update the device
+ agent.device = device
+
+ // release lock before processing transition
+ agent.requestQueue.RequestComplete()
+
+ if err := agent.deviceMgr.stateTransitions.ProcessTransition(log.WithSpanFromContext(context.Background(), ctx),
+ device, prevDevice, transientState, prevTransientState); err != nil {
+ logger.Errorw(ctx, "failed-process-transition", log.Fields{"device-id": device.Id, "previousAdminState": prevDevice.AdminState, "currentAdminState": device.AdminState})
+ }
+ return nil
+}
func (agent *Agent) updateDeviceReason(ctx context.Context, reason string) error {
if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
return err
diff --git a/rw_core/core/device/agent_port.go b/rw_core/core/device/agent_port.go
index e90a0a4..a3489fc 100644
--- a/rw_core/core/device/agent_port.go
+++ b/rw_core/core/device/agent_port.go
@@ -123,8 +123,9 @@
return err
}
- if device.AdminState != voltha.AdminState_DISABLED && device.AdminState != voltha.AdminState_DELETED {
- err := status.Error(codes.FailedPrecondition, fmt.Sprintf("invalid-state-%v", device.AdminState))
+ if device.AdminState != voltha.AdminState_DISABLED && !agent.isDeletionInProgress() {
+ err := status.Error(codes.FailedPrecondition, fmt.Sprintf("invalid-admin-state-%v",
+ device.AdminState))
logger.Warnw(ctx, "invalid-state-removing-ports", log.Fields{"state": device.AdminState, "error": err})
return err
}
diff --git a/rw_core/core/device/agent_transient_state.go b/rw_core/core/device/agent_transient_state.go
new file mode 100644
index 0000000..776d60d
--- /dev/null
+++ b/rw_core/core/device/agent_transient_state.go
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package device
+
+import (
+ "context"
+ "github.com/opencord/voltha-protos/v4/go/voltha"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+func (agent *Agent) getTransientState() voltha.DeviceTransientState_Types {
+ transientStateHandle := agent.transientStateLoader.Lock()
+ deviceTransientState := transientStateHandle.GetReadOnly()
+ transientStateHandle.UnLock()
+ return deviceTransientState
+}
+
+func (agent *Agent) updateTransientState(ctx context.Context, transientState voltha.DeviceTransientState_Types) error {
+ // Update device transient state
+ transientStateHandle := agent.transientStateLoader.Lock()
+ if err := transientStateHandle.Update(ctx, transientState); err != nil {
+ transientStateHandle.UnLock()
+ return status.Errorf(codes.Internal, "failed-update-device-transient-state:%s: %s", agent.deviceID, err)
+ }
+ transientStateHandle.UnLock()
+ return nil
+}
+
+func (agent *Agent) isDeletionInProgress() bool {
+ deviceTransientState := agent.getTransientState()
+ return deviceTransientState == voltha.DeviceTransientState_FORCE_DELETING ||
+ deviceTransientState == voltha.DeviceTransientState_DELETING_FROM_ADAPTER ||
+ deviceTransientState == voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE
+}
+
+func (agent *Agent) isStateDeleting(deviceTransientState voltha.DeviceTransientState_Types) bool {
+ return deviceTransientState == voltha.DeviceTransientState_FORCE_DELETING ||
+ deviceTransientState == voltha.DeviceTransientState_DELETING_FROM_ADAPTER ||
+ deviceTransientState == voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE
+}
+func (agent *Agent) deleteTransientState(ctx context.Context) error {
+ transientStateHandle := agent.transientStateLoader.Lock()
+ if err := transientStateHandle.Delete(ctx); err != nil {
+ transientStateHandle.UnLock()
+ return status.Errorf(codes.Internal, "failed-delete-device-transient-state:%s: %s", agent.deviceID, err)
+ }
+ transientStateHandle.UnLock()
+ return nil
+}
diff --git a/rw_core/core/device/manager.go b/rw_core/core/device/manager.go
index 3899623..9220fe5 100755
--- a/rw_core/core/device/manager.go
+++ b/rw_core/core/device/manager.go
@@ -209,7 +209,6 @@
// DeleteDevice removes a device from the data model
func (dMgr *Manager) DeleteDevice(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
log.EnrichSpan(ctx, log.Fields{"device-id": id.Id})
-
logger.Debugw(ctx, "DeleteDevice", log.Fields{"device-id": id.Id})
agent := dMgr.getDeviceAgent(ctx, id.Id)
if agent == nil {
@@ -218,6 +217,17 @@
return &empty.Empty{}, agent.deleteDevice(ctx)
}
+// ForceDeleteDevice removes a device from the data model forcefully without successfully waiting for the adapters.
+func (dMgr *Manager) ForceDeleteDevice(ctx context.Context, id *voltha.ID) (*empty.Empty, error) {
+ log.EnrichSpan(ctx, log.Fields{"device-id": id.Id})
+ logger.Debugw(ctx, "ForceDeleteDevice", log.Fields{"device-id": id.Id})
+ agent := dMgr.getDeviceAgent(ctx, id.Id)
+ if agent == nil {
+ return nil, status.Errorf(codes.NotFound, "%s", id.Id)
+ }
+ return &empty.Empty{}, agent.deleteDeviceForce(ctx)
+}
+
// GetDevicePort returns the port details for a specific device port entry
func (dMgr *Manager) GetDevicePort(ctx context.Context, deviceID string, portID uint32) (*voltha.Port, error) {
logger.Debugw(ctx, "ListDevicePorts", log.Fields{"device-id": deviceID})
@@ -473,10 +483,11 @@
if !device.Root {
continue
}
- if hostPort != "" && hostPort == device.GetHostAndPort() && device.AdminState != voltha.AdminState_DELETED {
+
+ if hostPort != "" && hostPort == device.GetHostAndPort() {
return true, nil
}
- if newDevice.MacAddress != "" && newDevice.MacAddress == device.MacAddress && device.AdminState != voltha.AdminState_DELETED {
+ if newDevice.MacAddress != "" && newDevice.MacAddress == device.MacAddress {
return true, nil
}
}
@@ -589,8 +600,8 @@
return err
}
- // If the device is in Pre-provisioning or deleted state stop here
- if device.AdminState == voltha.AdminState_PREPROVISIONED || device.AdminState == voltha.AdminState_DELETED {
+ // If the device is in Pre-provisioning or getting deleted state stop here
+ if device.AdminState == voltha.AdminState_PREPROVISIONED || dAgent.isDeletionInProgress() {
return nil
}
@@ -645,11 +656,14 @@
}
// isOkToReconcile validates whether a device is in the correct status to be reconciled
-func isOkToReconcile(device *voltha.Device) bool {
+func (dMgr *Manager) isOkToReconcile(ctx context.Context, device *voltha.Device) bool {
if device == nil {
return false
}
- return device.AdminState != voltha.AdminState_PREPROVISIONED && device.AdminState != voltha.AdminState_DELETED
+ if agent := dMgr.getDeviceAgent(ctx, device.Id); agent != nil {
+ return device.AdminState != voltha.AdminState_PREPROVISIONED && (!agent.isDeletionInProgress())
+ }
+ return false
}
// adapterRestarted is invoked whenever an adapter is restarted
@@ -672,7 +686,7 @@
continue
}
if isDeviceOwnedByService {
- if isOkToReconcile(rootDevice) {
+ if dMgr.isOkToReconcile(ctx, rootDevice) {
logger.Debugw(ctx, "reconciling-root-device", log.Fields{"rootId": rootDevice.Id})
responses = append(responses, dMgr.sendReconcileDeviceRequest(ctx, rootDevice))
} else {
@@ -689,7 +703,7 @@
logger.Warnw(ctx, "is-device-owned-by-service", log.Fields{"error": err, "child-device-id": childDevice.Id, "adapterType": adapter.Type, "replica-number": adapter.CurrentReplica})
}
if isDeviceOwnedByService {
- if isOkToReconcile(childDevice) {
+ if dMgr.isOkToReconcile(ctx, childDevice) {
logger.Debugw(ctx, "reconciling-child-device", log.Fields{"child-device-id": childDevice.Id})
responses = append(responses, dMgr.sendReconcileDeviceRequest(ctx, childDevice))
} else {
@@ -1222,11 +1236,29 @@
//DeleteAllChildDevices is invoked as a callback when the parent device is deleted
func (dMgr *Manager) DeleteAllChildDevices(ctx context.Context, parentCurrDevice *voltha.Device) error {
logger.Debug(ctx, "DeleteAllChildDevices")
+ force := false
+ // Get the parent device Transient state, if its FORCE_DELETED(go for force delete for child devices)
+ // So in cases when this handler is getting called other than DELETE operation, no force option would be used.
+ agent := dMgr.getDeviceAgent(ctx, parentCurrDevice.Id)
+ if agent == nil {
+ return status.Errorf(codes.NotFound, "%s", parentCurrDevice.Id)
+ }
+
+ force = agent.getTransientState() == voltha.DeviceTransientState_FORCE_DELETING
+
ports, _ := dMgr.listDevicePorts(ctx, parentCurrDevice.Id)
for childDeviceID := range dMgr.getAllChildDeviceIds(ctx, ports) {
if agent := dMgr.getDeviceAgent(ctx, childDeviceID); agent != nil {
- if err := agent.deleteDevice(ctx); err != nil {
- logger.Warnw(ctx, "failure-delete-device", log.Fields{"device-id": childDeviceID, "error": err.Error()})
+ if force {
+ if err := agent.deleteDeviceForce(ctx); err != nil {
+ logger.Warnw(ctx, "failure-delete-device-force", log.Fields{"device-id": childDeviceID,
+ "error": err.Error()})
+ }
+ } else {
+ if err := agent.deleteDevice(ctx); err != nil {
+ logger.Warnw(ctx, "failure-delete-device", log.Fields{"device-id": childDeviceID,
+ "error": err.Error()})
+ }
}
// No further action is required here. The deleteDevice will change the device state where the resulting
// callback will take care of cleaning the child device agent.
diff --git a/rw_core/core/device/state/transitions.go b/rw_core/core/device/state/transitions.go
index 81ac69d..e65c396 100644
--- a/rw_core/core/device/state/transitions.go
+++ b/rw_core/core/device/state/transitions.go
@@ -18,11 +18,10 @@
import (
"context"
- "reflect"
- "runtime"
-
"github.com/opencord/voltha-lib-go/v4/pkg/log"
"github.com/opencord/voltha-protos/v4/go/voltha"
+ "reflect"
+ "runtime"
)
// deviceType mentions type of device like parent, child
@@ -34,7 +33,7 @@
any deviceType = 2
)
-type matchResult uint8
+type matchResult uint16
const (
noMatch matchResult = iota // current state has not match in the transition table
@@ -45,17 +44,18 @@
// match is used to keep the current match states
type match struct {
- admin, oper, conn matchResult
+ admin, oper, conn, transient matchResult
}
// toInt returns an integer representing the matching level of the match (the larger the number the better)
func (m *match) toInt() int {
- return int(m.admin<<4 | m.oper<<2 | m.conn)
+ return int(m.transient<<8 | m.admin<<4 | m.oper<<2 | m.conn)
}
// isExactMatch returns true if match is an exact match
func (m *match) isExactMatch() bool {
- return m.admin == currPrevStateMatch && m.oper == currPrevStateMatch && m.conn == currPrevStateMatch
+ return m.admin == currPrevStateMatch && m.oper == currPrevStateMatch && m.conn == currPrevStateMatch &&
+ m.transient == currPrevStateMatch
}
// isBetterMatch returns true if newMatch is a worse match
@@ -68,6 +68,7 @@
Admin voltha.AdminState_Types
Connection voltha.ConnectStatus_Types
Operational voltha.OperStatus_Types
+ Transient voltha.DeviceTransientState_Types
}
// transitionHandler function type which takes the current and previous device info as input parameter
@@ -110,161 +111,203 @@
transitionMap.transitions,
transition{
deviceType: parent,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.CreateLogicalDevice}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: child,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: child,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.SetupUNILogicalPorts}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: child,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_DISCOVERED, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: child,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.SetupUNILogicalPorts}})
transitionMap.transitions = append(transitionMap.transitions,
- transition{
+ transition{ //DELETE PRE PROVISIONED State device forcefully
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+ currentState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_FORCE_DELETING},
handlers: []transitionHandler{dMgr.RunPostDeviceDelete}})
transitionMap.transitions = append(transitionMap.transitions,
- transition{
+ transition{ // DELETE PRE PROVISIONED State device no force option set
+ deviceType: any,
+ previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+ currentState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE},
+ handlers: []transitionHandler{dMgr.RunPostDeviceDelete}})
+ transitionMap.transitions = append(transitionMap.transitions,
+ transition{ //DELETE device forcefully
deviceType: parent,
- previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_FORCE_DELETING},
handlers: []transitionHandler{dMgr.DeleteAllLogicalPorts, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.RunPostDeviceDelete}})
transitionMap.transitions = append(transitionMap.transitions,
+ transition{ //DELETE device after adapter response
+ deviceType: parent,
+ previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE},
+ handlers: []transitionHandler{dMgr.DeleteAllLogicalPorts, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.RunPostDeviceDelete}})
+ transitionMap.transitions = append(transitionMap.transitions,
+ transition{ //DELETE no operation transition
+ deviceType: parent,
+ previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_FROM_ADAPTER},
+ handlers: []transitionHandler{}})
+ transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: parent,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_ACTIVE},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.DeleteAllLogicalPorts, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.DeleteAllDeviceFlows}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: parent,
- previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.DeleteAllLogicalPorts, dMgr.DeleteAllChildDevices, dMgr.DeleteLogicalDevice, dMgr.DeleteAllDeviceFlows}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: parent,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_ACTIVE},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.CreateLogicalDevice}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: parent,
- previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNREACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_REACHABLE, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.CreateLogicalDevice}})
transitionMap.transitions = append(transitionMap.transitions,
- transition{
+ transition{ //DELETE force case
deviceType: child,
- previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_FORCE_DELETING},
handlers: []transitionHandler{dMgr.ChildDeviceLost, dMgr.DeleteLogicalPorts, dMgr.RunPostDeviceDelete}})
transitionMap.transitions = append(transitionMap.transitions,
- transition{
+ transition{ //DELETE after adapter response case
deviceType: child,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_DELETED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE},
handlers: []transitionHandler{dMgr.ChildDeviceLost, dMgr.DeleteLogicalPorts, dMgr.RunPostDeviceDelete}})
transitionMap.transitions = append(transitionMap.transitions,
+ transition{ //DELETE wait for adapter response(no operation)
+ deviceType: child,
+ previousState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_ANY},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_DELETING_FROM_ADAPTER},
+ handlers: []transitionHandler{}})
+ transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: parent,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVE, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING},
- currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_ACTIVATING, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_ENABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: child,
- previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_UNKNOWN, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_PREPROVISIONED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
transitionMap.transitions = append(transitionMap.transitions,
transition{
deviceType: any,
- previousState: deviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
- currentState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN},
+ previousState: deviceState{Admin: voltha.AdminState_DOWNLOADING_IMAGE, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
+ currentState: deviceState{Admin: voltha.AdminState_DISABLED, Connection: voltha.ConnectStatus_UNKNOWN, Operational: voltha.OperStatus_UNKNOWN, Transient: voltha.DeviceTransientState_NONE},
handlers: []transitionHandler{dMgr.NotifyInvalidTransition}})
return &transitionMap
}
-func getDeviceStates(device *voltha.Device) deviceState {
- return deviceState{Admin: device.AdminState, Connection: device.ConnectStatus, Operational: device.OperStatus}
+func getDeviceStates(device *voltha.Device, transientState voltha.DeviceTransientState_Types) deviceState {
+ return deviceState{Admin: device.AdminState, Connection: device.ConnectStatus, Operational: device.OperStatus,
+ Transient: transientState}
}
// isMatched matches a state transition. It returns whether there is a match and if there is whether it is an exact match
func getHandler(previous deviceState, current deviceState, transition *transition) ([]transitionHandler, *match) {
m := &match{}
+ var waitForOtherStatesMatch bool
// Do we have an exact match?
if previous == transition.previousState && current == transition.currentState {
- return transition.handlers, &match{admin: currPrevStateMatch, oper: currPrevStateMatch, conn: currPrevStateMatch}
+ return transition.handlers, &match{admin: currPrevStateMatch, oper: currPrevStateMatch, conn: currPrevStateMatch,
+ transient: currPrevStateMatch}
+ }
+ // Do we have transient state match?
+ if current.Transient == transition.currentState.Transient && transition.currentState.Transient != voltha.DeviceTransientState_ANY {
+ if previous.Transient == transition.previousState.Transient || transition.previousState.Transient == voltha.DeviceTransientState_ANY {
+ m.transient = currPrevStateMatch
+ } else {
+ m.transient = currStateOnlyMatch
+ }
+ } else if current.Transient == transition.currentState.Transient && transition.currentState.Transient == voltha.DeviceTransientState_ANY {
+ if previous.Transient == transition.previousState.Transient || transition.previousState.Transient == voltha.DeviceTransientState_ANY {
+ m.transient = currWildcardMatch
+ }
+ }
+ if m.transient == noMatch {
+ return nil, m
}
// Do we have Admin state match?
@@ -278,12 +321,14 @@
if previous.Admin == transition.previousState.Admin || transition.previousState.Admin == voltha.AdminState_UNKNOWN {
m.admin = currWildcardMatch
}
+ } else if transition.previousState.Admin == voltha.AdminState_UNKNOWN && transition.currentState.Admin == voltha.AdminState_UNKNOWN {
+ // Will only be the case of DELETION currently.(to allow only transient match, we can avoid this check if
+ // we can allow wild card in admin state)
+ waitForOtherStatesMatch = true
}
- if m.admin == noMatch {
- // invalid transition - need to match on current admin state
+ if !waitForOtherStatesMatch && m.admin == noMatch {
return nil, m
}
-
// Do we have an operational state match?
if current.Operational == transition.currentState.Operational && transition.previousState.Operational != voltha.OperStatus_UNKNOWN {
if previous.Operational == transition.previousState.Operational || transition.previousState.Operational == voltha.OperStatus_UNKNOWN {
@@ -309,15 +354,15 @@
m.conn = currWildcardMatch
}
}
-
return transition.handlers, m
}
// getTransitionHandler returns transition handler & a flag that's set if the transition is invalid
-func (tMap *TransitionMap) getTransitionHandler(ctx context.Context, cDevice, pDevice *voltha.Device) []transitionHandler {
+func (tMap *TransitionMap) getTransitionHandler(ctx context.Context, cDevice, pDevice *voltha.Device,
+ cTransientState, pTransientState voltha.DeviceTransientState_Types) []transitionHandler {
//1. Get the previous and current set of states
- cState := getDeviceStates(cDevice)
- pState := getDeviceStates(pDevice)
+ cState := getDeviceStates(cDevice, cTransientState)
+ pState := getDeviceStates(pDevice, pTransientState)
// Do nothing is there are no states change
if pState == cState {
@@ -355,23 +400,27 @@
return currentMatch
}
-func (tMap *TransitionMap) ProcessTransition(ctx context.Context, device, prevDevice *voltha.Device) error {
+func (tMap *TransitionMap) ProcessTransition(ctx context.Context, device, prevDevice *voltha.Device,
+ deviceTransientState, prevDeviceTransientState voltha.DeviceTransientState_Types) error {
// This will be triggered on every state update
logger.Debugw(ctx, "state-transition", log.Fields{
- "device": device.Id,
- "prev-admin-state": prevDevice.AdminState,
- "prev-oper-state": prevDevice.OperStatus,
- "prev-conn-state": prevDevice.ConnectStatus,
- "curr-admin-state": device.AdminState,
- "curr-oper-state": device.OperStatus,
- "curr-conn-state": device.ConnectStatus,
+ "device": device.Id,
+ "prev-admin-state": prevDevice.AdminState,
+ "prev-oper-state": prevDevice.OperStatus,
+ "prev-conn-state": prevDevice.ConnectStatus,
+ "curr-admin-state": device.AdminState,
+ "curr-oper-state": device.OperStatus,
+ "curr-conn-state": device.ConnectStatus,
+ "curr-transient-state": deviceTransientState,
+ "prev-transient-state": prevDeviceTransientState,
})
- handlers := tMap.getTransitionHandler(ctx, device, prevDevice)
+ handlers := tMap.getTransitionHandler(ctx, device, prevDevice, deviceTransientState, prevDeviceTransientState)
if handlers == nil {
logger.Debugw(ctx, "no-op-transition", log.Fields{"deviceId": device.Id})
return nil
}
- logger.Debugw(ctx, "handler-found", log.Fields{"num-expectedHandlers": len(handlers), "isParent": device.Root, "current-data": device, "previous-data": prevDevice})
+ logger.Debugw(ctx, "handler-found", log.Fields{"num-expectedHandlers": len(handlers), "isParent": device.Root,
+ "current-data": device, "previous-data": prevDevice})
for _, handler := range handlers {
logger.Debugw(ctx, "running-handler", log.Fields{"handler": funcName(handler)})
if err := handler(ctx, device); err != nil {
diff --git a/rw_core/core/device/state/transitions_test.go b/rw_core/core/device/state/transitions_test.go
index a8f96ad..a085f97 100644
--- a/rw_core/core/device/state/transitions_test.go
+++ b/rw_core/core/device/state/transitions_test.go
@@ -52,123 +52,151 @@
}
func assertInvalidTransition(t *testing.T, device, prevDevice *voltha.Device) {
- handlers := transitionMap.getTransitionHandler(context.Background(), device, prevDevice)
+ handlers := transitionMap.getTransitionHandler(context.Background(), device, prevDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.NotifyInvalidTransition).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
}
func assertNoOpTransition(t *testing.T, device, prevDevice *voltha.Device) {
- handlers := transitionMap.getTransitionHandler(context.Background(), device, prevDevice)
+ handlers := transitionMap.getTransitionHandler(context.Background(), device, prevDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 0, len(handlers))
}
func TestValidTransitions(t *testing.T) {
ctx := context.Background()
+
previousDevice := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
device := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
- handlers := transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers := transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_DISCOVERED)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_DISCOVERED)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVATING)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVATING)
device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.SetupUNILogicalPorts).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
- device = getDevice(true, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ device = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+ voltha.DeviceTransientState_ANY)
+ assert.Equal(t, 1, len(handlers))
+ assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
+
+ previousDevice = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+ device = getDevice(true, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE,
+ voltha.DeviceTransientState_ANY)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
- device = getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ device = getDevice(false, voltha.AdminState_PREPROVISIONED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+ voltha.DeviceTransientState_ANY)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.RunPostDeviceDelete).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_ACTIVE)
- device = getDevice(false, voltha.AdminState_DELETED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_FAILED)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ device = getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_FAILED)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+ voltha.DeviceTransientState_ANY)
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())
@@ -176,7 +204,8 @@
previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
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.DeleteAllChildDevices).Pointer() == reflect.ValueOf(handlers[1]).Pointer())
@@ -185,13 +214,15 @@
previousDevice = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
device = getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
previousDevice = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN)
device = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
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.DeleteAllChildDevices).Pointer() == reflect.ValueOf(handlers[1]).Pointer())
@@ -200,7 +231,8 @@
previousDevice = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN)
device = getDevice(true, voltha.AdminState_DISABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN)
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_NONE,
+ voltha.DeviceTransientState_NONE)
assert.Equal(t, 1, len(handlers))
assert.True(t, reflect.ValueOf(tdm.CreateLogicalDevice).Pointer() == reflect.ValueOf(handlers[0]).Pointer())
@@ -220,9 +252,9 @@
getDevice(false, voltha.AdminState_DISABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN),
},
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),
+ getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN),
+ getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_UNKNOWN),
+ getDevice(false, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_FAILED),
},
expectedParentHandlers: []transitionHandler{
tdm.DeleteAllLogicalPorts,
@@ -242,7 +274,8 @@
for _, device := range deleteDeviceTest.devices {
device.Root = true
t.Run(testName, func(t *testing.T) {
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+ voltha.DeviceTransientState_ANY)
assert.Equal(t, 4, len(handlers))
for idx, expHandler := range deleteDeviceTest.expectedParentHandlers {
assert.True(t, reflect.ValueOf(expHandler).Pointer() == reflect.ValueOf(handlers[idx]).Pointer())
@@ -256,7 +289,8 @@
for _, device := range deleteDeviceTest.devices {
device.Root = false
t.Run(testName, func(t *testing.T) {
- handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice)
+ handlers = transitionMap.getTransitionHandler(ctx, device, previousDevice, voltha.DeviceTransientState_FORCE_DELETING,
+ voltha.DeviceTransientState_ANY)
assert.Equal(t, 3, len(handlers))
for idx, expHandler := range deleteDeviceTest.expectedChildHandlers {
assert.True(t, reflect.ValueOf(expHandler).Pointer() == reflect.ValueOf(handlers[idx]).Pointer())
@@ -264,6 +298,7 @@
})
}
}
+
}
func TestInvalidTransitions(t *testing.T) {
@@ -297,6 +332,7 @@
}
func TestNoOpTransitions(t *testing.T) {
+
previousDevice := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
device := getDevice(true, voltha.AdminState_ENABLED, voltha.ConnectStatus_UNKNOWN, voltha.OperStatus_UNKNOWN)
assertNoOpTransition(t, device, previousDevice)
@@ -323,7 +359,7 @@
}
func TestMatch(t *testing.T) {
- best := &match{admin: currPrevStateMatch, oper: currPrevStateMatch, conn: currPrevStateMatch}
- m := &match{admin: currStateOnlyMatch, oper: currWildcardMatch, conn: currWildcardMatch}
+ best := &match{admin: currPrevStateMatch, oper: currPrevStateMatch, conn: currPrevStateMatch, transient: currWildcardMatch}
+ m := &match{admin: currStateOnlyMatch, oper: currWildcardMatch, conn: currWildcardMatch, transient: currWildcardMatch}
fmt.Println(m.isBetterMatch(best), m.toInt(), best.toInt())
}
diff --git a/rw_core/core/device/transientstate/common.go b/rw_core/core/device/transientstate/common.go
new file mode 100644
index 0000000..b22c789
--- /dev/null
+++ b/rw_core/core/device/transientstate/common.go
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Package core Common Logger initialization
+package transientstate
+
+import (
+ "github.com/opencord/voltha-lib-go/v4/pkg/log"
+)
+
+var logger log.CLogger
+
+func init() {
+ // Setup this package so that it's log level can be modified at run time
+ var err error
+ logger, err = log.RegisterPackage(log.JSON, log.ErrorLevel, log.Fields{})
+ if err != nil {
+ panic(err)
+ }
+}
diff --git a/rw_core/core/device/transientstate/loader.go b/rw_core/core/device/transientstate/loader.go
new file mode 100644
index 0000000..f8710cc
--- /dev/null
+++ b/rw_core/core/device/transientstate/loader.go
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package transientstate
+
+import (
+ "context"
+ "fmt"
+ "sync"
+
+ "github.com/opencord/voltha-go/db/model"
+ "github.com/opencord/voltha-lib-go/v4/pkg/log"
+ "github.com/opencord/voltha-protos/v4/go/voltha"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+// Loader hides all low-level locking & synchronization related to device transient state updates
+type Loader struct {
+ dbProxy *model.Proxy
+ // this lock protects the device transient state
+ lock sync.RWMutex
+ deviceTransientState *data
+}
+
+type data struct {
+ transientState voltha.DeviceTransientState_Types
+ deviceID string
+}
+
+func NewLoader(dbProxy *model.Proxy, deviceID string) *Loader {
+ return &Loader{
+ dbProxy: dbProxy,
+ deviceTransientState: &data{
+ transientState: voltha.DeviceTransientState_NONE,
+ deviceID: deviceID,
+ },
+ }
+}
+
+// Load queries existing transient state from the kv,
+// and should only be called once when first created.
+func (loader *Loader) Load(ctx context.Context) {
+ loader.lock.Lock()
+ defer loader.lock.Unlock()
+
+ var deviceTransientState voltha.DeviceTransientState
+ if have, err := loader.dbProxy.Get(ctx, loader.deviceTransientState.deviceID, &deviceTransientState); err != nil || !have {
+ logger.Errorw(ctx, "failed-to-get-device-transient-state-from-cluster-data-proxy", log.Fields{"error": err})
+ return
+ }
+ loader.deviceTransientState.transientState = deviceTransientState.TransientState
+}
+
+// Lock acquires the lock for deviceTransientStateLoader, and returns a handle
+// which can be used to access it until it's unlocked.
+// This handle ensures that the deviceTransientState cannot be accessed if the lock is not held.
+// TODO: consider accepting a ctx and aborting the lock attempt on cancellation
+func (loader *Loader) Lock() *Handle {
+ loader.lock.Lock()
+ dataTransientState := loader.deviceTransientState
+ return &Handle{loader: loader, data: dataTransientState}
+}
+
+// Handle is allocated for each Lock() call, all modifications are made using it, and it is invalidated by Unlock()
+// This enforces correct Lock()-Usage()-Unlock() ordering.
+type Handle struct {
+ loader *Loader
+ data *data
+}
+
+// GetReadOnly returns device transient which MUST NOT be modified externally, but which is safe to keep indefinitely
+func (h *Handle) GetReadOnly() voltha.DeviceTransientState_Types {
+ return h.data.transientState
+}
+
+// Update updates device transient state in KV store
+// The provided device transient state must not be modified afterwards.
+func (h *Handle) Update(ctx context.Context, state voltha.DeviceTransientState_Types) error {
+ var tState voltha.DeviceTransientState
+ tState.TransientState = state
+ if err := h.loader.dbProxy.Set(ctx, fmt.Sprint(h.data.deviceID), &tState); err != nil {
+ return status.Errorf(codes.Internal, "failed-to-update-device-%v-transient-state: %s", h.data.deviceID, err)
+ }
+ h.data.transientState = state
+ return nil
+}
+
+// Delete deletes device transient state from KV store
+func (h *Handle) Delete(ctx context.Context) error {
+ if err := h.loader.dbProxy.Remove(ctx, fmt.Sprint(h.data.deviceID)); err != nil {
+ return status.Errorf(codes.Internal, "failed-to-delete-device-%v-transient-state: %s", h.data.deviceID, err)
+ }
+ return nil
+}
+
+// UnLock releases the lock on the device transient state.
+func (h *Handle) UnLock() {
+ defer h.loader.lock.Unlock()
+ h.data = nil
+}
diff --git a/rw_core/mocks/adapter.go b/rw_core/mocks/adapter.go
index 26f796fa4..c01fc70 100644
--- a/rw_core/mocks/adapter.go
+++ b/rw_core/mocks/adapter.go
@@ -45,13 +45,14 @@
// Adapter represents adapter attributes
type Adapter struct {
- coreProxy adapterif.CoreProxy
- flows map[uint64]*voltha.OfpFlowStats
- flowLock sync.RWMutex
- devices map[string]*voltha.Device
- deviceLock sync.RWMutex
- failFlowAdd bool
- failFlowDelete bool
+ coreProxy adapterif.CoreProxy
+ flows map[uint64]*voltha.OfpFlowStats
+ flowLock sync.RWMutex
+ devices map[string]*voltha.Device
+ deviceLock sync.RWMutex
+ failFlowAdd bool
+ failFlowDelete bool
+ failDeleteDevice bool
}
// NewAdapter creates adapter instance
@@ -133,6 +134,9 @@
// Delete_device -
func (ta *Adapter) Delete_device(ctx context.Context, device *voltha.Device) error { // nolint
+ if ta.failDeleteDevice {
+ return fmt.Errorf("delete-device-failure")
+ }
return nil
}
@@ -284,3 +288,8 @@
ta.failFlowAdd = failFlowAdd
ta.failFlowDelete = failFlowDelete
}
+
+// SetDeleteAction sets the adapter action on delete device
+func (ta *Adapter) SetDeleteAction(failDeleteDevice bool) {
+ ta.failDeleteDevice = failDeleteDevice
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v4/go/common/common.pb.go b/vendor/github.com/opencord/voltha-protos/v4/go/common/common.pb.go
index c476a08..0956330 100644
--- a/vendor/github.com/opencord/voltha-protos/v4/go/common/common.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v4/go/common/common.pb.go
@@ -57,10 +57,6 @@
AdminState_DISABLED AdminState_Types = 3
// The device is in the state of image download
AdminState_DOWNLOADING_IMAGE AdminState_Types = 4
- // The device is marked to be deleted
- AdminState_DELETED AdminState_Types = 5
- // The device is marked to be in deleting state
- AdminState_DELETING AdminState_Types = 6
)
var AdminState_Types_name = map[int32]string{
@@ -69,8 +65,6 @@
2: "ENABLED",
3: "DISABLED",
4: "DOWNLOADING_IMAGE",
- 5: "DELETED",
- 6: "DELETING",
}
var AdminState_Types_value = map[string]int32{
@@ -79,8 +73,6 @@
"ENABLED": 2,
"DISABLED": 3,
"DOWNLOADING_IMAGE": 4,
- "DELETED": 5,
- "DELETING": 6,
}
func (x AdminState_Types) String() string {
@@ -604,44 +596,43 @@
func init() { proto.RegisterFile("voltha_protos/common.proto", fileDescriptor_c2e3fd231961e826) }
var fileDescriptor_c2e3fd231961e826 = []byte{
- // 614 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x4f, 0x4f, 0xdb, 0x4e,
- 0x10, 0x8d, 0x9d, 0x3f, 0x3f, 0x32, 0x21, 0xc6, 0xbf, 0x05, 0xaa, 0x14, 0x55, 0x6a, 0xe4, 0x0b,
- 0xb4, 0xa2, 0x89, 0x44, 0xb9, 0xf6, 0x60, 0xec, 0x2d, 0x5d, 0x01, 0xeb, 0x68, 0x6d, 0x07, 0xd1,
- 0x43, 0x23, 0x13, 0x2f, 0xc1, 0x12, 0xf1, 0x5a, 0xf6, 0x06, 0x89, 0x73, 0x3f, 0x64, 0xbf, 0x4e,
- 0xb5, 0xeb, 0xf0, 0xaf, 0xe2, 0x62, 0xfb, 0xcd, 0x7b, 0x3b, 0x33, 0x6f, 0xc6, 0x0b, 0x7b, 0xf7,
- 0xe2, 0x4e, 0xde, 0x26, 0xb3, 0xa2, 0x14, 0x52, 0x54, 0xe3, 0xb9, 0x58, 0x2e, 0x45, 0x3e, 0xd2,
- 0x08, 0x75, 0x6a, 0xe4, 0xec, 0x80, 0x49, 0x7c, 0x64, 0x81, 0x99, 0xa5, 0x03, 0x63, 0x68, 0x1c,
- 0x74, 0x99, 0x99, 0xa5, 0xce, 0x3e, 0x34, 0x89, 0x5f, 0xa1, 0x21, 0xb4, 0x33, 0xc9, 0x97, 0xd5,
- 0xc0, 0x18, 0x36, 0x0f, 0x7a, 0x47, 0x30, 0x5a, 0xa7, 0x20, 0x3e, 0xab, 0x09, 0xe7, 0xb7, 0x01,
- 0xe0, 0xa6, 0xcb, 0x2c, 0x0f, 0x65, 0x22, 0xb9, 0xb3, 0x82, 0x76, 0xf4, 0x50, 0xf0, 0x0a, 0xf5,
- 0xe0, 0xbf, 0x98, 0x9e, 0xd1, 0xe0, 0x92, 0xda, 0x0d, 0x84, 0xc0, 0x9a, 0x30, 0x3c, 0x61, 0xc1,
- 0x94, 0x84, 0x24, 0xa0, 0xd8, 0xb7, 0x0d, 0x25, 0xc0, 0xd4, 0x3d, 0x39, 0xc7, 0xbe, 0x6d, 0xa2,
- 0x4d, 0xd8, 0xf0, 0x49, 0x58, 0xa3, 0x26, 0xda, 0x85, 0xff, 0xfd, 0xe0, 0x92, 0x9e, 0x07, 0xae,
- 0x4f, 0xe8, 0xe9, 0x8c, 0x5c, 0xb8, 0xa7, 0xd8, 0x6e, 0xa9, 0x13, 0x3e, 0x3e, 0xc7, 0x11, 0xf6,
- 0xed, 0xb6, 0x3e, 0xa1, 0x00, 0xa1, 0xa7, 0x76, 0xc7, 0x59, 0x00, 0x04, 0x05, 0x2f, 0x55, 0x0f,
- 0xab, 0xca, 0xb9, 0x7a, 0xb3, 0x09, 0x0b, 0xc0, 0x27, 0xa1, 0x17, 0x4c, 0x31, 0xd3, 0x0d, 0x58,
- 0x00, 0xae, 0x17, 0x91, 0xa9, 0xab, 0x73, 0x98, 0x4a, 0x1c, 0xe1, 0x50, 0x83, 0x26, 0x02, 0xe8,
- 0x68, 0x52, 0xd5, 0x05, 0xe8, 0x7c, 0x77, 0x89, 0x6a, 0xad, 0xed, 0x60, 0xe8, 0x7b, 0x22, 0xcf,
- 0xf9, 0x5c, 0xae, 0x6b, 0x1d, 0xbf, 0x59, 0x6b, 0x0b, 0x7a, 0x31, 0x65, 0xd8, 0xf5, 0x7e, 0x28,
- 0x4f, 0xb6, 0x81, 0xfa, 0xd0, 0x7d, 0x86, 0xa6, 0xf3, 0xc7, 0x80, 0xbe, 0x6a, 0x38, 0x91, 0x99,
- 0xc8, 0x19, 0xaf, 0x0a, 0xf4, 0x0d, 0x5a, 0x73, 0x91, 0x72, 0xbd, 0x02, 0xeb, 0xe8, 0xd3, 0xe3,
- 0xa0, 0x5f, 0x89, 0x5e, 0x22, 0xb9, 0x2a, 0x73, 0x4f, 0xa4, 0x9c, 0xe9, 0x63, 0x68, 0x1f, 0xb6,
- 0x92, 0x34, 0xcd, 0x14, 0x97, 0xdc, 0xcd, 0xb2, 0xfc, 0x46, 0x0c, 0x4c, 0xbd, 0x4c, 0xeb, 0x39,
- 0x4c, 0xf2, 0x1b, 0xe1, 0xfc, 0x82, 0xed, 0x37, 0xb2, 0xa8, 0x91, 0x07, 0x13, 0xcc, 0xdc, 0x88,
- 0x04, 0x74, 0x16, 0xc6, 0x9e, 0x87, 0xc3, 0xd0, 0x6e, 0xbc, 0x0e, 0xab, 0x21, 0xc4, 0x4c, 0xb9,
- 0x79, 0x0f, 0xbb, 0xcf, 0xe1, 0x98, 0x86, 0xf1, 0x64, 0x12, 0x30, 0xb5, 0x17, 0xd3, 0x39, 0x84,
- 0xee, 0x34, 0xb9, 0x5b, 0x71, 0x35, 0x14, 0xe7, 0x23, 0xb4, 0xd4, 0x1b, 0x75, 0xa1, 0x8d, 0x2f,
- 0x26, 0xd1, 0x95, 0xdd, 0x58, 0x6f, 0x3a, 0x72, 0xa9, 0x87, 0x6d, 0xc3, 0xa1, 0x60, 0x69, 0x75,
- 0x58, 0xf0, 0x79, 0x76, 0x93, 0xf1, 0xf2, 0xdf, 0x1f, 0x11, 0x1d, 0x42, 0xfb, 0x5e, 0x29, 0xb4,
- 0x1d, 0xeb, 0xe8, 0xdd, 0xe3, 0x60, 0x9e, 0x8a, 0x8c, 0xd4, 0x83, 0xd5, 0x22, 0x47, 0xc2, 0x66,
- 0x6d, 0x4a, 0xd3, 0x15, 0xb2, 0xa1, 0x19, 0x72, 0xa9, 0xd3, 0xf5, 0x99, 0xfa, 0x44, 0x43, 0xe8,
- 0xc5, 0x79, 0xb5, 0x2a, 0x0a, 0x51, 0x4a, 0x9e, 0xea, 0xac, 0x7d, 0xf6, 0x32, 0x84, 0x76, 0xa0,
- 0x8d, 0xcb, 0x52, 0x94, 0x83, 0xa6, 0xe6, 0x6a, 0x80, 0xf6, 0x60, 0xc3, 0xcf, 0x2a, 0x99, 0xe4,
- 0x73, 0x3e, 0x68, 0x69, 0xe2, 0x09, 0x7f, 0xfe, 0x00, 0x9b, 0x11, 0xaf, 0xe4, 0x85, 0x48, 0xf9,
- 0x19, 0x7f, 0xa8, 0x94, 0xc7, 0xa4, 0xc8, 0x66, 0x92, 0x57, 0xd2, 0x6e, 0x9c, 0x60, 0xd8, 0x16,
- 0xe5, 0x62, 0x24, 0x0a, 0x9e, 0xcf, 0x45, 0x99, 0x8e, 0xea, 0x3b, 0xf9, 0x73, 0xb4, 0xc8, 0xe4,
- 0xed, 0xea, 0x5a, 0xf9, 0x19, 0x3f, 0x72, 0xe3, 0x9a, 0xfb, 0xb2, 0xbe, 0xaf, 0xf7, 0xc7, 0xe3,
- 0x85, 0x58, 0xdf, 0xda, 0xeb, 0x8e, 0x0e, 0x7e, 0xfd, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x36, 0xc3,
- 0x8c, 0xb0, 0xd4, 0x03, 0x00, 0x00,
+ // 598 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x5f, 0x4f, 0xdb, 0x3e,
+ 0x14, 0x6d, 0xd2, 0x96, 0x1f, 0xbd, 0xa5, 0x21, 0x3f, 0x03, 0x53, 0x87, 0x26, 0xad, 0xca, 0x0b,
+ 0x6c, 0x62, 0xad, 0xc4, 0x78, 0xdd, 0x43, 0x48, 0x3c, 0x66, 0x01, 0x4e, 0xe5, 0x24, 0x45, 0xf0,
+ 0xb0, 0x2a, 0x34, 0xa6, 0x44, 0xa2, 0x71, 0x94, 0xb8, 0x48, 0x7c, 0xd2, 0x7d, 0x9d, 0xc9, 0x4e,
+ 0xf9, 0x37, 0xf5, 0x25, 0xf1, 0xb9, 0xe7, 0xe4, 0x1e, 0xdf, 0xe3, 0x18, 0xf6, 0x1f, 0xc5, 0x83,
+ 0xbc, 0x4f, 0xa6, 0x45, 0x29, 0xa4, 0xa8, 0x46, 0x33, 0xb1, 0x58, 0x88, 0x7c, 0xa8, 0x11, 0xda,
+ 0xa8, 0x91, 0xb3, 0x0b, 0x26, 0xf1, 0x91, 0x05, 0x66, 0x96, 0xf6, 0x8d, 0x81, 0x71, 0xd8, 0x61,
+ 0x66, 0x96, 0x3a, 0x07, 0xd0, 0x24, 0x7e, 0x85, 0x06, 0xd0, 0xce, 0x24, 0x5f, 0x54, 0x7d, 0x63,
+ 0xd0, 0x3c, 0xec, 0x1e, 0xc3, 0x70, 0xd5, 0x82, 0xf8, 0xac, 0x26, 0x9c, 0x7b, 0x00, 0x37, 0x5d,
+ 0x64, 0x79, 0x28, 0x13, 0xc9, 0x9d, 0x1b, 0x68, 0x47, 0x4f, 0x05, 0xaf, 0x50, 0x17, 0xfe, 0x8b,
+ 0xe9, 0x39, 0x0d, 0xae, 0xa8, 0xdd, 0x40, 0x08, 0xac, 0x31, 0xc3, 0x63, 0x16, 0x4c, 0x48, 0x48,
+ 0x02, 0x8a, 0x7d, 0xdb, 0x50, 0x02, 0x4c, 0xdd, 0xd3, 0x0b, 0xec, 0xdb, 0x26, 0xda, 0x82, 0x4d,
+ 0x9f, 0x84, 0x35, 0x6a, 0xa2, 0x3d, 0xf8, 0xdf, 0x0f, 0xae, 0xe8, 0x45, 0xe0, 0xfa, 0x84, 0x9e,
+ 0x4d, 0xc9, 0xa5, 0x7b, 0x86, 0xed, 0x96, 0x33, 0x07, 0x08, 0x0a, 0x5e, 0x2a, 0xa3, 0x65, 0xe5,
+ 0x5c, 0xaf, 0x75, 0xb2, 0x00, 0x7c, 0x12, 0x7a, 0xc1, 0x04, 0x33, 0xed, 0x62, 0x01, 0xb8, 0x5e,
+ 0x44, 0x26, 0x6e, 0x44, 0xe8, 0x99, 0x6d, 0x2a, 0x71, 0x84, 0x43, 0x0d, 0x9a, 0x08, 0x60, 0x43,
+ 0x93, 0xd8, 0x6e, 0xa9, 0xf5, 0x4f, 0x97, 0x28, 0xff, 0xb6, 0x83, 0xa1, 0xe7, 0x89, 0x3c, 0xe7,
+ 0x33, 0xb9, 0xf2, 0x3a, 0x59, 0xeb, 0xb5, 0x0d, 0xdd, 0x98, 0x32, 0xec, 0x7a, 0xbf, 0xd4, 0xc6,
+ 0x6d, 0x03, 0xf5, 0xa0, 0xf3, 0x0a, 0x4d, 0xe7, 0x8f, 0x01, 0x3d, 0xb5, 0xe1, 0x44, 0x66, 0x22,
+ 0x67, 0xbc, 0x2a, 0xd0, 0x0f, 0x68, 0xcd, 0x44, 0xca, 0x75, 0xcc, 0xd6, 0xf1, 0x97, 0xe7, 0x30,
+ 0xdf, 0x89, 0xde, 0x22, 0xb9, 0x2c, 0x73, 0x4f, 0xa4, 0x9c, 0xe9, 0xcf, 0xd0, 0x01, 0x6c, 0x27,
+ 0x69, 0x9a, 0x29, 0x2e, 0x79, 0x98, 0x66, 0xf9, 0x9d, 0xe8, 0x9b, 0xfa, 0xc0, 0xac, 0xd7, 0x32,
+ 0xc9, 0xef, 0x84, 0xf3, 0x1b, 0x76, 0xd6, 0x74, 0x51, 0xb9, 0x06, 0x63, 0xcc, 0xdc, 0x88, 0x04,
+ 0x74, 0x1a, 0xc6, 0x9e, 0x87, 0xc3, 0xd0, 0x6e, 0xbc, 0x2f, 0xab, 0x10, 0x62, 0xa6, 0xa6, 0xf9,
+ 0x08, 0x7b, 0xaf, 0xe5, 0x98, 0x86, 0xf1, 0x78, 0x1c, 0xb0, 0x48, 0x1d, 0x97, 0x73, 0x04, 0x9d,
+ 0x49, 0xf2, 0xb0, 0xe4, 0x2a, 0x14, 0xe7, 0x33, 0xb4, 0xd4, 0x1b, 0x75, 0xa0, 0x8d, 0x2f, 0xc7,
+ 0xd1, 0xb5, 0xdd, 0x58, 0x1d, 0x67, 0xe4, 0x52, 0x0f, 0xdb, 0x86, 0x43, 0xc1, 0xd2, 0xea, 0xb0,
+ 0xe0, 0xb3, 0xec, 0x2e, 0xe3, 0xe5, 0xbf, 0x3f, 0x1b, 0x3a, 0x82, 0xf6, 0xa3, 0x52, 0xe8, 0x71,
+ 0xac, 0xe3, 0x0f, 0xcf, 0xc1, 0xbc, 0x98, 0x0c, 0xd5, 0x83, 0xd5, 0x22, 0x47, 0xc2, 0x56, 0x3d,
+ 0x94, 0xa6, 0x2b, 0x64, 0x43, 0x33, 0xe4, 0x52, 0xb7, 0xeb, 0x31, 0xb5, 0x44, 0x03, 0xe8, 0xc6,
+ 0x79, 0xb5, 0x2c, 0x0a, 0x51, 0x4a, 0x9e, 0xea, 0xae, 0x3d, 0xf6, 0xb6, 0x84, 0x76, 0xa1, 0x8d,
+ 0xcb, 0x52, 0x94, 0xfd, 0xa6, 0xe6, 0x6a, 0x80, 0xf6, 0x61, 0xd3, 0xcf, 0x2a, 0x99, 0xe4, 0x33,
+ 0xde, 0x6f, 0x69, 0xe2, 0x05, 0x7f, 0xfd, 0x04, 0x5b, 0x11, 0xaf, 0xe4, 0xa5, 0x48, 0xf9, 0x39,
+ 0x7f, 0xaa, 0xd4, 0x8c, 0x49, 0x91, 0x4d, 0x25, 0xaf, 0xa4, 0xdd, 0x38, 0xc5, 0xb0, 0x23, 0xca,
+ 0xf9, 0x50, 0x14, 0x3c, 0x9f, 0x89, 0x32, 0x1d, 0xd6, 0xf7, 0xee, 0x66, 0x38, 0xcf, 0xe4, 0xfd,
+ 0xf2, 0x56, 0xcd, 0x33, 0x7a, 0xe6, 0x46, 0x35, 0xf7, 0x6d, 0x75, 0x27, 0x1f, 0x4f, 0x46, 0x73,
+ 0xb1, 0xba, 0x99, 0xb7, 0x1b, 0xba, 0xf8, 0xfd, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7d, 0x32,
+ 0x70, 0x38, 0xb8, 0x03, 0x00, 0x00,
}
diff --git a/vendor/github.com/opencord/voltha-protos/v4/go/inter_container/inter_container.pb.go b/vendor/github.com/opencord/voltha-protos/v4/go/inter_container/inter_container.pb.go
index 16c4520..752eecb 100644
--- a/vendor/github.com/opencord/voltha-protos/v4/go/inter_container/inter_container.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v4/go/inter_container/inter_container.pb.go
@@ -71,8 +71,6 @@
const AdminState_ENABLED = AdminState_Types(common.AdminState_ENABLED)
const AdminState_DISABLED = AdminState_Types(common.AdminState_DISABLED)
const AdminState_DOWNLOADING_IMAGE = AdminState_Types(common.AdminState_DOWNLOADING_IMAGE)
-const AdminState_DELETED = AdminState_Types(common.AdminState_DELETED)
-const AdminState_DELETING = AdminState_Types(common.AdminState_DELETING)
// OperStatus_Types from public import voltha_protos/common.proto
type OperStatus_Types = common.OperStatus_Types
diff --git a/vendor/github.com/opencord/voltha-protos/v4/go/voltha/core.pb.go b/vendor/github.com/opencord/voltha-protos/v4/go/voltha/core.pb.go
new file mode 100644
index 0000000..4c92095
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-protos/v4/go/voltha/core.pb.go
@@ -0,0 +1,133 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: voltha_protos/core.proto
+
+package voltha
+
+import (
+ fmt "fmt"
+ proto "github.com/golang/protobuf/proto"
+ math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+// Transient State for devices
+type DeviceTransientState_Types int32
+
+const (
+ // The transient state of the device is not set
+ DeviceTransientState_NONE DeviceTransientState_Types = 0
+ // The state of the device in core is any state, i.e DELETING, DELETED, DELETE_FAILED, NONE.
+ // This state is only used for transitions.
+ DeviceTransientState_ANY DeviceTransientState_Types = 1
+ // The device is in FORCE_DELETING state
+ DeviceTransientState_FORCE_DELETING DeviceTransientState_Types = 2
+ // The device is getting deleted from adapter state
+ DeviceTransientState_DELETING_FROM_ADAPTER DeviceTransientState_Types = 3
+ // The device is deleted from adapter and is getting deleted in core.
+ DeviceTransientState_DELETING_POST_ADAPTER_RESPONSE DeviceTransientState_Types = 4
+ // State to represent that the device deletion is failed
+ DeviceTransientState_DELETE_FAILED DeviceTransientState_Types = 5
+)
+
+var DeviceTransientState_Types_name = map[int32]string{
+ 0: "NONE",
+ 1: "ANY",
+ 2: "FORCE_DELETING",
+ 3: "DELETING_FROM_ADAPTER",
+ 4: "DELETING_POST_ADAPTER_RESPONSE",
+ 5: "DELETE_FAILED",
+}
+
+var DeviceTransientState_Types_value = map[string]int32{
+ "NONE": 0,
+ "ANY": 1,
+ "FORCE_DELETING": 2,
+ "DELETING_FROM_ADAPTER": 3,
+ "DELETING_POST_ADAPTER_RESPONSE": 4,
+ "DELETE_FAILED": 5,
+}
+
+func (x DeviceTransientState_Types) String() string {
+ return proto.EnumName(DeviceTransientState_Types_name, int32(x))
+}
+
+func (DeviceTransientState_Types) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_39634f15fb8a505e, []int{0, 0}
+}
+
+type DeviceTransientState struct {
+ TransientState DeviceTransientState_Types `protobuf:"varint,1,opt,name=transient_state,json=transientState,proto3,enum=voltha.DeviceTransientState_Types" json:"transient_state,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *DeviceTransientState) Reset() { *m = DeviceTransientState{} }
+func (m *DeviceTransientState) String() string { return proto.CompactTextString(m) }
+func (*DeviceTransientState) ProtoMessage() {}
+func (*DeviceTransientState) Descriptor() ([]byte, []int) {
+ return fileDescriptor_39634f15fb8a505e, []int{0}
+}
+
+func (m *DeviceTransientState) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_DeviceTransientState.Unmarshal(m, b)
+}
+func (m *DeviceTransientState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_DeviceTransientState.Marshal(b, m, deterministic)
+}
+func (m *DeviceTransientState) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_DeviceTransientState.Merge(m, src)
+}
+func (m *DeviceTransientState) XXX_Size() int {
+ return xxx_messageInfo_DeviceTransientState.Size(m)
+}
+func (m *DeviceTransientState) XXX_DiscardUnknown() {
+ xxx_messageInfo_DeviceTransientState.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_DeviceTransientState proto.InternalMessageInfo
+
+func (m *DeviceTransientState) GetTransientState() DeviceTransientState_Types {
+ if m != nil {
+ return m.TransientState
+ }
+ return DeviceTransientState_NONE
+}
+
+func init() {
+ proto.RegisterEnum("voltha.DeviceTransientState_Types", DeviceTransientState_Types_name, DeviceTransientState_Types_value)
+ proto.RegisterType((*DeviceTransientState)(nil), "voltha.DeviceTransientState")
+}
+
+func init() { proto.RegisterFile("voltha_protos/core.proto", fileDescriptor_39634f15fb8a505e) }
+
+var fileDescriptor_39634f15fb8a505e = []byte{
+ // 264 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x4d, 0x4b, 0xc4, 0x30,
+ 0x10, 0x86, 0xad, 0xfb, 0xa1, 0x0c, 0x58, 0x63, 0x54, 0x58, 0x2f, 0x22, 0x3d, 0x79, 0x31, 0x05,
+ 0xf5, 0x0f, 0x54, 0x3b, 0x95, 0xc5, 0xb5, 0x2d, 0x6d, 0x2e, 0x7a, 0x09, 0xdd, 0x1a, 0xba, 0x05,
+ 0x6d, 0x4a, 0x1a, 0x0b, 0xde, 0xfc, 0xb5, 0xfe, 0x0e, 0xb1, 0x1f, 0x82, 0xb0, 0xb7, 0x99, 0xe7,
+ 0x99, 0xf7, 0x30, 0x2f, 0x2c, 0x5a, 0xf5, 0x66, 0x36, 0x99, 0xa8, 0xb5, 0x32, 0xaa, 0x71, 0x73,
+ 0xa5, 0x25, 0xeb, 0x66, 0x3a, 0xef, 0x8d, 0xf3, 0x6d, 0xc1, 0x89, 0x2f, 0xdb, 0x32, 0x97, 0x5c,
+ 0x67, 0x55, 0x53, 0xca, 0xca, 0xa4, 0x26, 0x33, 0x92, 0x3e, 0xc2, 0xa1, 0x19, 0x89, 0x68, 0x7e,
+ 0xd1, 0xc2, 0xba, 0xb0, 0x2e, 0xed, 0x6b, 0x87, 0xf5, 0x51, 0xb6, 0x2d, 0xc6, 0xf8, 0x67, 0x2d,
+ 0x9b, 0xc4, 0x36, 0xff, 0xa8, 0xf3, 0x65, 0xc1, 0xac, 0x33, 0x74, 0x1f, 0xa6, 0x61, 0x14, 0x22,
+ 0xd9, 0xa1, 0x7b, 0x30, 0xf1, 0xc2, 0x67, 0x62, 0x51, 0x0a, 0x76, 0x10, 0x25, 0xf7, 0x28, 0x7c,
+ 0x5c, 0x21, 0x5f, 0x86, 0x0f, 0x64, 0x97, 0x9e, 0xc1, 0xe9, 0xb8, 0x89, 0x20, 0x89, 0x9e, 0x84,
+ 0xe7, 0x7b, 0x31, 0xc7, 0x84, 0x4c, 0xa8, 0x03, 0xe7, 0x7f, 0x2a, 0x8e, 0x52, 0x3e, 0x2a, 0x91,
+ 0x60, 0x1a, 0x47, 0x61, 0x8a, 0x64, 0x4a, 0x8f, 0xe0, 0xa0, 0xbb, 0x41, 0x11, 0x78, 0xcb, 0x15,
+ 0xfa, 0x64, 0x76, 0x87, 0x70, 0xac, 0x74, 0xc1, 0x54, 0x2d, 0xab, 0x5c, 0xe9, 0xd7, 0xe1, 0x89,
+ 0x17, 0x56, 0x94, 0x66, 0xf3, 0xb1, 0x66, 0xb9, 0x7a, 0x77, 0x47, 0xe7, 0xf6, 0xee, 0x6a, 0x68,
+ 0xad, 0xbd, 0x75, 0x0b, 0x35, 0xb0, 0xf5, 0xbc, 0x83, 0x37, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff,
+ 0xe3, 0x06, 0xbc, 0xa1, 0x5a, 0x01, 0x00, 0x00,
+}
diff --git a/vendor/github.com/opencord/voltha-protos/v4/go/voltha/voltha.pb.go b/vendor/github.com/opencord/voltha-protos/v4/go/voltha/voltha.pb.go
index 4db124f..217adcf 100644
--- a/vendor/github.com/opencord/voltha-protos/v4/go/voltha/voltha.pb.go
+++ b/vendor/github.com/opencord/voltha-protos/v4/go/voltha/voltha.pb.go
@@ -91,8 +91,6 @@
const AdminState_ENABLED = AdminState_Types(common.AdminState_ENABLED)
const AdminState_DISABLED = AdminState_Types(common.AdminState_DISABLED)
const AdminState_DOWNLOADING_IMAGE = AdminState_Types(common.AdminState_DOWNLOADING_IMAGE)
-const AdminState_DELETED = AdminState_Types(common.AdminState_DELETED)
-const AdminState_DELETING = AdminState_Types(common.AdminState_DELETING)
// OperStatus_Types from public import voltha_protos/common.proto
type OperStatus_Types = common.OperStatus_Types
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c8b6a04..b190e83 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -117,7 +117,7 @@
github.com/opencord/voltha-lib-go/v4/pkg/mocks/kafka
github.com/opencord/voltha-lib-go/v4/pkg/probe
github.com/opencord/voltha-lib-go/v4/pkg/version
-# github.com/opencord/voltha-protos/v4 v4.0.2
+# github.com/opencord/voltha-protos/v4 v4.0.5
github.com/opencord/voltha-protos/v4/go/common
github.com/opencord/voltha-protos/v4/go/ext/config
github.com/opencord/voltha-protos/v4/go/inter_container