Skip to content

Commit

Permalink
Fix #1804 - encapsulate sync job by a try-catch per device (#1809)
Browse files Browse the repository at this point in the history
  • Loading branch information
kbeaugrand authored Feb 27, 2023
1 parent 3a974aa commit 929d0ea
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 6 deletions.
27 changes: 21 additions & 6 deletions src/AzureIoTHub.Portal.Infrastructure/Jobs/SyncEdgeDeviceJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,30 @@ private async Task SyncEdgeDevices()

foreach (var twin in deviceTwins)
{
var deviceModel = await this.edgeDeviceModelRepository.GetByIdAsync(twin.Tags[ModelId]?.ToString() ?? string.Empty);
try
{
if (!twin.Tags.Contains(ModelId))
{
this.logger.LogWarning($"The device with wont be synchronized since it doesn't have a model identifier.");
continue;
}

var modelId = twin.Tags[ModelId].ToString();

var deviceModel = await this.edgeDeviceModelRepository.GetByIdAsync(modelId);

if (deviceModel == null)
if (deviceModel == null)
{
this.logger.LogWarning($"The device with wont be synchronized, its model id {modelId} doesn't exist");
continue;
}

await CreateOrUpdateDevice(twin);
}
catch (Exception ex)
{
this.logger.LogWarning($"The device with wont be synched, its model id {twin.Tags[ModelId]?.ToString()} doesn't exist");
continue;
this.logger.LogError(ex, $"Failed to synchronize device {twin.DeviceId}");
}

await CreateOrUpdateDevice(twin);
}

foreach (var item in (await this.edgeDeviceRepository.GetAllAsync()).Where(edgeDevice => !deviceTwins.Exists(twin => twin.DeviceId == edgeDevice.Id)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,139 @@ public async Task ExecuteExistingEdgeDeviceWithGreeterVersionDeviceUpdated()
// Assert
MockRepository.VerifyAll();
}

[Test]
public async Task WhenErrorOccursJobShouldContinueToNextDevice()
{
// Arrange
var mockJobExecutionContext = MockRepository.Create<IJobExecutionContext>();

var expectedDeviceModel = Fixture.Create<EdgeDeviceModel>();
var fakeTwin = Fixture.Create<Twin>();

var expectedTwinDevice = new Twin
{
DeviceId = Fixture.Create<string>(),
Tags = new TwinCollection
{
["modelId"] = expectedDeviceModel.Id,
["deviceName"] = Fixture.Create<string>()
},
Capabilities = new DeviceCapabilities{ IotEdge = true },
Version = 2
};

_ = this.mockExternalDeviceService
.Setup(x => x.GetAllEdgeDevice(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<bool?>(),
It.IsAny<string>(),
It.Is<int>(x => x == 100)))
.ReturnsAsync(new PaginationResult<Twin>
{
Items = new List<Twin>
{
expectedTwinDevice,
fakeTwin
},
TotalItems = 2
});

_ = this.mockEdgeDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny<Expression<Func<EdgeDevice, bool>>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new List<EdgeDevice>
{
new EdgeDevice
{
Id = expectedTwinDevice.DeviceId
}
});

_ = this.mockUnitOfWork.Setup(work => work.SaveAsync())
.Returns(Task.CompletedTask);

_ = this.mockEdgeDeviceModelRepository.Setup(c => c.GetByIdAsync(It.IsAny<string>()))
.Throws<NotImplementedException>();

// Act
await this.syncEdgeDeviceJob.Execute(mockJobExecutionContext.Object);

// Assert
MockRepository.VerifyAll();
}

[Test]
public async Task WhenModelIsNotFoundShouldContinueToNextDevice()
{
// Arrange
var mockJobExecutionContext = MockRepository.Create<IJobExecutionContext>();

var expectedDeviceModel = Fixture.Create<EdgeDeviceModel>();
var fakeTwin = Fixture.Create<Twin>();

var expectedTwinDevice = new Twin
{
DeviceId = Fixture.Create<string>(),
Tags = new TwinCollection
{
["modelId"] = expectedDeviceModel.Id,
["deviceName"] = Fixture.Create<string>()
},
Capabilities = new DeviceCapabilities{ IotEdge = true },
Version = 2
};

_ = this.mockExternalDeviceService
.Setup(x => x.GetAllEdgeDevice(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<bool?>(),
It.IsAny<string>(),
It.Is<int>(x => x == 100)))
.ReturnsAsync(new PaginationResult<Twin>
{
Items = new List<Twin>
{
expectedTwinDevice,
expectedTwinDevice,
},
TotalItems = 2
});

_ = this.mockEdgeDeviceRepository.Setup(x => x.GetAllAsync(It.IsAny<Expression<Func<EdgeDevice, bool>>>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new List<EdgeDevice>
{
new EdgeDevice
{
Id = expectedTwinDevice.DeviceId
}
});

_ = this.mockUnitOfWork.Setup(work => work.SaveAsync())
.Returns(Task.CompletedTask);

_ = this.mockEdgeDeviceModelRepository.Setup(c => c.GetByIdAsync(It.IsAny<string>()))
.ReturnsAsync((EdgeDeviceModel)null);

// Act
await this.syncEdgeDeviceJob.Execute(mockJobExecutionContext.Object);

// Assert
MockRepository.VerifyAll();
this.mockEdgeDeviceModelRepository.Verify(c => c.GetByIdAsync(It.IsAny<string>()), Times.Exactly(2));
}

[Test]
public async Task WhenNothinWorksJobShouldNotThrowAnException()
{
// Arrange
var mockJobExecutionContext = MockRepository.Create<IJobExecutionContext>();

// Act
await this.syncEdgeDeviceJob.Execute(mockJobExecutionContext.Object);

// Assert
MockRepository.VerifyAll();
}
}
}

0 comments on commit 929d0ea

Please sign in to comment.