From adb410662b0d363f0164d588f4be4db62f340249 Mon Sep 17 00:00:00 2001 From: Hocine Hacherouf Date: Sun, 11 Sep 2022 16:37:00 +0200 Subject: [PATCH] Add migration of device tags from st table to database #1207 --- .../20220911135612_Add DeviceTag.Designer.cs | 79 +++++++++++++++++++ .../20220911135612_Add DeviceTag.cs | 35 ++++++++ .../PortalDbContextModelSnapshot.cs | 20 +++++ .../PortalDbContext.cs | 1 + .../Seeds/DeviceTagSeeder.cs | 43 ++++++++++ src/AzureIoTHub.Portal/Server/Startup.cs | 3 + .../Entities/DeviceTag.cs | 19 +++++ 7 files changed, 200 insertions(+) create mode 100644 src/AzureIoTHub.Portal.Infrastructure/Migrations/20220911135612_Add DeviceTag.Designer.cs create mode 100644 src/AzureIoTHub.Portal.Infrastructure/Migrations/20220911135612_Add DeviceTag.cs create mode 100644 src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceTagSeeder.cs create mode 100644 src/AzureIoTHubPortal.Domain/Entities/DeviceTag.cs diff --git a/src/AzureIoTHub.Portal.Infrastructure/Migrations/20220911135612_Add DeviceTag.Designer.cs b/src/AzureIoTHub.Portal.Infrastructure/Migrations/20220911135612_Add DeviceTag.Designer.cs new file mode 100644 index 000000000..ce9d74c45 --- /dev/null +++ b/src/AzureIoTHub.Portal.Infrastructure/Migrations/20220911135612_Add DeviceTag.Designer.cs @@ -0,0 +1,79 @@ +// +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.Infrastructure.Migrations +{ + [DbContext(typeof(PortalDbContext))] + [Migration("20220911135612_Add DeviceTag")] + partial class AddDeviceTag + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + 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"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/AzureIoTHub.Portal.Infrastructure/Migrations/20220911135612_Add DeviceTag.cs b/src/AzureIoTHub.Portal.Infrastructure/Migrations/20220911135612_Add DeviceTag.cs new file mode 100644 index 000000000..1219a391a --- /dev/null +++ b/src/AzureIoTHub.Portal.Infrastructure/Migrations/20220911135612_Add DeviceTag.cs @@ -0,0 +1,35 @@ +// 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.Infrastructure.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + public partial class AddDeviceTag : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + _ = migrationBuilder.CreateTable( + name: "DeviceTags", + columns: table => new + { + Id = table.Column(type: "text", nullable: false), + Label = table.Column(type: "text", nullable: false), + Required = table.Column(type: "boolean", nullable: false), + Searchable = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + _ = table.PrimaryKey("PK_DeviceTags", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + _ = migrationBuilder.DropTable( + name: "DeviceTags"); + } + } +} diff --git a/src/AzureIoTHub.Portal.Infrastructure/Migrations/PortalDbContextModelSnapshot.cs b/src/AzureIoTHub.Portal.Infrastructure/Migrations/PortalDbContextModelSnapshot.cs index 5bfa19394..efc3c1d28 100644 --- a/src/AzureIoTHub.Portal.Infrastructure/Migrations/PortalDbContextModelSnapshot.cs +++ b/src/AzureIoTHub.Portal.Infrastructure/Migrations/PortalDbContextModelSnapshot.cs @@ -51,6 +51,26 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); + }); #pragma warning restore 612, 618 } } diff --git a/src/AzureIoTHub.Portal.Infrastructure/PortalDbContext.cs b/src/AzureIoTHub.Portal.Infrastructure/PortalDbContext.cs index 34378ff04..0b223cf0a 100644 --- a/src/AzureIoTHub.Portal.Infrastructure/PortalDbContext.cs +++ b/src/AzureIoTHub.Portal.Infrastructure/PortalDbContext.cs @@ -13,6 +13,7 @@ namespace AzureIoTHub.Portal.Infrastructure public class PortalDbContext : DbContext { public DbSet DeviceModelProperties { get; set; } + public DbSet DeviceTags { get; set; } #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public PortalDbContext(DbContextOptions options) diff --git a/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceTagSeeder.cs b/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceTagSeeder.cs new file mode 100644 index 000000000..5a615e799 --- /dev/null +++ b/src/AzureIoTHub.Portal.Infrastructure/Seeds/DeviceTagSeeder.cs @@ -0,0 +1,43 @@ +// 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.Seeds +{ + using Azure.Data.Tables; + using Domain; + using Domain.Entities; + using Factories; + using Microsoft.EntityFrameworkCore; + + internal static class DeviceTagSeeder + { + public static async Task MigrateDeviceTags(this PortalDbContext ctx, ConfigHandler config) + { + var table = new TableClientFactory(config.StorageAccountConnectionString) + .GetDeviceTagSettings(); + + var set = ctx.Set(); + + foreach (var item in table.Query().ToArray()) + { + if (await set.AnyAsync(c => c.Id == item.RowKey)) + continue; + +#pragma warning disable CS8629 // Nullable value type may be null. + _ = await set.AddAsync(new DeviceTag + { + Id = item.RowKey, + Label = item[nameof(DeviceTag.Label)].ToString(), + Required = bool.Parse(item[nameof(DeviceTag.Required)].ToString() ?? "false"), + Searchable = bool.Parse(item[nameof(DeviceTag.Searchable)].ToString() ?? "false") + }); +#pragma warning restore CS8629 // Nullable value type may be null. + + if (config is ProductionConfigHandler) + { + _ = await table.DeleteEntityAsync(item.PartitionKey, item.RowKey); + } + } + } + } +} diff --git a/src/AzureIoTHub.Portal/Server/Startup.cs b/src/AzureIoTHub.Portal/Server/Startup.cs index 851f70ba8..6ba628f43 100644 --- a/src/AzureIoTHub.Portal/Server/Startup.cs +++ b/src/AzureIoTHub.Portal/Server/Startup.cs @@ -445,6 +445,9 @@ private static async Task EnsureDatabaseCreatedAndUpToDate(IApplicationBuilder a await context .MigrateDeviceModelProperties(config); + await context + .MigrateDeviceTags(config); + _ = await context.SaveChangesAsync(); } catch (InvalidOperationException e) diff --git a/src/AzureIoTHubPortal.Domain/Entities/DeviceTag.cs b/src/AzureIoTHubPortal.Domain/Entities/DeviceTag.cs new file mode 100644 index 000000000..f3d0e835e --- /dev/null +++ b/src/AzureIoTHubPortal.Domain/Entities/DeviceTag.cs @@ -0,0 +1,19 @@ +// 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.Domain.Entities +{ + using System.ComponentModel.DataAnnotations.Schema; + using Base; + + public class DeviceTag : EntityBase + { + [NotMapped] public string Name => Id; + + public string Label { get; set; } + + public bool Required { get; set; } + + public bool Searchable { get; set; } + } +}