From f85f266ab1450e40de308ac916294fd99f1e3ea7 Mon Sep 17 00:00:00 2001 From: weichou Date: Wed, 20 Jan 2021 20:12:43 +0800 Subject: [PATCH] fix(meta): Delete DS API should check the associated Device existence Delete Device Service API should check the associated Device existence. If there is any associated Device exists, the Device Service deletion should return error. fix 2989 Signed-off-by: weichou --- .../core/metadata/v2/application/deviceservice.go | 11 ++++++++++- .../metadata/v2/controller/http/deviceservice_test.go | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/internal/core/metadata/v2/application/deviceservice.go b/internal/core/metadata/v2/application/deviceservice.go index b06ddc321f..53f645a5de 100644 --- a/internal/core/metadata/v2/application/deviceservice.go +++ b/internal/core/metadata/v2/application/deviceservice.go @@ -103,7 +103,16 @@ func DeleteDeviceServiceByName(name string, ctx context.Context, dic *di.Contain return errors.NewCommonEdgeX(errors.KindContractInvalid, "name is empty", nil) } dbClient := v2MetadataContainer.DBClientFrom(dic.Get) - err := dbClient.DeleteDeviceServiceByName(name) + + // Check the associated Device 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) + } + err = dbClient.DeleteDeviceServiceByName(name) if err != nil { return errors.NewCommonEdgeXWrapper(err) } diff --git a/internal/core/metadata/v2/controller/http/deviceservice_test.go b/internal/core/metadata/v2/controller/http/deviceservice_test.go index a6b02bd944..831f1933e1 100644 --- a/internal/core/metadata/v2/controller/http/deviceservice_test.go +++ b/internal/core/metadata/v2/controller/http/deviceservice_test.go @@ -466,11 +466,15 @@ func TestDeleteDeviceServiceByName(t *testing.T) { deviceService := dtos.ToDeviceServiceModel(buildTestDeviceServiceRequest().Service) noName := "" notFoundName := "notFoundName" + deviceExists := "deviceExists" 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("DevicesByServiceName", 0, 1, notFoundName).Return([]models.Device{}, nil) + dbClientMock.On("DevicesByServiceName", 0, 1, deviceExists).Return([]models.Device{models.Device{}}, nil) dic.Update(di.ServiceConstructorMap{ v2MetadataContainer.DBClientInterfaceName: func(get di.Get) interface{} { return dbClientMock @@ -489,6 +493,7 @@ func TestDeleteDeviceServiceByName(t *testing.T) { {"Valid - delete device service by name", deviceService.Name, false, http.StatusOK}, {"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}, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) {