From 77b92681e11c0d62a68a7663b5c7f2bdfb39f1b2 Mon Sep 17 00:00:00 2001 From: GuillaumeM <86654731+GuillaumeM-2ISA@users.noreply.github.com> Date: Mon, 6 Mar 2023 10:24:27 +0100 Subject: [PATCH] Fix Bug: Failed to delete a device that is not present in IoT Hub #1836 (#1839) * fix delete device * update unit test device service --- .../Services/DeviceService.cs | 6 ++-- .../Services/DeviceServiceBase.cs | 16 +++++++-- .../Services/LoRaWanDeviceService.cs | 2 +- .../Server/Services/DeviceServiceTests.cs | 33 +++++++++++++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/AzureIoTHub.Portal.Server/Services/DeviceService.cs b/src/AzureIoTHub.Portal.Server/Services/DeviceService.cs index c0efaf07a..c2bf04010 100644 --- a/src/AzureIoTHub.Portal.Server/Services/DeviceService.cs +++ b/src/AzureIoTHub.Portal.Server/Services/DeviceService.cs @@ -17,6 +17,7 @@ namespace AzureIoTHub.Portal.Server.Services using Domain.Exceptions; using Domain.Repositories; using Infrastructure; + using Microsoft.Extensions.Logging; using Models.v10; public class DeviceService : DeviceServiceBase @@ -37,8 +38,9 @@ public DeviceService(IMapper mapper, IDeviceTagService deviceTagService, IDeviceModelImageManager deviceModelImageManager, IDeviceTwinMapper deviceTwinMapper, - PortalDbContext portalDbContext) - : base(portalDbContext, mapper, externalDevicesService, deviceTagService, deviceModelImageManager, deviceTwinMapper) + PortalDbContext portalDbContext, + ILogger logger) + : base(portalDbContext, mapper, externalDevicesService, deviceTagService, deviceModelImageManager, deviceTwinMapper, logger) { this.mapper = mapper; this.unitOfWork = unitOfWork; diff --git a/src/AzureIoTHub.Portal.Server/Services/DeviceServiceBase.cs b/src/AzureIoTHub.Portal.Server/Services/DeviceServiceBase.cs index 50bc9c824..e11bfdff7 100644 --- a/src/AzureIoTHub.Portal.Server/Services/DeviceServiceBase.cs +++ b/src/AzureIoTHub.Portal.Server/Services/DeviceServiceBase.cs @@ -18,7 +18,9 @@ namespace AzureIoTHub.Portal.Server.Services using Infrastructure; using Infrastructure.Repositories; using Microsoft.Azure.Devices; + using Microsoft.Azure.Devices.Common.Exceptions; using Microsoft.EntityFrameworkCore; + using Microsoft.Extensions.Logging; using Models.v10; using Shared.Models.v1._0; using Shared.Models.v10.Filters; @@ -33,13 +35,15 @@ public abstract class DeviceServiceBase : IDeviceService private readonly IDeviceTagService deviceTagService; private readonly IDeviceModelImageManager deviceModelImageManager; private readonly IDeviceTwinMapper deviceTwinMapper; + private readonly ILogger> logger; protected DeviceServiceBase(PortalDbContext portalDbContext, IMapper mapper, IExternalDeviceService externalDevicesService, IDeviceTagService deviceTagService, IDeviceModelImageManager deviceModelImageManager, - IDeviceTwinMapper deviceTwinMapper) + IDeviceTwinMapper deviceTwinMapper, + ILogger> logger) { this.portalDbContext = portalDbContext; this.mapper = mapper; @@ -47,6 +51,7 @@ protected DeviceServiceBase(PortalDbContext portalDbContext, this.deviceTagService = deviceTagService; this.deviceModelImageManager = deviceModelImageManager; this.deviceTwinMapper = deviceTwinMapper; + this.logger = logger; } public async Task> GetDevices(string searchText = null, bool? searchStatus = null, bool? searchState = null, int pageSize = 10, @@ -181,7 +186,14 @@ public async Task UpdateDevice(TDto device) public virtual async Task DeleteDevice(string deviceId) { - await this.externalDevicesService.DeleteDevice(deviceId); + try + { + await this.externalDevicesService.DeleteDevice(deviceId); + } + catch (DeviceNotFoundException e) + { + this.logger.LogWarning($"Unable to delete the device with ID {deviceId} because it doesn't exist on IoT Hub {e.Message}"); + } await DeleteDeviceInDatabase(deviceId); } diff --git a/src/AzureIoTHub.Portal.Server/Services/LoRaWanDeviceService.cs b/src/AzureIoTHub.Portal.Server/Services/LoRaWanDeviceService.cs index 66b8560c7..9835535f7 100644 --- a/src/AzureIoTHub.Portal.Server/Services/LoRaWanDeviceService.cs +++ b/src/AzureIoTHub.Portal.Server/Services/LoRaWanDeviceService.cs @@ -49,7 +49,7 @@ public LoRaWanDeviceService( PortalDbContext portalDbContext, IDeviceModelImageManager deviceModelImageManager, IDeviceTwinMapper deviceTwinMapper) - : base(portalDbContext, mapper, externalDevicesService, deviceTagService, deviceModelImageManager, deviceTwinMapper) + : base(portalDbContext, mapper, externalDevicesService, deviceTagService, deviceModelImageManager, deviceTwinMapper, logger) { this.logger = logger; this.mapper = mapper; diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/DeviceServiceTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/DeviceServiceTests.cs index 3b9c4bd4e..c7f3446bc 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/DeviceServiceTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/DeviceServiceTests.cs @@ -19,6 +19,7 @@ namespace AzureIoTHub.Portal.Tests.Unit.Server.Services using EntityFramework.Exceptions.Common; using FluentAssertions; using Microsoft.Azure.Devices; + using Microsoft.Azure.Devices.Common.Exceptions; using Microsoft.Azure.Devices.Shared; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; @@ -652,5 +653,37 @@ public async Task GetAvailableLabels_LabelsExists_LabelsReturned() _ = result.Count().Should().Be(expectedLabels.Count); MockRepository.VerifyAll(); } + + [Test] + public async Task DeleteDevice_DeviceNotFoundOnAzure_DeviceDeletedInDatabase() + { + // Arrange + var deviceDto = new DeviceDetails + { + DeviceID = Fixture.Create() + }; + + _ = this.mockExternalDevicesService.Setup(service => service.DeleteDevice(deviceDto.DeviceID)) + .ThrowsAsync(new DeviceNotFoundException(deviceDto.DeviceID)); + + _ = this.mockDeviceRepository.Setup(repository => repository.GetByIdAsync(deviceDto.DeviceID, d => d.Tags, d => d.Labels)) + .ReturnsAsync(new Device + { + Tags = new List(), + Labels = new List