-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sync GreenGrassDeployment #2120
Merged
Merged
Changes from 2 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
5ae5209
Sync GreenGrassDeployment (Started)
ssgueye2 d7a1ed1
Sync Deployments (waiting for one test)
ssgueye2 d3e9c80
Sync Deployment (DONE)
ssgueye2 a965d8b
remove getComponentIfExist
ssgueye2 4607e65
Sync GreenGrassDeployment (Started)
ssgueye2 89f7fe9
Sync Deployments (waiting for one test)
ssgueye2 e3148d5
Sync Deployment (DONE)
ssgueye2 9c67f6e
remove getComponentIfExist
ssgueye2 e732724
update Sync Deployment With Dynamic Thing group
ssgueye2 b3c6469
Merge branch '#2073-Sync-AWS-GreenGrass-Deployment' of https://github…
ssgueye2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
140 changes: 140 additions & 0 deletions
140
src/AzureIoTHub.Portal.Infrastructure/Jobs/AWS/SyncGreenGrassDeploymentsJob.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Copyright (c) CGI France. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
namespace AzureIoTHub.Portal.Infrastructure.Jobs.AWS | ||
{ | ||
using Amazon.IoT; | ||
using AutoMapper; | ||
using AzureIoTHub.Portal.Application.Managers; | ||
using AzureIoTHub.Portal.Domain.Repositories; | ||
using AzureIoTHub.Portal.Domain; | ||
using Microsoft.Extensions.Logging; | ||
using Quartz; | ||
using Amazon.GreengrassV2; | ||
using AzureIoTHub.Portal.Models.v10; | ||
using Amazon.GreengrassV2.Model; | ||
using AzureIoTHub.Portal.Domain.Entities; | ||
|
||
[DisallowConcurrentExecution] | ||
public class SyncGreenGrassDeploymentsJob : IJob | ||
{ | ||
private readonly ILogger<SyncThingTypesJob> logger; | ||
private readonly IMapper mapper; | ||
private readonly IUnitOfWork unitOfWork; | ||
private readonly IEdgeDeviceModelRepository edgeDeviceModelRepository; | ||
private readonly IAmazonIoT amazonIoTClient; | ||
private readonly IAmazonGreengrassV2 amazonGreenGrass; | ||
private readonly IDeviceModelImageManager deviceModelImageManager; | ||
|
||
public SyncGreenGrassDeploymentsJob( | ||
ILogger<SyncThingTypesJob> logger, | ||
IMapper mapper, | ||
IUnitOfWork unitOfWork, | ||
IEdgeDeviceModelRepository edgeDeviceModelRepository, | ||
IAmazonIoT amazonIoTClient, | ||
IAmazonGreengrassV2 amazonGreenGrass, | ||
IDeviceModelImageManager awsImageManager) | ||
{ | ||
this.deviceModelImageManager = awsImageManager; | ||
this.mapper = mapper; | ||
this.unitOfWork = unitOfWork; | ||
this.edgeDeviceModelRepository = edgeDeviceModelRepository; | ||
this.amazonIoTClient = amazonIoTClient; | ||
this.amazonGreenGrass = amazonGreenGrass; | ||
this.logger = logger; | ||
} | ||
|
||
|
||
public async Task Execute(IJobExecutionContext context) | ||
{ | ||
try | ||
{ | ||
this.logger.LogInformation("Start of sync Greengrass Deployents job"); | ||
|
||
await SyncGreenGrassDeployments(); | ||
|
||
this.logger.LogInformation("End of sync Greengrass Deployents job"); | ||
} | ||
catch (Exception e) | ||
{ | ||
this.logger.LogError(e, "Sync Greengrass Deployents job has failed"); | ||
} | ||
} | ||
|
||
private async Task SyncGreenGrassDeployments() | ||
{ | ||
var awsGreenGrassDeployments = await GetAllGreenGrassDeployments(); | ||
|
||
foreach (var deployment in awsGreenGrassDeployments) | ||
{ | ||
await CreateNonExisitingGreenGrassDeployment(deployment); | ||
} | ||
|
||
//Delete in DB AWS deleted deployments | ||
await DeleteGreenGrassDeployments(awsGreenGrassDeployments); | ||
} | ||
|
||
private async Task<List<IoTEdgeModel>> GetAllGreenGrassDeployments() | ||
{ | ||
var deployments = new List<IoTEdgeModel>(); | ||
|
||
var nextToken = string.Empty; | ||
|
||
var getAllAwsGreenGrassDeployments = await this.amazonGreenGrass.ListDeploymentsAsync( | ||
new ListDeploymentsRequest | ||
{ | ||
NextToken = nextToken, | ||
HistoryFilter = DeploymentHistoryFilter.LATEST_ONLY | ||
}); | ||
|
||
foreach (var deployment in getAllAwsGreenGrassDeployments.Deployments) | ||
{ | ||
var iotEdgeModel = new IoTEdgeModel | ||
{ | ||
ModelId = deployment.DeploymentId, //Instead of giving a random Id here, we can give the deploymentID | ||
Name = deployment.DeploymentName, | ||
ExternalIdentifier = deployment.DeploymentId | ||
}; | ||
deployments.Add(iotEdgeModel); | ||
} | ||
|
||
return deployments; | ||
} | ||
|
||
private async Task CreateNonExisitingGreenGrassDeployment(IoTEdgeModel iotEdgeModel) | ||
{ | ||
|
||
var iotEdgeModels = (await this.edgeDeviceModelRepository.GetAllAsync()) | ||
.Where(edge => edge.ExternalIdentifier!.Equals(iotEdgeModel.ExternalIdentifier, StringComparison.Ordinal)).ToList(); | ||
|
||
if (iotEdgeModels.Count == 0) | ||
{ | ||
//In Aws, it is possible to create a deployment without a name, so it will take the id as a name | ||
//Here is how we handle it | ||
iotEdgeModel.Name ??= iotEdgeModel.ModelId; | ||
|
||
var edgeModel = this.mapper.Map<EdgeDeviceModel>(iotEdgeModel); | ||
|
||
await this.edgeDeviceModelRepository.InsertAsync(edgeModel); | ||
await this.unitOfWork.SaveAsync(); | ||
_ = this.deviceModelImageManager.SetDefaultImageToModel(edgeModel.Id); | ||
} | ||
|
||
} | ||
|
||
private async Task DeleteGreenGrassDeployments(List<IoTEdgeModel> edgeModels) | ||
{ | ||
//Get All Deployments that are not in AWS | ||
var deploymentToDelete = (await this.edgeDeviceModelRepository.GetAllAsync()) | ||
.Where(edge => !edgeModels.Any(edgeModel => edge.ExternalIdentifier!.Equals(edgeModel.ExternalIdentifier, StringComparison.Ordinal))) | ||
.ToList(); | ||
|
||
deploymentToDelete.ForEach(async edgeModel => | ||
{ | ||
await this.deviceModelImageManager.DeleteDeviceModelImageAsync(edgeModel.Id); | ||
this.edgeDeviceModelRepository.Delete(edgeModel.Id); | ||
await this.unitOfWork.SaveAsync(); | ||
}); | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
...zureIoTHub.Portal.Tests.Unit/Infrastructure/Jobs/AWS/SyncGreenGrassDeploymentsJobTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// Copyright (c) CGI France. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
namespace AzureIoTHub.Portal.Tests.Unit.Infrastructure.Jobs.AWS | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Amazon.GreengrassV2; | ||
using Amazon.GreengrassV2.Model; | ||
using Amazon.IoT; | ||
using AutoFixture; | ||
using AzureIoTHub.Portal.Application.Managers; | ||
using AzureIoTHub.Portal.Domain; | ||
using AzureIoTHub.Portal.Domain.Entities; | ||
using AzureIoTHub.Portal.Domain.Repositories; | ||
using AzureIoTHub.Portal.Infrastructure.Jobs.AWS; | ||
using AzureIoTHub.Portal.Tests.Unit.UnitTests.Bases; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Moq; | ||
using NUnit.Framework; | ||
using Quartz; | ||
|
||
public class SyncGreenGrassDeploymentsJobTests : BackendUnitTest | ||
{ | ||
private IJob syncGreenGrassJob; | ||
|
||
private Mock<IUnitOfWork> mockUnitOfWork; | ||
private Mock<IEdgeDeviceModelRepository> mockEdgeDeviceModelRepository; | ||
private Mock<IAmazonIoT> mockAmazonIoTClient; | ||
private Mock<IAmazonGreengrassV2> mockAmazonGreenGrass; | ||
private Mock<IDeviceModelImageManager> mockDeviceModelImageManager; | ||
|
||
public override void Setup() | ||
{ | ||
base.Setup(); | ||
|
||
this.mockDeviceModelImageManager = MockRepository.Create<IDeviceModelImageManager>(); | ||
this.mockUnitOfWork = MockRepository.Create<IUnitOfWork>(); | ||
this.mockEdgeDeviceModelRepository = MockRepository.Create<IEdgeDeviceModelRepository>(); | ||
this.mockAmazonIoTClient = MockRepository.Create<IAmazonIoT>(); | ||
this.mockAmazonGreenGrass = MockRepository.Create<IAmazonGreengrassV2>(); | ||
|
||
_ = ServiceCollection.AddSingleton(this.mockDeviceModelImageManager.Object); | ||
_ = ServiceCollection.AddSingleton(this.mockUnitOfWork.Object); | ||
_ = ServiceCollection.AddSingleton(this.mockEdgeDeviceModelRepository.Object); | ||
_ = ServiceCollection.AddSingleton(this.mockAmazonIoTClient.Object); | ||
_ = ServiceCollection.AddSingleton(this.mockAmazonGreenGrass.Object); | ||
_ = ServiceCollection.AddSingleton<IJob, SyncGreenGrassDeploymentsJob>(); | ||
|
||
|
||
Services = ServiceCollection.BuildServiceProvider(); | ||
|
||
this.syncGreenGrassJob = Services.GetRequiredService<IJob>(); | ||
} | ||
|
||
[Test] | ||
public async Task ExecuteSyncExistingAWSDeploymentsAndCreateNinExistingDeploymentInDB() | ||
{ | ||
|
||
//Arrange | ||
var mockJobExecutionContext = MockRepository.Create<IJobExecutionContext>(); | ||
|
||
var deploymentId = Fixture.Create<string>(); | ||
|
||
var listDeploymentsInAws = new ListDeploymentsResponse | ||
{ | ||
Deployments = new List<Deployment>() | ||
{ | ||
new Deployment | ||
{ | ||
DeploymentId = deploymentId, | ||
}, | ||
new Deployment | ||
{ | ||
DeploymentId = Fixture.Create<string>(), | ||
}, | ||
new Deployment | ||
{ | ||
DeploymentId = Fixture.Create<string>(), | ||
} | ||
} | ||
}; | ||
var existingDeployments = new List<EdgeDeviceModel> | ||
{ | ||
new EdgeDeviceModel | ||
{ | ||
Id = Fixture.Create<string>(), | ||
ExternalIdentifier = deploymentId, | ||
}, | ||
new EdgeDeviceModel | ||
{ | ||
Id = Fixture.Create<string>(), | ||
ExternalIdentifier = Fixture.Create<string>(), | ||
} | ||
}; | ||
|
||
_ = this.mockAmazonGreenGrass.Setup(greengrass => greengrass.ListDeploymentsAsync(It.IsAny<ListDeploymentsRequest>(), It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(listDeploymentsInAws); | ||
|
||
_ = this.mockEdgeDeviceModelRepository.Setup(u => u.GetAllAsync(null, It.IsAny<CancellationToken>())) | ||
.ReturnsAsync(existingDeployments); | ||
|
||
_ = this.mockEdgeDeviceModelRepository.Setup(u => u.InsertAsync(It.Is<EdgeDeviceModel>(s => !s.ExternalIdentifier.Equals(deploymentId, StringComparison.Ordinal)))) | ||
.Returns(Task.CompletedTask); | ||
_ = this.mockDeviceModelImageManager.Setup(c => c.SetDefaultImageToModel(It.Is<string>(s => !s.Equals(deploymentId, StringComparison.Ordinal)))) | ||
.ReturnsAsync(Fixture.Create<string>()); | ||
_ = this.mockUnitOfWork.Setup(c => c.SaveAsync()) | ||
.Returns(Task.CompletedTask); | ||
|
||
// Act | ||
await this.syncGreenGrassJob.Execute(mockJobExecutionContext.Object); | ||
|
||
// Assert | ||
MockRepository.VerifyAll(); | ||
|
||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Check notice
Code scanning / CodeQL
Generic catch clause