Skip to content

Commit

Permalink
Merge pull request edgexfoundry#3056 from weichou1229/issue-2988
Browse files Browse the repository at this point in the history
fix(meta): Check the associated object existence when delete Profile
  • Loading branch information
cloudxxx8 authored Jan 21, 2021
2 parents abd2591 + 0e0a70a commit 4ca1de5
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 7 deletions.
21 changes: 19 additions & 2 deletions internal/core/metadata/v2/application/deviceprofile.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (C) 2020 IOTech Ltd
// Copyright (C) 2020-2021 IOTech Ltd
//
// SPDX-License-Identifier: Apache-2.0

Expand Down Expand Up @@ -79,7 +79,24 @@ func DeleteDeviceProfileByName(name string, ctx context.Context, dic *di.Contain
return errors.NewCommonEdgeX(errors.KindContractInvalid, "name is empty", nil)
}
dbClient := v2MetadataContainer.DBClientFrom(dic.Get)
err := dbClient.DeleteDeviceProfileByName(name)

// Check the associated Device and ProvisionWatcher existence
devices, err := dbClient.DevicesByProfileName(0, 1, name)
if err != nil {
return errors.NewCommonEdgeXWrapper(err)
}
if len(devices) > 0 {
return errors.NewCommonEdgeX(errors.KindContractInvalid, "fail to delete the device profile when associated device exists", nil)
}
provisionWatchers, err := dbClient.ProvisionWatchersByProfileName(0, 1, name)
if err != nil {
return errors.NewCommonEdgeXWrapper(err)
}
if len(provisionWatchers) > 0 {
return errors.NewCommonEdgeX(errors.KindContractInvalid, "fail to delete the device profile when associated provisionWatcher exists", nil)
}

err = dbClient.DeleteDeviceProfileByName(name)
if err != nil {
return errors.NewCommonEdgeXWrapper(err)
}
Expand Down
10 changes: 9 additions & 1 deletion internal/core/metadata/v2/application/deviceservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,22 @@ func DeleteDeviceServiceByName(name string, ctx context.Context, dic *di.Contain
}
dbClient := v2MetadataContainer.DBClientFrom(dic.Get)

// Check the associated Device existence
// Check the associated Device and ProvisionWatcher existence
devices, err := dbClient.DevicesByServiceName(0, 1, name)
if err != nil {
return errors.NewCommonEdgeXWrapper(err)
}
if len(devices) > 0 {
return errors.NewCommonEdgeX(errors.KindContractInvalid, "fail to delete the device service when associated device exists", nil)
}
provisionWatchers, err := dbClient.ProvisionWatchersByServiceName(0, 1, name)
if err != nil {
return errors.NewCommonEdgeXWrapper(err)
}
if len(provisionWatchers) > 0 {
return errors.NewCommonEdgeX(errors.KindContractInvalid, "fail to delete the device service when associated provisionWatcher exists", nil)
}

err = dbClient.DeleteDeviceServiceByName(name)
if err != nil {
return errors.NewCommonEdgeXWrapper(err)
Expand Down
13 changes: 12 additions & 1 deletion internal/core/metadata/v2/controller/http/deviceprofile_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (C) 2020 IOTech Ltd
// Copyright (C) 2020-2021 IOTech Ltd
//
// SPDX-License-Identifier: Apache-2.0

Expand Down Expand Up @@ -805,11 +805,20 @@ func TestDeleteDeviceProfileByName(t *testing.T) {
deviceProfile := dtos.ToDeviceProfileModel(buildTestDeviceProfileRequest().Profile)
noName := ""
notFoundName := "notFoundName"
deviceExists := "deviceExists"
provisionWatcherExists := "provisionWatcherExists"

dic := mockDic()
dbClientMock := &dbMock.DBClient{}
dbClientMock.On("DevicesByProfileName", 0, 1, deviceProfile.Name).Return([]models.Device{}, nil)
dbClientMock.On("ProvisionWatchersByProfileName", 0, 1, deviceProfile.Name).Return([]models.ProvisionWatcher{}, nil)
dbClientMock.On("DeleteDeviceProfileByName", deviceProfile.Name).Return(nil)
dbClientMock.On("DevicesByProfileName", 0, 1, notFoundName).Return([]models.Device{}, nil)
dbClientMock.On("ProvisionWatchersByProfileName", 0, 1, notFoundName).Return([]models.ProvisionWatcher{}, nil)
dbClientMock.On("DeleteDeviceProfileByName", notFoundName).Return(errors.NewCommonEdgeX(errors.KindEntityDoesNotExist, "device profile doesn't exist in the database", nil))
dbClientMock.On("DevicesByProfileName", 0, 1, deviceExists).Return([]models.Device{models.Device{}}, nil)
dbClientMock.On("DevicesByProfileName", 0, 1, provisionWatcherExists).Return([]models.Device{}, nil)
dbClientMock.On("ProvisionWatchersByProfileName", 0, 1, provisionWatcherExists).Return([]models.ProvisionWatcher{models.ProvisionWatcher{}}, nil)
dic.Update(di.ServiceConstructorMap{
v2MetadataContainer.DBClientInterfaceName: func(get di.Get) interface{} {
return dbClientMock
Expand All @@ -828,6 +837,8 @@ func TestDeleteDeviceProfileByName(t *testing.T) {
{"Valid - delete device profile by name", deviceProfile.Name, false, http.StatusOK},
{"Invalid - name parameter is empty", noName, true, http.StatusBadRequest},
{"Invalid - device profile not found by name", notFoundName, true, http.StatusNotFound},
{"Invalid - associated device exists", deviceExists, true, http.StatusBadRequest},
{"Invalid - associated provisionWatcher Exists", provisionWatcherExists, true, http.StatusBadRequest},
}
for _, testCase := range tests {
t.Run(testCase.name, func(t *testing.T) {
Expand Down
12 changes: 9 additions & 3 deletions internal/core/metadata/v2/controller/http/deviceservice_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (C) 2020 IOTech Ltd
// Copyright (C) 2020-2021 IOTech Ltd
//
// SPDX-License-Identifier: Apache-2.0

Expand Down Expand Up @@ -467,14 +467,19 @@ func TestDeleteDeviceServiceByName(t *testing.T) {
noName := ""
notFoundName := "notFoundName"
deviceExists := "deviceExists"
provisionWatcherExists := "provisionWatcherExists"

dic := mockDic()
dbClientMock := &dbMock.DBClient{}
dbClientMock.On("DeleteDeviceServiceByName", deviceService.Name).Return(nil)
dbClientMock.On("DevicesByServiceName", 0, 1, deviceService.Name).Return([]models.Device{}, nil)
dbClientMock.On("DeleteDeviceServiceByName", notFoundName).Return(errors.NewCommonEdgeX(errors.KindEntityDoesNotExist, "device service doesn't exist in the database", nil))
dbClientMock.On("ProvisionWatchersByServiceName", 0, 1, deviceService.Name).Return([]models.ProvisionWatcher{}, nil)
dbClientMock.On("DeleteDeviceServiceByName", deviceService.Name).Return(nil)
dbClientMock.On("DevicesByServiceName", 0, 1, notFoundName).Return([]models.Device{}, nil)
dbClientMock.On("ProvisionWatchersByServiceName", 0, 1, notFoundName).Return([]models.ProvisionWatcher{}, nil)
dbClientMock.On("DeleteDeviceServiceByName", notFoundName).Return(errors.NewCommonEdgeX(errors.KindEntityDoesNotExist, "device service doesn't exist in the database", nil))
dbClientMock.On("DevicesByServiceName", 0, 1, deviceExists).Return([]models.Device{models.Device{}}, nil)
dbClientMock.On("DevicesByServiceName", 0, 1, provisionWatcherExists).Return([]models.Device{}, nil)
dbClientMock.On("ProvisionWatchersByServiceName", 0, 1, provisionWatcherExists).Return([]models.ProvisionWatcher{models.ProvisionWatcher{}}, nil)
dic.Update(di.ServiceConstructorMap{
v2MetadataContainer.DBClientInterfaceName: func(get di.Get) interface{} {
return dbClientMock
Expand All @@ -494,6 +499,7 @@ func TestDeleteDeviceServiceByName(t *testing.T) {
{"Invalid - name parameter is empty", noName, true, http.StatusBadRequest},
{"Invalid - device service not found by name", notFoundName, true, http.StatusNotFound},
{"Invalid - associated device exists", deviceExists, true, http.StatusBadRequest},
{"Invalid - associated provisionWatcher Exists", provisionWatcherExists, true, http.StatusBadRequest},
}
for _, testCase := range tests {
t.Run(testCase.name, func(t *testing.T) {
Expand Down

0 comments on commit 4ca1de5

Please sign in to comment.