diff --git a/src/AzureIoTHub.Portal.Client/Pages/EdgeModels/EdgeModule/ModuleDialog.razor b/src/AzureIoTHub.Portal.Client/Pages/EdgeModels/EdgeModule/ModuleDialog.razor
index ecd1f1375..2d691ea42 100644
--- a/src/AzureIoTHub.Portal.Client/Pages/EdgeModels/EdgeModule/ModuleDialog.razor
+++ b/src/AzureIoTHub.Portal.Client/Pages/EdgeModels/EdgeModule/ModuleDialog.razor
@@ -50,7 +50,7 @@
Required="true"/>
- The Version should be incremented when updating the component
+ The Version Number should be incremented when updating the component
}
@@ -120,7 +120,10 @@
Module.ModuleName = currentModuleName;
Module.ImageURI = currentImageUri;
Module.ContainerCreateOptions = currentContainerCreateOptions;
- Module.Version = currentNumVersion;
+
+ if (Portal.CloudProvider.Equals(CloudProviders.Azure)) { Module.Version = " "; }
+ else { Module.Version = currentNumVersion; }
+
Module.EnvironmentVariables = new List(currentEnvironmentVariables.ToArray());
Module.ModuleIdentityTwinSettings = new List(currentModuleIdentityTwinSettings.ToArray());
Module.Commands = new List(currentCommands.ToArray());
diff --git a/src/AzureIoTHub.Portal.Domain/Entities/EdgeDeviceModel.cs b/src/AzureIoTHub.Portal.Domain/Entities/EdgeDeviceModel.cs
index 2c9978eaf..14f9c1622 100644
--- a/src/AzureIoTHub.Portal.Domain/Entities/EdgeDeviceModel.cs
+++ b/src/AzureIoTHub.Portal.Domain/Entities/EdgeDeviceModel.cs
@@ -10,7 +10,7 @@ public class EdgeDeviceModel : EntityBase
public string Name { get; set; } = default!;
public string? Description { get; set; }
- public string? IdProvider { get; set; }
+ public string? ExternalIdentifier { get; set; }
///
/// Labels
diff --git a/src/AzureIoTHub.Portal.Infrastructure/Services/AWS/AwsConfigService.cs b/src/AzureIoTHub.Portal.Infrastructure/Services/AWS/AwsConfigService.cs
index dbefca0fc..8b3d9ef29 100644
--- a/src/AzureIoTHub.Portal.Infrastructure/Services/AWS/AwsConfigService.cs
+++ b/src/AzureIoTHub.Portal.Infrastructure/Services/AWS/AwsConfigService.cs
@@ -74,7 +74,7 @@ public async Task RollOutEdgeModelConfiguration(IoTEdgeModel edgeModel)
}
else
{
- edgeModel!.IdProvider = createDeploymentResponse.DeploymentId;
+ edgeModel!.ExternalIdentifier = createDeploymentResponse.DeploymentId;
_ = this.mapper.Map(edgeModel, edgeModelEntity);
@@ -240,9 +240,45 @@ public Task GetConfigItem(string id)
throw new NotImplementedException();
}
- public Task DeleteConfiguration(string configId)
+ public async Task DeleteConfiguration(string modelId)
{
- throw new NotImplementedException();
+ var modules = await GetConfigModuleList(modelId);
+ foreach (var module in modules)
+ {
+ var deletedComponentResponse = await this.greengras.DeleteComponentAsync(new DeleteComponentRequest
+ {
+ Arn = $"arn:aws:greengrass:{config.AWSRegion}:{config.AWSAccountId}:components:{module.ModuleName}:versions:{module.Version}"
+ });
+
+ if (deletedComponentResponse.HttpStatusCode != HttpStatusCode.NoContent)
+ {
+ throw new InternalServerErrorException("The deletion of the component failed due to an error in the Amazon IoT API.");
+
+ }
+ }
+
+ var cancelDeploymentResponse = await this.greengras.CancelDeploymentAsync(new CancelDeploymentRequest
+ {
+ DeploymentId = modelId
+ });
+ if (cancelDeploymentResponse.HttpStatusCode != HttpStatusCode.OK)
+ {
+ throw new InternalServerErrorException("The cancellation of the deployment failed due to an error in the Amazon IoT API.");
+
+ }
+ else
+ {
+ var deleteDeploymentResponse = await this.greengras.DeleteDeploymentAsync(new DeleteDeploymentRequest
+ {
+ DeploymentId = modelId
+ });
+
+ if (deleteDeploymentResponse.HttpStatusCode != HttpStatusCode.NoContent)
+ {
+ throw new InternalServerErrorException("The deletion of the deployment failed due to an error in the Amazon IoT API.");
+ }
+ }
+
}
public Task GetFailedDeploymentsCount()
diff --git a/src/AzureIoTHub.Portal.Infrastructure/Services/EdgeModelService.cs b/src/AzureIoTHub.Portal.Infrastructure/Services/EdgeModelService.cs
index dbcec3694..96087e3a9 100644
--- a/src/AzureIoTHub.Portal.Infrastructure/Services/EdgeModelService.cs
+++ b/src/AzureIoTHub.Portal.Infrastructure/Services/EdgeModelService.cs
@@ -219,7 +219,7 @@ private async Task GetAzureEdgeModel(EdgeDeviceModel edgeModelEnti
private async Task GetAwsEdgeModel(EdgeDeviceModel edgeModelEntity)
{
- var modules = await this.configService.GetConfigModuleList(edgeModelEntity.IdProvider!);
+ var modules = await this.configService.GetConfigModuleList(edgeModelEntity.ExternalIdentifier!);
//TODO : User a mapper
//Previously return this.edgeDeviceModelMapper.CreateEdgeDeviceModel(query.Value, modules, routes, commands);
var result = new IoTEdgeModel
@@ -282,17 +282,24 @@ public async Task DeleteEdgeModel(string edgeModelId)
return;
}
- var config = this.configService.GetIoTEdgeConfigurations().Result.FirstOrDefault(x => x.Id.StartsWith(edgeModelId, StringComparison.Ordinal));
-
- if (config != null)
+ if (this.config.CloudProvider.Equals(CloudProviders.Azure, StringComparison.Ordinal))
{
- await this.configService.DeleteConfiguration(config.Id);
- }
+ var config = this.configService.GetIoTEdgeConfigurations().Result.FirstOrDefault(x => x.Id.StartsWith(edgeModelId, StringComparison.Ordinal));
- var existingCommands = this.commandRepository.GetAll().Where(x => x.EdgeDeviceModelId == edgeModelId).ToList();
- foreach (var command in existingCommands)
+ if (config != null)
+ {
+ await this.configService.DeleteConfiguration(config.Id);
+ }
+
+ var existingCommands = this.commandRepository.GetAll().Where(x => x.EdgeDeviceModelId == edgeModelId).ToList();
+ foreach (var command in existingCommands)
+ {
+ this.commandRepository.Delete(command.Id);
+ }
+ }
+ else
{
- this.commandRepository.Delete(command.Id);
+ await this.configService.DeleteConfiguration(edgeModelEntity.ExternalIdentifier!);
}
foreach (var labelEntity in edgeModelEntity.Labels)
diff --git a/src/AzureIoTHub.Portal.Infrastructure/Startup/AWSServiceCollectionExtension.cs b/src/AzureIoTHub.Portal.Infrastructure/Startup/AWSServiceCollectionExtension.cs
index 0db5dbd6b..b2e501114 100644
--- a/src/AzureIoTHub.Portal.Infrastructure/Startup/AWSServiceCollectionExtension.cs
+++ b/src/AzureIoTHub.Portal.Infrastructure/Startup/AWSServiceCollectionExtension.cs
@@ -29,8 +29,7 @@ public static IServiceCollection AddAWSInfrastructureLayer(this IServiceCollecti
.ConfigureAWSClient(configuration).Result
.ConfigureAWSServices()
.ConfigureAWSDeviceModelImages()
- .ConfigureAWSSyncJobs(configuration)
- .ConfigureOtherDependencies();
+ .ConfigureAWSSyncJobs(configuration);
}
private static async Task ConfigureAWSClient(this IServiceCollection services, ConfigHandler configuration)
{
@@ -88,10 +87,5 @@ private static IServiceCollection ConfigureAWSSyncJobs(this IServiceCollection s
});
}
- private static IServiceCollection ConfigureOtherDependencies(this IServiceCollection services)
- {
- _ = services.AddSingleton(new PortalSettings());
- return services;
- }
}
}
diff --git a/src/AzureIoTHub.Portal.Postgres/Migrations/20230526083144_Change IdProvider to ExternalIdentifier.Designer.cs b/src/AzureIoTHub.Portal.Postgres/Migrations/20230526083144_Change IdProvider to ExternalIdentifier.Designer.cs
new file mode 100644
index 000000000..3757b91f6
--- /dev/null
+++ b/src/AzureIoTHub.Portal.Postgres/Migrations/20230526083144_Change IdProvider to ExternalIdentifier.Designer.cs
@@ -0,0 +1,590 @@
+//
+using System;
+using AzureIoTHub.Portal.Infrastructure;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace AzureIoTHub.Portal.Postgres.Migrations
+{
+ [DbContext(typeof(PortalDbContext))]
+ [Migration("20230526083144_Change IdProvider to ExternalIdentifier")]
+ partial class ChangeIdProvidertoExternalIdentifier
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.4")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.Concentrator", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("ClientThumbprint")
+ .HasColumnType("text");
+
+ b.Property("DeviceType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsConnected")
+ .HasColumnType("boolean");
+
+ b.Property("IsEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("LoraRegion")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Version")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("Concentrators");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.Device", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("DeviceModelId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsConnected")
+ .HasColumnType("boolean");
+
+ b.Property("IsEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("StatusUpdatedTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Version")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeviceModelId");
+
+ b.ToTable("Devices", (string)null);
+
+ b.UseTptMappingStrategy();
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.DeviceModel", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("ABPRelaxMode")
+ .HasColumnType("boolean");
+
+ b.Property("AppEUI")
+ .HasColumnType("text");
+
+ b.Property("ClassType")
+ .HasColumnType("integer");
+
+ b.Property("Deduplication")
+ .HasColumnType("integer");
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("Downlink")
+ .HasColumnType("boolean");
+
+ b.Property("IsBuiltin")
+ .HasColumnType("boolean");
+
+ b.Property("KeepAliveTimeout")
+ .HasColumnType("integer");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PreferredWindow")
+ .HasColumnType("integer");
+
+ b.Property("RXDelay")
+ .HasColumnType("integer");
+
+ b.Property("SensorDecoder")
+ .HasColumnType("text");
+
+ b.Property("SupportLoRaFeatures")
+ .HasColumnType("boolean");
+
+ b.Property("UseOTAA")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.ToTable("DeviceModels");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.DeviceModelCommand", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("Confirmed")
+ .HasColumnType("boolean");
+
+ b.Property("DeviceModelId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Frame")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsBuiltin")
+ .HasColumnType("boolean");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Port")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("DeviceModelCommands");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.DeviceModelProperty", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsWritable")
+ .HasColumnType("boolean");
+
+ b.Property("ModelId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Order")
+ .HasColumnType("integer");
+
+ b.Property("PropertyType")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("DeviceModelProperties");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.DeviceTag", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("Label")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Required")
+ .HasColumnType("boolean");
+
+ b.Property("Searchable")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.ToTable("DeviceTags");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.DeviceTagValue", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("DeviceId")
+ .HasColumnType("text");
+
+ b.Property("EdgeDeviceId")
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeviceId");
+
+ b.HasIndex("EdgeDeviceId");
+
+ b.ToTable("DeviceTagValues");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.EdgeDevice", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("ConnectionState")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DeviceModelId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("NbDevices")
+ .HasColumnType("integer");
+
+ b.Property("NbModules")
+ .HasColumnType("integer");
+
+ b.Property("Scope")
+ .HasColumnType("text");
+
+ b.Property("Version")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeviceModelId");
+
+ b.ToTable("EdgeDevices");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.EdgeDeviceModel", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("ExternalIdentifier")
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("EdgeDeviceModels");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.EdgeDeviceModelCommand", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("EdgeDeviceModelId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ModuleName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("EdgeDeviceModelCommands");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.Label", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("Color")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DeviceId")
+ .HasColumnType("text");
+
+ b.Property("DeviceModelId")
+ .HasColumnType("text");
+
+ b.Property("EdgeDeviceId")
+ .HasColumnType("text");
+
+ b.Property("EdgeDeviceModelId")
+ .HasColumnType("text");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DeviceId");
+
+ b.HasIndex("DeviceModelId");
+
+ b.HasIndex("EdgeDeviceId");
+
+ b.HasIndex("EdgeDeviceModelId");
+
+ b.ToTable("Labels");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.LoRaDeviceTelemetry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("EnqueuedTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LorawanDeviceId")
+ .HasColumnType("text");
+
+ b.Property("Telemetry")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LorawanDeviceId");
+
+ b.ToTable("LoRaDeviceTelemetry");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.LorawanDevice", b =>
+ {
+ b.HasBaseType("AzureIoTHub.Portal.Domain.Entities.Device");
+
+ b.Property("ABPRelaxMode")
+ .HasColumnType("boolean");
+
+ b.Property("AlreadyLoggedInOnce")
+ .HasColumnType("boolean");
+
+ b.Property("AppEUI")
+ .HasColumnType("text");
+
+ b.Property("AppKey")
+ .HasColumnType("text");
+
+ b.Property("AppSKey")
+ .HasColumnType("text");
+
+ b.Property("ClassType")
+ .HasColumnType("integer");
+
+ b.Property("DataRate")
+ .HasColumnType("text");
+
+ b.Property("Deduplication")
+ .HasColumnType("integer");
+
+ b.Property("DevAddr")
+ .HasColumnType("text");
+
+ b.Property("Downlink")
+ .HasColumnType("boolean");
+
+ b.Property("FCntDownStart")
+ .HasColumnType("integer");
+
+ b.Property("FCntResetCounter")
+ .HasColumnType("integer");
+
+ b.Property("FCntUpStart")
+ .HasColumnType("integer");
+
+ b.Property("GatewayID")
+ .HasColumnType("text");
+
+ b.Property("KeepAliveTimeout")
+ .HasColumnType("integer");
+
+ b.Property("NbRep")
+ .HasColumnType("text");
+
+ b.Property("NwkSKey")
+ .HasColumnType("text");
+
+ b.Property("PreferredWindow")
+ .HasColumnType("integer");
+
+ b.Property("RX1DROffset")
+ .HasColumnType("integer");
+
+ b.Property("RX2DataRate")
+ .HasColumnType("integer");
+
+ b.Property("RXDelay")
+ .HasColumnType("integer");
+
+ b.Property("ReportedRX1DROffset")
+ .HasColumnType("text");
+
+ b.Property("ReportedRX2DataRate")
+ .HasColumnType("text");
+
+ b.Property("ReportedRXDelay")
+ .HasColumnType("text");
+
+ b.Property("SensorDecoder")
+ .HasColumnType("text");
+
+ b.Property("Supports32BitFCnt")
+ .HasColumnType("boolean");
+
+ b.Property("TxPower")
+ .HasColumnType("text");
+
+ b.Property("UseOTAA")
+ .HasColumnType("boolean");
+
+ b.ToTable("LorawanDevices", (string)null);
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.Device", b =>
+ {
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.DeviceModel", "DeviceModel")
+ .WithMany()
+ .HasForeignKey("DeviceModelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("DeviceModel");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.DeviceTagValue", b =>
+ {
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.Device", null)
+ .WithMany("Tags")
+ .HasForeignKey("DeviceId");
+
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.EdgeDevice", null)
+ .WithMany("Tags")
+ .HasForeignKey("EdgeDeviceId");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.EdgeDevice", b =>
+ {
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.EdgeDeviceModel", "DeviceModel")
+ .WithMany()
+ .HasForeignKey("DeviceModelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("DeviceModel");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.Label", b =>
+ {
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.Device", null)
+ .WithMany("Labels")
+ .HasForeignKey("DeviceId");
+
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.DeviceModel", null)
+ .WithMany("Labels")
+ .HasForeignKey("DeviceModelId");
+
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.EdgeDevice", null)
+ .WithMany("Labels")
+ .HasForeignKey("EdgeDeviceId");
+
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.EdgeDeviceModel", null)
+ .WithMany("Labels")
+ .HasForeignKey("EdgeDeviceModelId");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.LoRaDeviceTelemetry", b =>
+ {
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.LorawanDevice", null)
+ .WithMany("Telemetry")
+ .HasForeignKey("LorawanDeviceId");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.LorawanDevice", b =>
+ {
+ b.HasOne("AzureIoTHub.Portal.Domain.Entities.Device", null)
+ .WithOne()
+ .HasForeignKey("AzureIoTHub.Portal.Domain.Entities.LorawanDevice", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.Device", b =>
+ {
+ b.Navigation("Labels");
+
+ b.Navigation("Tags");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.DeviceModel", b =>
+ {
+ b.Navigation("Labels");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.EdgeDevice", b =>
+ {
+ b.Navigation("Labels");
+
+ b.Navigation("Tags");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.EdgeDeviceModel", b =>
+ {
+ b.Navigation("Labels");
+ });
+
+ modelBuilder.Entity("AzureIoTHub.Portal.Domain.Entities.LorawanDevice", b =>
+ {
+ b.Navigation("Telemetry");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/AzureIoTHub.Portal.Postgres/Migrations/20230526083144_Change IdProvider to ExternalIdentifier.cs b/src/AzureIoTHub.Portal.Postgres/Migrations/20230526083144_Change IdProvider to ExternalIdentifier.cs
new file mode 100644
index 000000000..d0bd13170
--- /dev/null
+++ b/src/AzureIoTHub.Portal.Postgres/Migrations/20230526083144_Change IdProvider to ExternalIdentifier.cs
@@ -0,0 +1,30 @@
+// Copyright (c) CGI France. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#nullable disable
+
+namespace AzureIoTHub.Portal.Postgres.Migrations
+{
+ using Microsoft.EntityFrameworkCore.Migrations;
+
+ ///
+ public partial class ChangeIdProvidertoExternalIdentifier : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ _ = migrationBuilder.RenameColumn(
+ name: "IdProvider",
+ table: "EdgeDeviceModels",
+ newName: "ExternalIdentifier");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ _ = migrationBuilder.RenameColumn(
+ name: "ExternalIdentifier",
+ table: "EdgeDeviceModels",
+ newName: "IdProvider");
+ }
+ }
+}
diff --git a/src/AzureIoTHub.Portal.Postgres/Migrations/PortalDbContextModelSnapshot.cs b/src/AzureIoTHub.Portal.Postgres/Migrations/PortalDbContextModelSnapshot.cs
index 05d5edac4..27a95859e 100644
--- a/src/AzureIoTHub.Portal.Postgres/Migrations/PortalDbContextModelSnapshot.cs
+++ b/src/AzureIoTHub.Portal.Postgres/Migrations/PortalDbContextModelSnapshot.cs
@@ -300,7 +300,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property("Description")
.HasColumnType("text");
- b.Property("IdProvider")
+ b.Property("ExternalIdentifier")
.HasColumnType("text");
b.Property("Name")
diff --git a/src/AzureIoTHub.Portal.Shared/Models/v1.0/IoTEdgeModelListItem.cs b/src/AzureIoTHub.Portal.Shared/Models/v1.0/IoTEdgeModelListItem.cs
index 5c975bd3e..43c5620be 100644
--- a/src/AzureIoTHub.Portal.Shared/Models/v1.0/IoTEdgeModelListItem.cs
+++ b/src/AzureIoTHub.Portal.Shared/Models/v1.0/IoTEdgeModelListItem.cs
@@ -31,7 +31,7 @@ public class IoTEdgeModelListItem
///
/// The aws deployment ID.
///
- public string IdProvider { get; set; } = default!;
+ public string ExternalIdentifier { get; set; } = default!;
///
diff --git a/src/AzureIoTHub.Portal.Shared/Models/v1.0/IoTEdgeModule.cs b/src/AzureIoTHub.Portal.Shared/Models/v1.0/IoTEdgeModule.cs
index bcb3080ef..643b710f5 100644
--- a/src/AzureIoTHub.Portal.Shared/Models/v1.0/IoTEdgeModule.cs
+++ b/src/AzureIoTHub.Portal.Shared/Models/v1.0/IoTEdgeModule.cs
@@ -46,7 +46,7 @@ public class IoTEdgeModule
///
public List Commands { get; set; } = new List();
- [Required(ErrorMessage = "The component version is required.")]
+ [Required(ErrorMessage = "The component version is required.", AllowEmptyStrings = true)]
public string Version { get; set; } = default!;
}
}
diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Infrastructure/Services/AWS_Tests/AwsConfigTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Infrastructure/Services/AWS_Tests/AwsConfigTests.cs
index 3d30916f7..ce13873fa 100644
--- a/src/AzureIoTHub.Portal.Tests.Unit/Infrastructure/Services/AWS_Tests/AwsConfigTests.cs
+++ b/src/AzureIoTHub.Portal.Tests.Unit/Infrastructure/Services/AWS_Tests/AwsConfigTests.cs
@@ -186,10 +186,64 @@ public async Task GetAllDeploymentComponentsShouldRetreiveImageUriAndEnvironment
});
//Arrange
- _ = await this.awsConfigService.GetConfigModuleList(edge.IdProvider);
+ _ = await this.awsConfigService.GetConfigModuleList(edge.ExternalIdentifier);
//Assert
MockRepository.VerifyAll();
}
+
+ [Test]
+ public async Task DeleteDeploymentShouldDeleteTheDeploymentVersionAndAllItsComponentsVersions()
+ {
+ //Act
+ var edge = Fixture.Create();
+ using var recipeAsMemoryStream = new MemoryStream(Encoding.UTF8.GetBytes(Fixture.Create().ToString()));
+
+ _ = this.mockConfigHandler.Setup(handler => handler.AWSRegion).Returns("eu-west-1");
+ _ = this.mockConfigHandler.Setup(handler => handler.AWSAccountId).Returns("00000000");
+
+ _ = this.mockGreengrasClient.Setup(s3 => s3.GetDeploymentAsync(It.IsAny(), It.IsAny()))
+ .ReturnsAsync(new GetDeploymentResponse
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ Components = new Dictionary
+ {
+ {"test", new ComponentDeploymentSpecification()}
+
+ }
+ });
+
+ _ = this.mockGreengrasClient.Setup(s3 => s3.GetComponentAsync(It.IsAny(), It.IsAny()))
+ .ReturnsAsync(new GetComponentResponse
+ {
+ HttpStatusCode = HttpStatusCode.OK,
+ Recipe = recipeAsMemoryStream,
+ RecipeOutputFormat = RecipeOutputFormat.JSON
+ });
+
+ _ = this.mockGreengrasClient.Setup(s3 => s3.DeleteComponentAsync(It.IsAny(), It.IsAny()))
+ .ReturnsAsync(new DeleteComponentResponse
+ {
+ HttpStatusCode = HttpStatusCode.NoContent
+ });
+
+ _ = this.mockGreengrasClient.Setup(s3 => s3.CancelDeploymentAsync(It.IsAny(), It.IsAny()))
+ .ReturnsAsync(new CancelDeploymentResponse
+ {
+ HttpStatusCode = HttpStatusCode.OK
+ });
+
+ _ = this.mockGreengrasClient.Setup(s3 => s3.DeleteDeploymentAsync(It.IsAny(), It.IsAny()))
+ .ReturnsAsync(new DeleteDeploymentResponse
+ {
+ HttpStatusCode = HttpStatusCode.NoContent
+ });
+ //Arrange
+ await this.awsConfigService.DeleteConfiguration(edge.ExternalIdentifier);
+
+ //Assert
+ MockRepository.VerifyAll();
+
+ }
}
}
diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/EdgeModelServiceTest.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/EdgeModelServiceTest.cs
index e2cd9c466..6857ad796 100644
--- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/EdgeModelServiceTest.cs
+++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/EdgeModelServiceTest.cs
@@ -459,6 +459,8 @@ public void UpdateEdgeModelShouldThrowInternalServerErrorExceptionIfDbUpdateExce
public async Task DeleteEdgeModelShouldDeleteEdgeModel()
{
// Arrange
+ _ = this.mockConfigHandler.Setup(handler => handler.CloudProvider).Returns("Azure");
+
var edgeDeviceModel = Fixture.Create();
var edgeDeviceModelEntity = Mapper.Map(edgeDeviceModel);
@@ -497,6 +499,35 @@ public async Task DeleteEdgeModelShouldDeleteEdgeModel()
MockRepository.VerifyAll();
}
+ [Test]
+ public async Task DeleteEdgeModelForAwsShouldDeleteEdgeModel()
+ {
+ // Arrange
+ _ = this.mockConfigHandler.Setup(handler => handler.CloudProvider).Returns("AWS");
+
+ var edgeDeviceModel = Fixture.Create();
+ var edgeDeviceModelEntity = Mapper.Map(edgeDeviceModel);
+
+ _ = this.mockEdgeDeviceModelRepository.Setup(repository => repository.GetByIdAsync(edgeDeviceModelEntity.Id, d => d.Labels))
+ .ReturnsAsync(edgeDeviceModelEntity);
+
+ this.mockLabelRepository.Setup(repository => repository.Delete(It.IsAny()))
+ .Verifiable();
+
+ _ = this.mockEdgeDeviceModelRepository.Setup(repository => repository.Delete(It.IsAny()));
+ _ = this.mockUnitOfWork.Setup(work => work.SaveAsync())
+ .Returns(Task.CompletedTask);
+
+ _ = this.mockConfigService.Setup(x => x.DeleteConfiguration(It.IsAny()))
+ .Returns(Task.CompletedTask);
+
+ // Act
+ await this.edgeDeviceModelService.DeleteEdgeModel(edgeDeviceModel.ModelId);
+
+ // Assert
+ MockRepository.VerifyAll();
+ }
+
[Test]
public async Task DeleteEdgeModel_ModelDoesntExist_NothingIsDone()
{