From f0ba7a1eebec522326b0ab55447f1e2cb5e72423 Mon Sep 17 00:00:00 2001 From: salim ben ahben <40862545+Sben65@users.noreply.github.com> Date: Wed, 2 Nov 2022 15:04:53 +0100 Subject: [PATCH] BugFix/#1421_-_Unable to delete device in database when the device did not exist in IoTHub (#1499) * resolve #1421 * fix test * update syncEdgeDevice test * delete useless using * feature delete useless device in db for device, lorawan device and concentrator --- .../Jobs/SyncConcentratorsJob.cs | 10 +- .../Jobs/SyncDevicesJob.cs | 15 ++- .../Jobs/SyncEdgeDeviceJob.cs | 10 +- .../Server/Jobs/SyncConcentratorsJobTests.cs | 36 +++++++ .../Server/Jobs/SyncDevicesJobTests.cs | 99 +++++++++++++++++++ .../Server/Jobs/SyncEdgeDeviceJobTest.cs | 27 +++++ 6 files changed, 194 insertions(+), 3 deletions(-) diff --git a/src/AzureIoTHub.Portal.Server/Jobs/SyncConcentratorsJob.cs b/src/AzureIoTHub.Portal.Server/Jobs/SyncConcentratorsJob.cs index a8d116c93..0aeafa403 100644 --- a/src/AzureIoTHub.Portal.Server/Jobs/SyncConcentratorsJob.cs +++ b/src/AzureIoTHub.Portal.Server/Jobs/SyncConcentratorsJob.cs @@ -14,6 +14,7 @@ namespace AzureIoTHub.Portal.Server.Jobs using Microsoft.Azure.Devices.Shared; using Microsoft.Extensions.Logging; using Quartz; + using System.Linq; [DisallowConcurrentExecution] public class SyncConcentratorsJob : IJob @@ -56,11 +57,18 @@ public async Task Execute(IJobExecutionContext context) private async Task SyncConcentrators() { - foreach (var twin in await GetTwinConcentrators()) + var concentratorTwins = await GetTwinConcentrators(); + + foreach (var twin in concentratorTwins) { await CreateOrUpdateConcentrator(twin); } + foreach (var item in (await this.concentratorRepository.GetAllAsync()).Where(device => !concentratorTwins.Exists(x => x.DeviceId == device.Id))) + { + this.concentratorRepository.Delete(item.Id); + } + await this.unitOfWork.SaveAsync(); } diff --git a/src/AzureIoTHub.Portal.Server/Jobs/SyncDevicesJob.cs b/src/AzureIoTHub.Portal.Server/Jobs/SyncDevicesJob.cs index 2bcac14d4..e30342038 100644 --- a/src/AzureIoTHub.Portal.Server/Jobs/SyncDevicesJob.cs +++ b/src/AzureIoTHub.Portal.Server/Jobs/SyncDevicesJob.cs @@ -14,6 +14,7 @@ namespace AzureIoTHub.Portal.Server.Jobs using Microsoft.Azure.Devices.Shared; using Microsoft.Extensions.Logging; using Quartz; + using System.Linq; [DisallowConcurrentExecution] public class SyncDevicesJob : IJob @@ -66,7 +67,9 @@ public async Task Execute(IJobExecutionContext context) private async Task SyncDevices() { - foreach (var twin in await GetTwinDevices()) + var deviceTwins = await GetTwinDevices(); + + foreach (var twin in deviceTwins) { var deviceModel = await this.deviceModelRepository.GetByIdAsync(twin.Tags[ModelId]?.ToString() ?? string.Empty); @@ -86,6 +89,16 @@ private async Task SyncDevices() } } + foreach (var item in (await this.deviceRepository.GetAllAsync()).Where(device => !deviceTwins.Exists(x => x.DeviceId == device.Id))) + { + this.deviceRepository.Delete(item.Id); + } + + foreach (var item in (await this.lorawanDeviceRepository.GetAllAsync()).Where(lorawanDevice => !deviceTwins.Exists(x => x.DeviceId == lorawanDevice.Id))) + { + this.lorawanDeviceRepository.Delete(item.Id); + } + await this.unitOfWork.SaveAsync(); } diff --git a/src/AzureIoTHub.Portal.Server/Jobs/SyncEdgeDeviceJob.cs b/src/AzureIoTHub.Portal.Server/Jobs/SyncEdgeDeviceJob.cs index 8765e8d9a..c746c08a0 100644 --- a/src/AzureIoTHub.Portal.Server/Jobs/SyncEdgeDeviceJob.cs +++ b/src/AzureIoTHub.Portal.Server/Jobs/SyncEdgeDeviceJob.cs @@ -5,6 +5,7 @@ namespace AzureIoTHub.Portal.Server.Jobs { using System; using System.Collections.Generic; + using System.Linq; using System.Threading.Tasks; using AutoMapper; using AzureIoTHub.Portal.Domain; @@ -67,7 +68,9 @@ public async Task Execute(IJobExecutionContext context) private async Task SyncEdgeDevices() { - foreach (var twin in await GetTwinDevices()) + var deviceTwins = await GetTwinDevices(); + + foreach (var twin in deviceTwins) { var deviceModel = await this.edgeDeviceModelRepository.GetByIdAsync(twin.Tags[ModelId]?.ToString() ?? string.Empty); @@ -80,6 +83,11 @@ private async Task SyncEdgeDevices() await CreateOrUpdateDevice(twin); } + foreach (var item in (await this.edgeDeviceRepository.GetAllAsync()).Where(edgeDevice => !deviceTwins.Exists(twin => twin.DeviceId == edgeDevice.Id))) + { + this.edgeDeviceRepository.Delete(item.Id); + } + await this.unitOfWork.SaveAsync(); } diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncConcentratorsJobTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncConcentratorsJobTests.cs index a19f81b66..8f984cbe9 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncConcentratorsJobTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncConcentratorsJobTests.cs @@ -3,7 +3,10 @@ namespace AzureIoTHub.Portal.Tests.Unit.Server.Jobs { + using System; using System.Collections.Generic; + using System.Linq.Expressions; + using System.Threading; using System.Threading.Tasks; using AutoFixture; using AzureIoTHub.Portal.Domain; @@ -87,6 +90,21 @@ public async Task ExecuteNewConcentratorShouldCreateEntity() _ = this.mockConcentratorRepository.Setup(repository => repository.InsertAsync(It.IsAny())) .Returns(Task.CompletedTask); + _ = this.mockConcentratorRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new Concentrator + { + Id = expectedTwinConcentrator.DeviceId + }, + new Concentrator + { + Id = Guid.NewGuid().ToString() + } + }); + + this.mockConcentratorRepository.Setup(x => x.Delete(It.IsAny())).Verifiable(); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask); @@ -146,6 +164,15 @@ public async Task ExecuteExistingConcentratorWithGreaterVersionShouldUpdateEntit this.mockConcentratorRepository.Setup(repository => repository.Update(It.IsAny())) .Verifiable(); + _ = this.mockConcentratorRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new Concentrator + { + Id = expectedTwinConcentrator.DeviceId + } + }); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask); @@ -202,6 +229,15 @@ public async Task ExecuteExistingConcentratorWithLowerOrEqualVersionShouldReturn _ = this.mockConcentratorRepository.Setup(repository => repository.GetByIdAsync(expectedTwinConcentrator.DeviceId)) .ReturnsAsync(existingConcentrator); + _ = this.mockConcentratorRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new Concentrator + { + Id = expectedTwinConcentrator.DeviceId + } + }); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask); diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncDevicesJobTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncDevicesJobTests.cs index 8d47d9203..a0db997a9 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncDevicesJobTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncDevicesJobTests.cs @@ -3,7 +3,10 @@ namespace AzureIoTHub.Portal.Tests.Unit.Server.Jobs { + using System; using System.Collections.Generic; + using System.Linq.Expressions; + using System.Threading; using System.Threading.Tasks; using AutoFixture; using AzureIoTHub.Portal.Domain; @@ -103,6 +106,36 @@ public async Task Execute_NewDevice_DeviceCreated() _ = this.mockDeviceRepository.Setup(repository => repository.InsertAsync(It.IsAny())) .Returns(Task.CompletedTask); + _ = this.mockDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new Device + { + Id = expectedTwinDevice.DeviceId + }, + new Device + { + Id = Guid.NewGuid().ToString() + } + }); + + this.mockDeviceRepository.Setup(x => x.Delete(It.IsAny())).Verifiable(); + + _ = this.mockLorawanDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new LorawanDevice + { + Id = expectedTwinDevice.DeviceId + }, + new LorawanDevice + { + Id = Guid.NewGuid().ToString() + } + }); + + this.mockLorawanDeviceRepository.Setup(x => x.Delete(It.IsAny())).Verifiable(); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask); @@ -181,6 +214,24 @@ public async Task Execute_ExistingDeviceWithGreeterVersion_DeviceUpdated() this.mockDeviceRepository.Setup(repository => repository.Update(It.IsAny())) .Verifiable(); + _ = this.mockDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new Device + { + Id = expectedTwinDevice.DeviceId + } + }); + + _ = this.mockLorawanDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new LorawanDevice + { + Id = expectedTwinDevice.DeviceId + } + }); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask); @@ -240,6 +291,36 @@ public async Task Execute_NewLorawanDevice_LorawanDeviceCreated() _ = this.mockLorawanDeviceRepository.Setup(repository => repository.InsertAsync(It.IsAny())) .Returns(Task.CompletedTask); + _ = this.mockDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new Device + { + Id = expectedTwinDevice.DeviceId + }, + new Device + { + Id = Guid.NewGuid().ToString() + } + }); + + this.mockDeviceRepository.Setup(x => x.Delete(It.IsAny())).Verifiable(); + + _ = this.mockLorawanDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new LorawanDevice + { + Id = expectedTwinDevice.DeviceId + }, + new LorawanDevice + { + Id = Guid.NewGuid().ToString() + } + }); + + this.mockLorawanDeviceRepository.Setup(x => x.Delete(It.IsAny())).Verifiable(); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask); @@ -318,6 +399,24 @@ public async Task Execute_ExistingLorawanDeviceWithGreeterVersion_LorawanDeviceU this.mockLorawanDeviceRepository.Setup(repository => repository.Update(It.IsAny())) .Verifiable(); + _ = this.mockDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new Device + { + Id = expectedTwinDevice.DeviceId + } + }); + + _ = this.mockLorawanDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new LorawanDevice + { + Id = expectedTwinDevice.DeviceId + } + }); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask); diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncEdgeDeviceJobTest.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncEdgeDeviceJobTest.cs index 065131c91..800e25307 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncEdgeDeviceJobTest.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Jobs/SyncEdgeDeviceJobTest.cs @@ -3,7 +3,10 @@ namespace AzureIoTHub.Portal.Tests.Unit.Server.Jobs { + using System; using System.Collections.Generic; + using System.Linq.Expressions; + using System.Threading; using System.Threading.Tasks; using AutoFixture; using AzureIoTHub.Portal.Domain; @@ -110,6 +113,21 @@ public async Task ExecuteNewEdgeDeviceDeviceCreated() _ = this.mockEdgeDeviceRepository.Setup(x => x.InsertAsync(It.IsAny())) .Returns(Task.CompletedTask); + _ = this.mockEdgeDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new EdgeDevice + { + Id = expectedTwinDevice.DeviceId + }, + new EdgeDevice + { + Id = Guid.NewGuid().ToString() + } + }); + + this.mockEdgeDeviceRepository.Setup(x => x.Delete(It.IsAny())).Verifiable(); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask); @@ -192,6 +210,15 @@ public async Task ExecuteExistingEdgeDeviceWithGreeterVersionDeviceUpdated() this.mockEdgeDeviceRepository.Setup(repository => repository.Update(It.IsAny())) .Verifiable(); + _ = this.mockEdgeDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny>>(), It.IsAny())) + .ReturnsAsync(new List + { + new EdgeDevice + { + Id = expectedTwinDevice.DeviceId + } + }); + _ = this.mockUnitOfWork.Setup(work => work.SaveAsync()) .Returns(Task.CompletedTask);