Skip to content
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

Refactor the AWS External Device Service #2185

Merged
merged 5 commits into from
Jun 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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