Skip to content

Commit

Permalink
Refactor the AWS External Device Service (#2185)
Browse files Browse the repository at this point in the history
* #2110 Refactor AWS External Device

- Remove AWS Exterrnal Device
- Calls to AWS APIs in the respective services
- Add methods to mutualize in IExternalDeviceService

* #2110 Add missing TU

* #2110 Add AWSExternalDeviceService TU
  • Loading branch information
delager authored and kbeaugrand committed Jun 22, 2023
1 parent 1f6192d commit d99d001
Show file tree
Hide file tree
Showing 19 changed files with 885 additions and 1,082 deletions.
7 changes: 7 additions & 0 deletions src/IoTHub.Portal.Application/Mappers/DeviceModelProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public DeviceModelProfile()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.ThingTypeId))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.ThingTypeName))
.ForMember(dest => dest.Description, opts => opts.MapFrom(src => src.ThingTypeProperties.ThingTypeDescription ?? string.Empty));

_ = CreateMap<DescribeThingResponse, ExternalDeviceModelDto>()
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.ThingTypeName));

_ = CreateMap<DescribeThingTypeResponse, ExternalDeviceModelDto>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.ThingTypeId))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.ThingTypeName));
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ namespace IoTHub.Portal.Application.Services
using Microsoft.Azure.Devices.Shared;
using IoTHub.Portal.Domain.Shared;
using Shared.Models.v10;
using Amazon.IoT.Model;

public interface IExternalDeviceService
{
Task<ExternalDeviceModelDto> CreateDeviceModel(ExternalDeviceModelDto deviceModel);

Task DeleteDeviceModel(ExternalDeviceModelDto deviceModel);

Task<bool?> IsEdgeDeviceModel(ExternalDeviceModelDto deviceModel);

Task<Device> GetDevice(string deviceId);

Task<Twin> GetDeviceTwin(string deviceId);
Expand Down Expand Up @@ -49,6 +52,8 @@ Task<PaginationResult<Twin>> GetAllDevice(
Dictionary<string, string>? searchTags = null,
int pageSize = 10);

Task<IList<DescribeThingResponse>> GetAllThing();

Task<PaginationResult<Twin>> GetAllEdgeDevice(
string? continuationToken = null,
string? searchText = null,
Expand Down
11 changes: 6 additions & 5 deletions src/IoTHub.Portal.Infrastructure/Jobs/AWS/SyncThingTypesJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ namespace IoTHub.Portal.Infrastructure.Jobs.AWS
using Amazon.IoT.Model;
using AutoMapper;
using IoTHub.Portal.Application.Managers;
using IoTHub.Portal.Application.Services.AWS;
using IoTHub.Portal.Application.Services;
using IoTHub.Portal.Domain;
using IoTHub.Portal.Domain.Entities;
using IoTHub.Portal.Domain.Repositories;
using IoTHub.Portal.Domain.Shared;
using Microsoft.Extensions.Logging;
using Quartz;

Expand All @@ -25,7 +26,7 @@ public class SyncThingTypesJob : IJob
private readonly IDeviceModelRepository deviceModelRepository;
private readonly IAmazonIoT amazonIoTClient;
private readonly IDeviceModelImageManager deviceModelImageManager;
private readonly IAWSExternalDeviceService awsExternalDeviceService;
private readonly IExternalDeviceService externalDeviceService;

public SyncThingTypesJob(
ILogger<SyncThingTypesJob> logger,
Expand All @@ -34,14 +35,14 @@ public SyncThingTypesJob(
IDeviceModelRepository deviceModelRepository,
IAmazonIoT amazonIoTClient,
IDeviceModelImageManager awsImageManager,
IAWSExternalDeviceService awsExternalDeviceService)
IExternalDeviceService externalDeviceService)
{
this.deviceModelImageManager = awsImageManager;
this.mapper = mapper;
this.unitOfWork = unitOfWork;
this.deviceModelRepository = deviceModelRepository;
this.amazonIoTClient = amazonIoTClient;
this.awsExternalDeviceService = awsExternalDeviceService;
this.externalDeviceService = externalDeviceService;
this.logger = logger;
}

Expand All @@ -68,7 +69,7 @@ private async Task SyncThingTypesAsDeviceModels()

foreach (var thingType in thingTypes)
{
var isEdge = await awsExternalDeviceService.IsEdgeThingType(thingType);
var isEdge = await externalDeviceService.IsEdgeDeviceModel(this.mapper.Map<ExternalDeviceModelDto>(thingType));

// Cannot know if the thing type was created for an iotEdge or not, so skipping...
if (!isEdge.HasValue)
Expand Down
19 changes: 7 additions & 12 deletions src/IoTHub.Portal.Infrastructure/Jobs/AWS/SyncThingsJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ namespace IoTHub.Portal.Infrastructure.Jobs.AWS
using Amazon.GreengrassV2.Model;
using Amazon.GreengrassV2;
using Amazon.IoT;
using Amazon.IoT.Model;
using Amazon.IotData;
using Amazon.IotData.Model;
using AutoMapper;
using IoTHub.Portal.Application.Services.AWS;
using IoTHub.Portal.Domain;
using IoTHub.Portal.Domain.Entities;
using IoTHub.Portal.Domain.Repositories;
using Microsoft.Extensions.Logging;
using Quartz;
using Quartz.Util;
using IoTHub.Portal.Application.Services;
using IoTHub.Portal.Domain.Shared;

[DisallowConcurrentExecution]
public class SyncThingsJob : IJob
Expand All @@ -36,7 +36,7 @@ public class SyncThingsJob : IJob
private readonly IAmazonIoT amazonIoTClient;
private readonly IAmazonIotData amazonIoTDataClient;
private readonly IAmazonGreengrassV2 amazonGreenGrass;
private readonly IAWSExternalDeviceService awsExternalDeviceService;
private readonly IExternalDeviceService externalDeviceService;

public SyncThingsJob(
ILogger<SyncThingsJob> logger,
Expand All @@ -50,7 +50,7 @@ public SyncThingsJob(
IAmazonIoT amazonIoTClient,
IAmazonIotData amazonIoTDataClient,
IAmazonGreengrassV2 amazonGreenGrass,
IAWSExternalDeviceService awsExternalDeviceService)
IExternalDeviceService externalDeviceService)
{
this.mapper = mapper;
this.unitOfWork = unitOfWork;
Expand All @@ -63,7 +63,7 @@ public SyncThingsJob(
this.amazonIoTDataClient = amazonIoTDataClient;
this.amazonGreenGrass = amazonGreenGrass;
this.logger = logger;
this.awsExternalDeviceService = awsExternalDeviceService;
this.externalDeviceService = externalDeviceService;
}


Expand All @@ -85,7 +85,7 @@ public async Task Execute(IJobExecutionContext context)

private async Task SyncThingsAsDevices()
{
var things = await this.awsExternalDeviceService.GetAllThings();
var things = await this.externalDeviceService.GetAllThing();

foreach (var thing in things)
{
Expand All @@ -107,12 +107,7 @@ private async Task SyncThingsAsDevices()
//Retrieve ThingType to know if it's an iotEdge
try
{
var thingType = await this.amazonIoTClient.DescribeThingTypeAsync(new DescribeThingTypeRequest()
{
ThingTypeName = thing.ThingTypeName
});

isEdge = await awsExternalDeviceService.IsEdgeThingType(thingType);
isEdge = await externalDeviceService.IsEdgeDeviceModel(this.mapper.Map<ExternalDeviceModelDto>(thing));
}
catch (AmazonIoTException e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace IoTHub.Portal.Infrastructure.Services.AWS
using System.Collections.Generic;
using System.Threading.Tasks;
using IoTHub.Portal.Application.Services;
using IoTHub.Portal.Application.Services.AWS;
using IoTHub.Portal.Domain.Exceptions;
using IoTHub.Portal.Models.v10;
using Newtonsoft.Json;
Expand All @@ -18,20 +17,25 @@ namespace IoTHub.Portal.Infrastructure.Services.AWS
using IoTHub.Portal.Domain.Repositories;
using Azure;
using IoTHub.Portal.Application.Helpers;
using Amazon.IoT;
using Amazon.IotData;

public class AWSDevicePropertyService : IDevicePropertyService
{
private readonly IDeviceModelPropertiesService deviceModelPropertiesService;
private readonly IAWSExternalDeviceService externalDeviceService;
private readonly IDeviceRepository deviceRepository;
private readonly IAmazonIoT amazonIoTClient;
private readonly IAmazonIotData amazonIotDataClient;

public AWSDevicePropertyService(IDeviceModelPropertiesService deviceModelPropertiesService
, IAWSExternalDeviceService externalDeviceService
, IDeviceRepository deviceRepository)
, IDeviceRepository deviceRepository
, IAmazonIoT amazonIoTClient
, IAmazonIotData amazonIotDataClient)
{
this.deviceModelPropertiesService = deviceModelPropertiesService;
this.externalDeviceService = externalDeviceService;
this.deviceRepository = deviceRepository;
this.amazonIoTClient = amazonIoTClient;
this.amazonIotDataClient = amazonIotDataClient;
}

public async Task<IEnumerable<DevicePropertyValue>> GetProperties(string deviceId)
Expand All @@ -42,7 +46,14 @@ public async Task<IEnumerable<DevicePropertyValue>> GetProperties(string deviceI
throw new ResourceNotFoundException($"Unable to find the device {deviceId} in DB");
}

var deviceShadow = await this.externalDeviceService.GetDeviceShadow(deviceDb.Name);
var shadowResponse = await this.amazonIotDataClient.GetThingShadowAsync(new GetThingShadowRequest
{
ThingName = deviceDb.Name
});
if (shadowResponse.HttpStatusCode != System.Net.HttpStatusCode.OK)
{
throw new InternalServerErrorException($"Unable to get the thing shadow with device name : {deviceDb.Name} due to an error in the Amazon IoT API : {shadowResponse.HttpStatusCode}");
}

IEnumerable<DeviceModelProperty> items;
try
Expand All @@ -60,7 +71,7 @@ public async Task<IEnumerable<DevicePropertyValue>> GetProperties(string deviceI

try
{
desiredPropertiesAsJson = AWSDeviceHelper.RetrieveDesiredProperties(deviceShadow);
desiredPropertiesAsJson = AWSDeviceHelper.RetrieveDesiredProperties(shadowResponse);
}
catch (JsonReaderException e)
{
Expand All @@ -69,7 +80,7 @@ public async Task<IEnumerable<DevicePropertyValue>> GetProperties(string deviceI

try
{
reportedPropertiesAsJson = AWSDeviceHelper.RetrieveReportedProperties(deviceShadow);
reportedPropertiesAsJson = AWSDeviceHelper.RetrieveReportedProperties(shadowResponse);
}
catch (JsonReaderException e)
{
Expand Down Expand Up @@ -137,7 +148,12 @@ public async Task SetProperties(string deviceId, IEnumerable<DevicePropertyValue
Payload = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload)))
};

_ = await this.externalDeviceService.UpdateDeviceShadow(shadowRequest);
var shadowResponse = await this.amazonIotDataClient.UpdateThingShadowAsync(shadowRequest);

if (shadowResponse.HttpStatusCode != System.Net.HttpStatusCode.OK)
{
throw new InternalServerErrorException($"Unable to create/update the thing shadow with device name : {shadowRequest.ThingName} due to an error in the Amazon IoT API : {shadowResponse.HttpStatusCode}");
}
}
}
}
Loading

0 comments on commit d99d001

Please sign in to comment.