Skip to content

Commit

Permalink
#1922 Delete AWS IoT Device (#2119)
Browse files Browse the repository at this point in the history
- Delete AWS Device
- TU Delete AWS Device
  • Loading branch information
delager authored and kbeaugrand committed Jun 23, 2023
1 parent abccb57 commit 4d90761
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace AzureIoTHub.Portal.Application.Mappers.AWS
using Amazon.IoT.Model;
using Amazon.IotData.Model;
using AutoMapper;
using AzureIoTHub.Portal.Domain.Entities;
using Models.v10;
using Newtonsoft.Json;

Expand All @@ -25,6 +26,10 @@ public AWSDeviceThingProfile()
.ForPath(dest => dest.AttributePayload.Attributes, opts => opts.MapFrom(src => src.Tags))
.ReverseMap();

_ = CreateMap<Device, DeleteThingRequest>()
.ForMember(dest => dest.ThingName, opts => opts.MapFrom(src => src.Name))
.ReverseMap();

_ = CreateMap<DeviceDetails, UpdateThingShadowRequest>()
.ForMember(dest => dest.ThingName, opts => opts.MapFrom(src => src.DeviceName))
.ForMember(dest => dest.Payload, opts => opts.MapFrom(src => EmptyPayload()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public interface IAWSExternalDeviceService

Task<UpdateThingResponse> UpdateDevice(UpdateThingRequest device);

Task<DeleteThingResponse> DeleteDevice(DeleteThingRequest device);

Task<GetThingShadowResponse> GetDeviceShadow(string deviceName);

Task<UpdateThingShadowResponse> UpdateDeviceShadow(UpdateThingShadowRequest shadow);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

namespace AzureIoTHub.Portal.Infrastructure.Services.AWS
{
using System;
using System.Threading.Tasks;
using AzureIoTHub.Portal.Application.Services;
using Models.v10;
Expand Down Expand Up @@ -67,9 +66,15 @@ public override async Task<DeviceDetails> UpdateDevice(DeviceDetails device)
return await UpdateDeviceInDatabase(device);
}

public override Task DeleteDevice(string deviceId)
public override async Task DeleteDevice(string deviceId)
{
throw new NotImplementedException();
//Delete Thing
var device = await deviceRepository.GetByIdAsync(deviceId);
var deleteThingRequest = this.mapper.Map<DeleteThingRequest>(device);
_ = await this.externalDevicesService.DeleteDevice(deleteThingRequest);

//Delete Thing in DB
await DeleteDeviceInDatabase(deviceId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ public async Task<UpdateThingResponse> UpdateDevice(UpdateThingRequest device)
return thingResponse;
}

public async Task<DeleteThingResponse> DeleteDevice(DeleteThingRequest device)
{
var deleteResponse = await this.amazonIotClient.DeleteThingAsync(device);

if (deleteResponse.HttpStatusCode != System.Net.HttpStatusCode.OK)
{
throw new InternalServerErrorException($"Unable to delete the thing with device name : {device.ThingName} due to an error in the Amazon IoT API : {deleteResponse.HttpStatusCode}");
}

return deleteResponse;
}

public async Task<GetThingShadowResponse> GetDeviceShadow(string deviceName)
{
var shadowRequest = new GetThingShadowRequest { ThingName = deviceName };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace AzureIoTHub.Portal.Tests.Unit.Infrastructure.Services
using AzureIoTHub.Portal.Tests.Unit.UnitTests.Bases;
using EntityFramework.Exceptions.Common;
using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
Expand Down Expand Up @@ -267,5 +268,122 @@ public async Task UpdateDeviceWhenDbUpdateExceptionIsRaisedCannotInsertNullExcep
_ = await act.Should().ThrowAsync<CannotInsertNullException>();
MockRepository.VerifyAll();
}

[Test]
public async Task DeleteDevice()
{
// Arrange
var deviceDto = new DeviceDetails
{
DeviceID = Fixture.Create<string>()
};

var device = new Device
{
Id = deviceDto.DeviceID,
Tags = Fixture.CreateMany<DeviceTagValue>(5).ToList(),
Labels = Fixture.CreateMany<Label>(5).ToList()
};

_ = this.mockAWSExternalDevicesService.Setup(service => service.DeleteDevice(It.IsAny<DeleteThingRequest>()))
.ReturnsAsync(new DeleteThingResponse()
{
HttpStatusCode = HttpStatusCode.OK
});

_ = this.mockDeviceRepository.Setup(repository => repository.GetByIdAsync(deviceDto.DeviceID, d => d.Tags, d => d.Labels))
.ReturnsAsync(device);

_ = this.mockDeviceRepository.Setup(repository => repository.GetByIdAsync(deviceDto.DeviceID))
.ReturnsAsync(device);

this.mockDeviceTagValueRepository.Setup(repository => repository.Delete(It.IsAny<string>()))
.Verifiable();

this.mockLabelRepository.Setup(repository => repository.Delete(It.IsAny<string>()))
.Verifiable();

this.mockDeviceRepository.Setup(repository => repository.Delete(deviceDto.DeviceID))
.Verifiable();

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

// Act
await this.awsDeviceService.DeleteDevice(deviceDto.DeviceID);

// Assert
MockRepository.VerifyAll();
}

[Test]
public async Task DeleteDeviceNothingIsDoneIfDeviceNotExist()
{
// Arrange
var deviceDto = new DeviceDetails
{
DeviceID = Fixture.Create<string>()
};

_ = this.mockAWSExternalDevicesService.Setup(service => service.DeleteDevice(It.IsAny<DeleteThingRequest>()))
.ReturnsAsync(new DeleteThingResponse()
{
HttpStatusCode = HttpStatusCode.OK
});

_ = this.mockDeviceRepository.Setup(repository => repository.GetByIdAsync(deviceDto.DeviceID, d => d.Tags, d => d.Labels))
.ReturnsAsync((Device)null);

_ = this.mockDeviceRepository.Setup(repository => repository.GetByIdAsync(deviceDto.DeviceID))
.ReturnsAsync((Device)null);

// Act
await this.awsDeviceService.DeleteDevice(deviceDto.DeviceID);

// Assert
MockRepository.VerifyAll();
}

[Test]
public async Task DeleteDeviceWhenDbUpdateExceptionIsRaisedDbUpdateExceptionIsThrown()
{
// Arrange
var deviceDto = new DeviceDetails
{
DeviceID = Fixture.Create<string>()
};

var device = new Device
{
Id = deviceDto.DeviceID,
Tags = new List<DeviceTagValue>(),
Labels = new List<Label>(),
};

_ = this.mockAWSExternalDevicesService.Setup(service => service.DeleteDevice(It.IsAny<DeleteThingRequest>()))
.ReturnsAsync(new DeleteThingResponse()
{
HttpStatusCode = HttpStatusCode.OK
});

_ = this.mockDeviceRepository.Setup(repository => repository.GetByIdAsync(deviceDto.DeviceID, d => d.Tags, d => d.Labels))
.ReturnsAsync(device);

_ = this.mockDeviceRepository.Setup(repository => repository.GetByIdAsync(deviceDto.DeviceID))
.ReturnsAsync(device);

this.mockDeviceRepository.Setup(repository => repository.Delete(deviceDto.DeviceID))
.Verifiable();

_ = this.mockUnitOfWork.Setup(work => work.SaveAsync())
.ThrowsAsync(new DbUpdateException());

// Act
var act = () => this.awsDeviceService.DeleteDevice(deviceDto.DeviceID);

// Assert
_ = await act.Should().ThrowAsync<DbUpdateException>();
MockRepository.VerifyAll();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,55 @@ public Task UpdateDeviceShouldThrowInternalServerErrorIfHttpStatusCodeIsNotOK()
return Task.CompletedTask;
}

[Test]
public async Task DeleteDeviceShouldReturnAValue()
{
// Arrange
var deleteThingRequest = new DeleteThingRequest()
{
ThingName = Fixture.Create<string>(),
};

var expected = new DeleteThingResponse
{
HttpStatusCode = HttpStatusCode.OK
};

_ = this.mockAmazonIotClient.Setup(iotClient => iotClient.DeleteThingAsync(It.IsAny<DeleteThingRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(expected);

//Act
var result = await this.awsExternalDeviceService.DeleteDevice(deleteThingRequest);

//Assert
_ = result.Should().BeEquivalentTo(expected);
MockRepository.VerifyAll();
}

[Test]
public Task DeleteDeviceShouldThrowInternalServerErrorIfHttpStatusCodeIsNotOK()
{
// Arrange
var deleteThingRequest = new DeleteThingRequest()
{
ThingName = Fixture.Create<string>(),
};

_ = this.mockAmazonIotClient.Setup(iotClient => iotClient.DeleteThingAsync(It.IsAny<DeleteThingRequest>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new DeleteThingResponse
{
HttpStatusCode = HttpStatusCode.BadRequest
});

//Act
var result = () => this.awsExternalDeviceService.DeleteDevice(deleteThingRequest);

//Assert
_ = result.Should().ThrowAsync<InternalServerErrorException>();
MockRepository.VerifyAll();
return Task.CompletedTask;
}

[Test]
public async Task GetDeviceShadowShouldReturnAValue()
{
Expand Down

0 comments on commit 4d90761

Please sign in to comment.