From 245111313649e8f84f9ade4aa8b44a419ff1b87b Mon Sep 17 00:00:00 2001 From: Arne Dumarey Date: Fri, 7 Jun 2024 16:28:00 +0200 Subject: [PATCH 1/6] feat: cleanup old tables rename new --- .../Parcel/List/ParcelListV2Query.cs | 6 +- .../Parcel/List/ParcelListOsloV2Query.cs | 6 +- .../Parcel/List/ParcelListV2QueryItem.cs | 2 - .../Modules/LastChangedListConsoleModule.cs | 4 +- .../LegacyContext.cs | 13 +- .../20221123144056_AddV2Tables_P2.cs | 2 +- ...255_UpdateListCountViewToWithCountTable.cs | 6 +- ...641_DeleteOldRenameV2WithCount.Designer.cs | 224 ++++++++++++++ ...240607120641_DeleteOldRenameV2WithCount.cs | 273 +++++++++++++++++ .../Migrations/LegacyContextModelSnapshot.cs | 109 +------ .../ParcelDetail.cs} | 22 +- .../ParcelDetailAddress.cs} | 16 +- .../ParcelDetailExtensions.cs} | 12 +- .../ParcelDetailProjections.cs} | 24 +- .../ParcelDetailV2/ParcelDetailAddressV2.cs | 36 --- .../ParcelDetailV2/ParcelDetailV2.cs | 103 ------- .../ParcelDetailV2Extensions.cs | 30 -- .../ParcelDetailV2ListViewCount.cs | 7 - .../ParcelDetailV2Projections.cs | 287 ------------------ .../Infrastructure/Modules/ApiModule.cs | 12 +- .../Legacy/ParcelDetailItemV2Tests.cs | 12 +- 21 files changed, 575 insertions(+), 631 deletions(-) create mode 100644 src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.Designer.cs create mode 100644 src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.cs rename src/ParcelRegistry.Projections.Legacy/{ParcelDetailWithCountV2/ParcelDetailV2.cs => ParcelDetail/ParcelDetail.cs} (81%) rename src/ParcelRegistry.Projections.Legacy/{ParcelDetailWithCountV2/ParcelDetailAddressV2.cs => ParcelDetail/ParcelDetailAddress.cs} (70%) rename src/ParcelRegistry.Projections.Legacy/{ParcelDetailWithCountV2/ParcelDetailV2Extensions.cs => ParcelDetail/ParcelDetailExtensions.cs} (61%) rename src/ParcelRegistry.Projections.Legacy/{ParcelDetailWithCountV2/ParcelDetailV2Projections.cs => ParcelDetail/ParcelDetailProjections.cs} (94%) delete mode 100644 src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailAddressV2.cs delete mode 100644 src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2.cs delete mode 100644 src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2Extensions.cs delete mode 100644 src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2ListViewCount.cs delete mode 100644 src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2Projections.cs diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Query.cs b/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Query.cs index bc226149..dea4df14 100644 --- a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Query.cs +++ b/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Query.cs @@ -10,7 +10,7 @@ namespace ParcelRegistry.Api.Legacy.Parcel.List using Convertors; using Microsoft.EntityFrameworkCore; using ParcelRegistry.Projections.Legacy; - using ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2; + using Projections.Legacy.ParcelDetail; public class ParcelListV2Query : Query { @@ -84,9 +84,9 @@ public class ParcelSortingV2 : ISorting { public IEnumerable SortableFields { get; } = new[] { - nameof(ParcelDetailV2.CaPaKey), + nameof(ParcelDetail.CaPaKey), }; - public SortingHeader DefaultSortingHeader { get; } = new SortingHeader(nameof(ParcelDetailV2.CaPaKey), SortOrder.Ascending); + public SortingHeader DefaultSortingHeader { get; } = new SortingHeader(nameof(ParcelDetail.CaPaKey), SortOrder.Ascending); } } diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListOsloV2Query.cs b/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListOsloV2Query.cs index ccc89ea3..c73cd678 100644 --- a/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListOsloV2Query.cs +++ b/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListOsloV2Query.cs @@ -10,7 +10,7 @@ namespace ParcelRegistry.Api.Oslo.Parcel.List using Convertors; using Microsoft.EntityFrameworkCore; using Projections.Legacy; - using Projections.Legacy.ParcelDetailWithCountV2; + using Projections.Legacy.ParcelDetail; public class ParcelListOsloV2Query : Query { @@ -82,10 +82,10 @@ public class ParcelSortingV2 : ISorting { public IEnumerable SortableFields { get; } = new[] { - nameof(ParcelDetailV2.CaPaKey), + nameof(ParcelDetail.CaPaKey), }; public SortingHeader DefaultSortingHeader { get; } = - new SortingHeader(nameof(ParcelDetailV2.CaPaKey), SortOrder.Ascending); + new SortingHeader(nameof(ParcelDetail.CaPaKey), SortOrder.Ascending); } } diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListV2QueryItem.cs b/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListV2QueryItem.cs index d0e8194f..772ec924 100644 --- a/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListV2QueryItem.cs +++ b/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListV2QueryItem.cs @@ -1,10 +1,8 @@ namespace ParcelRegistry.Api.Oslo.Parcel.List { using System; - using System.Collections.Generic; using NodaTime; using ParcelRegistry.Parcel; - using Projections.Legacy.ParcelDetailV2; public sealed class ParcelListV2QueryItem { diff --git a/src/ParcelRegistry.Projections.LastChangedList.Console/Infrastructure/Modules/LastChangedListConsoleModule.cs b/src/ParcelRegistry.Projections.LastChangedList.Console/Infrastructure/Modules/LastChangedListConsoleModule.cs index 826d647c..524cc560 100644 --- a/src/ParcelRegistry.Projections.LastChangedList.Console/Infrastructure/Modules/LastChangedListConsoleModule.cs +++ b/src/ParcelRegistry.Projections.LastChangedList.Console/Infrastructure/Modules/LastChangedListConsoleModule.cs @@ -11,7 +11,7 @@ namespace ParcelRegistry.Projections.LastChangedList.Console.Infrastructure.Modu using Be.Vlaanderen.Basisregisters.Projector; using Be.Vlaanderen.Basisregisters.Projector.ConnectedProjections; using Be.Vlaanderen.Basisregisters.Projector.Modules; - using Legacy.ParcelDetailWithCountV2; + using Legacy.ParcelDetail; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -77,7 +77,7 @@ private void RegisterProjections(ContainerBuilder builder) builder.Register(_ => new LastChangedListParcelCacheValidator( _configuration.GetConnectionString("LegacyProjections")!, - ParcelDetailV2Configuration.ProjectionStateName)) + ParcelDetailConfiguration.ProjectionStateName)) .AsSelf(); builder diff --git a/src/ParcelRegistry.Projections.Legacy/LegacyContext.cs b/src/ParcelRegistry.Projections.Legacy/LegacyContext.cs index bfd0e04d..38ad3dca 100755 --- a/src/ParcelRegistry.Projections.Legacy/LegacyContext.cs +++ b/src/ParcelRegistry.Projections.Legacy/LegacyContext.cs @@ -3,17 +3,13 @@ namespace ParcelRegistry.Projections.Legacy using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; using Infrastructure; using Microsoft.EntityFrameworkCore; - using ParcelDetailV2; using ParcelSyndication; - using ParcelDetailWithCount = ParcelDetailWithCountV2.ParcelDetailV2; - + public class LegacyContext : RunnerDbContext { public override string ProjectionStateSchema => Schema.Legacy; internal const string ParcelDetailV2ListCountName = "vw_ParcelDetailV2ListCount"; - - public DbSet ParcelDetailV2 { get; set; } - public DbSet ParcelDetailWithCountV2 { get; set; } + public DbSet ParcelDetailWithCountV2 { get; set; } public DbSet ParcelSyndication { get; set; } @@ -35,4 +31,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .ToView(ParcelDetailV2ListCountName, Schema.Legacy); } } + + public class ParcelDetailV2ListViewCount + { + public long Count { get; set; } + } } diff --git a/src/ParcelRegistry.Projections.Legacy/Migrations/20221123144056_AddV2Tables_P2.cs b/src/ParcelRegistry.Projections.Legacy/Migrations/20221123144056_AddV2Tables_P2.cs index aa5fd2e0..a4fef04b 100644 --- a/src/ParcelRegistry.Projections.Legacy/Migrations/20221123144056_AddV2Tables_P2.cs +++ b/src/ParcelRegistry.Projections.Legacy/Migrations/20221123144056_AddV2Tables_P2.cs @@ -20,7 +20,7 @@ CREATE VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListC WITH SCHEMABINDING AS SELECT COUNT_BIG(*) as Count - FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailV2.ParcelDetailV2Configuration.TableName}] + FROM [{Infrastructure.Schema.Legacy}].[ParcelDetailsV2] WHERE [Removed] = 0"); migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); diff --git a/src/ParcelRegistry.Projections.Legacy/Migrations/20240528134255_UpdateListCountViewToWithCountTable.cs b/src/ParcelRegistry.Projections.Legacy/Migrations/20240528134255_UpdateListCountViewToWithCountTable.cs index 524cd792..e15fad69 100644 --- a/src/ParcelRegistry.Projections.Legacy/Migrations/20240528134255_UpdateListCountViewToWithCountTable.cs +++ b/src/ParcelRegistry.Projections.Legacy/Migrations/20240528134255_UpdateListCountViewToWithCountTable.cs @@ -4,6 +4,8 @@ namespace ParcelRegistry.Projections.Legacy.Migrations { + using ParcelDetail; + /// public partial class UpdateListCountViewToWithCountTable : Migration { @@ -15,7 +17,7 @@ ALTER VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCo WITH SCHEMABINDING AS SELECT COUNT_BIG(*) as Count - FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailWithCountV2.ParcelDetailV2Configuration.TableName}] + FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailConfiguration.TableName}] WHERE [Removed] = 0"); migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); @@ -29,7 +31,7 @@ ALTER VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCo WITH SCHEMABINDING AS SELECT COUNT_BIG(*) as Count - FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailV2.ParcelDetailV2Configuration.TableName}] + FROM [{Infrastructure.Schema.Legacy}].[ParcelDetailsV2] WHERE [Removed] = 0"); migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); diff --git a/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.Designer.cs b/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.Designer.cs new file mode 100644 index 00000000..0143b144 --- /dev/null +++ b/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.Designer.cs @@ -0,0 +1,224 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ParcelRegistry.Projections.Legacy; + +#nullable disable + +namespace ParcelRegistry.Projections.Legacy.Migrations +{ + [DbContext(typeof(LegacyContext))] + [Migration("20240607120641_DeleteOldRenameV2WithCount")] + partial class DeleteOldRenameV2WithCount + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.ProjectionStates.ProjectionStateItem", b => + { + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("DesiredState") + .HasColumnType("nvarchar(max)"); + + b.Property("DesiredStateChangedAt") + .HasColumnType("datetimeoffset"); + + b.Property("ErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("Position") + .HasColumnType("bigint"); + + b.HasKey("Name"); + + b.ToTable("ProjectionStates", "ParcelRegistryLegacy"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetail", b => + { + b.Property("ParcelId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CaPaKey") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Gml") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("GmlType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastEventHash") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Removed") + .HasColumnType("bit"); + + b.Property("StatusAsString") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("nvarchar(450)") + .HasColumnName("Status"); + + b.Property("VersionTimestampAsDateTimeOffset") + .HasColumnType("datetimeoffset") + .HasColumnName("VersionTimestamp"); + + b.HasKey("ParcelId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("ParcelId"), false); + + b.HasAlternateKey("CaPaKey"); + + b.HasIndex("CaPaKey"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CaPaKey")); + + b.HasIndex("Removed"); + + SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("Removed"), new[] { "CaPaKey", "StatusAsString", "VersionTimestampAsDateTimeOffset" }); + + b.HasIndex("StatusAsString"); + + b.ToTable("ParcelDetails", "ParcelRegistryLegacy"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetailAddress", b => + { + b.Property("ParcelId") + .HasColumnType("uniqueidentifier"); + + b.Property("AddressPersistentLocalId") + .HasColumnType("int"); + + b.Property("Count") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(1); + + b.HasKey("ParcelId", "AddressPersistentLocalId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("ParcelId", "AddressPersistentLocalId")); + + b.HasIndex("AddressPersistentLocalId"); + + b.ToTable("ParcelDetailAddresses", "ParcelRegistryLegacy"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailV2ListViewCount", b => + { + b.Property("Count") + .HasColumnType("bigint"); + + b.ToTable((string)null); + + b.ToView("vw_ParcelDetailV2ListCount", "ParcelRegistryLegacy"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelSyndication.ParcelSyndicationItem", b => + { + b.Property("Position") + .HasColumnType("bigint"); + + b.Property("AddressPersistentLocalIdsAsString") + .HasColumnType("nvarchar(max)") + .HasColumnName("AddressPersistentLocalIds"); + + b.Property("AddressesAsString") + .HasColumnType("nvarchar(max)") + .HasColumnName("AddressIds"); + + b.Property("Application") + .HasColumnType("int"); + + b.Property("CaPaKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ChangeType") + .HasColumnType("nvarchar(max)"); + + b.Property("EventDataAsXml") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtendedWkbGeometry") + .HasColumnType("varbinary(max)"); + + b.Property("LastChangedOnAsDateTimeOffset") + .HasColumnType("datetimeoffset") + .HasColumnName("LastChangedOn"); + + b.Property("Modification") + .HasColumnType("int"); + + b.Property("Operator") + .HasColumnType("nvarchar(max)"); + + b.Property("Organisation") + .HasColumnType("int"); + + b.Property("ParcelId") + .IsRequired() + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasColumnType("nvarchar(max)"); + + b.Property("RecordCreatedAtAsDateTimeOffset") + .HasColumnType("datetimeoffset") + .HasColumnName("RecordCreatedAt"); + + b.Property("StatusAsString") + .HasColumnType("nvarchar(max)") + .HasColumnName("Status"); + + b.Property("SyndicationItemCreatedAt") + .HasColumnType("datetimeoffset"); + + b.HasKey("Position"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Position")); + + b.HasIndex("ParcelId"); + + b.HasIndex("Position") + .HasDatabaseName("CI_ParcelSyndication_Position") + .HasAnnotation("SqlServer:ColumnStoreIndex", ""); + + b.ToTable("ParcelSyndication", "ParcelRegistryLegacy"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetailAddress", b => + { + b.HasOne("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetail", null) + .WithMany("Addresses") + .HasForeignKey("ParcelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetail", b => + { + b.Navigation("Addresses"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.cs b/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.cs new file mode 100644 index 00000000..29c9a1e9 --- /dev/null +++ b/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.cs @@ -0,0 +1,273 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ParcelRegistry.Projections.Legacy.Migrations +{ + using ParcelDetail; + + /// + public partial class DeleteOldRenameV2WithCount : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql($@"DROP VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}]"); + + migrationBuilder.DropTable( + name: "ParcelAddressesV2", + schema: "ParcelRegistryLegacy"); + + migrationBuilder.DropTable( + name: "ParcelDetailsV2", + schema: "ParcelRegistryLegacy"); + + migrationBuilder.DropForeignKey( + name: "FK_ParcelAddressesWithCountV2_ParcelDetailsWithCountV2_ParcelId", + schema: "ParcelRegistryLegacy", + table: "ParcelAddressesWithCountV2"); + + migrationBuilder.DropUniqueConstraint( + name:"AK_ParcelDetailsWithCountV2_CaPaKey", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailsWithCountV2"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ParcelAddressesWithCountV2", + schema: "ParcelRegistryLegacy", + table: "ParcelAddressesWithCountV2"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ParcelDetailsWithCountV2", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailsWithCountV2"); + + migrationBuilder.RenameTable( + name: "ParcelDetailsWithCountV2", + schema: "ParcelRegistryLegacy", + newName:"ParcelDetails", + newSchema:"ParcelRegistryLegacy"); + + migrationBuilder.RenameTable( + name: "ParcelAddressesWithCountV2", + schema: "ParcelRegistryLegacy", + newName:"ParcelDetailAddresses", + newSchema:"ParcelRegistryLegacy"); + + migrationBuilder.AddPrimaryKey( + name: "PK_ParcelAddresses", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailAddresses", + columns: new[] { "ParcelId", "AddressPersistentLocalId" }) + .Annotation("SqlServer:Clustered", true); + + migrationBuilder.AddPrimaryKey( + name: "PK_ParcelDetails", + schema: "ParcelRegistryLegacy", + table: "ParcelDetails", + columns: new[] { "ParcelId" }) + .Annotation("SqlServer:Clustered", false); + + migrationBuilder.AddUniqueConstraint( + name:"AK_ParcelDetails_CaPaKey", + schema:"ParcelRegistryLegacy", + table:"ParcelDetails", + column:"CaPaKey"); + + migrationBuilder.AddForeignKey( + name: "FK_ParcelDetailAddresses_ParcelDetails_ParcelId", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailAddresses", + column: "ParcelId", + principalSchema: "ParcelRegistryLegacy", + principalTable: "ParcelDetails", + principalColumn: "ParcelId", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.RenameIndex( + name: "IX_ParcelAddressesWithCountV2_AddressPersistentLocalId", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailAddresses", + newName: "IX_ParcelDetailAddresses_AddressPersistentLocalId"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelDetailsWithCountV2_CaPaKey", + schema: "ParcelRegistryLegacy", + table: "ParcelDetails", + newName: "IX_ParcelDetails_CaPaKey"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelDetailsWithCountV2_Removed", + schema: "ParcelRegistryLegacy", + table: "ParcelDetails", + newName: "IX_ParcelDetails_Removed"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelDetailsWithCountV2_Status", + schema: "ParcelRegistryLegacy", + table: "ParcelDetails", + newName: "IX_ParcelDetails_Status"); + + migrationBuilder.Sql($@" +CREATE VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] +WITH SCHEMABINDING +AS +SELECT COUNT_BIG(*) as Count +FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailConfiguration.TableName}] +WHERE [Removed] = 0"); + + migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql($@"DROP VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}]"); + + migrationBuilder.CreateTable( + name: "ParcelDetailsV2", + schema: "ParcelRegistryLegacy", + columns: table => new + { + ParcelId = table.Column(type: "uniqueidentifier", nullable: false), + CaPaKey = table.Column(type: "nvarchar(450)", nullable: false), + Gml = table.Column(type: "nvarchar(max)", nullable: false), + GmlType = table.Column(type: "nvarchar(max)", nullable: false), + LastEventHash = table.Column(type: "nvarchar(max)", nullable: false), + Removed = table.Column(type: "bit", nullable: false), + Status = table.Column(type: "nvarchar(450)", maxLength: 450, nullable: false), + VersionTimestamp = table.Column(type: "datetimeoffset", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ParcelDetailsV2", x => x.ParcelId) + .Annotation("SqlServer:Clustered", false); + table.UniqueConstraint("AK_ParcelDetailsV2_CaPaKey", x => x.CaPaKey); + }); + + migrationBuilder.CreateTable( + name: "ParcelAddressesV2", + schema: "ParcelRegistryLegacy", + columns: table => new + { + ParcelId = table.Column(type: "uniqueidentifier", nullable: false), + AddressPersistentLocalId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ParcelAddressesV2", x => new { x.ParcelId, x.AddressPersistentLocalId }) + .Annotation("SqlServer:Clustered", true); + table.ForeignKey( + name: "FK_ParcelAddressesV2_ParcelDetailsV2_ParcelId", + column: x => x.ParcelId, + principalSchema: "ParcelRegistryLegacy", + principalTable: "ParcelDetailsV2", + principalColumn: "ParcelId", + onDelete: ReferentialAction.Cascade); + }); + + // Rename indexes back to original names + migrationBuilder.RenameIndex( + name: "IX_ParcelDetails_Status", + schema: "ParcelRegistryLegacy", + table: "ParcelDetails", + newName: "IX_ParcelDetailsWithCountV2_Status"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelDetails_Removed", + schema: "ParcelRegistryLegacy", + table: "ParcelDetails", + newName: "IX_ParcelDetailsWithCountV2_Removed"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelDetails_CaPaKey", + schema: "ParcelRegistryLegacy", + table: "ParcelDetails", + newName: "IX_ParcelDetailsWithCountV2_CaPaKey"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelDetailAddresses_AddressPersistentLocalId", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailAddresses", + newName: "IX_ParcelAddressesWithCountV2_AddressPersistentLocalId"); + + // Drop foreign key, unique constraint, and primary keys + migrationBuilder.DropForeignKey( + name: "FK_ParcelDetailAddresses_ParcelDetails_ParcelId", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailAddresses"); + + migrationBuilder.DropUniqueConstraint( + name:"AK_ParcelDetails_CaPaKey", + schema:"ParcelRegistryLegacy", + table:"ParcelDetails"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ParcelDetails", + schema: "ParcelRegistryLegacy", + table: "ParcelDetails"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ParcelAddresses", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailAddresses"); + + // Rename tables back to original names + migrationBuilder.RenameTable( + name: "ParcelDetailAddresses", + schema: "ParcelRegistryLegacy", + newName: "ParcelAddressesWithCountV2", + newSchema: "ParcelRegistryLegacy"); + + migrationBuilder.RenameTable( + name: "ParcelDetails", + schema: "ParcelRegistryLegacy", + newName: "ParcelDetailsWithCountV2", + newSchema: "ParcelRegistryLegacy"); + + // Add back the primary keys + migrationBuilder.AddPrimaryKey( + name: "PK_ParcelDetailsWithCountV2", + schema: "ParcelRegistryLegacy", + table: "ParcelDetailsWithCountV2", + column: "ParcelId") + .Annotation("SqlServer:Clustered", false); + + migrationBuilder.AddPrimaryKey( + name: "PK_ParcelAddressesWithCountV2", + schema: "ParcelRegistryLegacy", + table: "ParcelAddressesWithCountV2", + columns: new[] { "ParcelId", "AddressPersistentLocalId" }) + .Annotation("SqlServer:Clustered", true); + + // Add back the unique constraint + migrationBuilder.AddUniqueConstraint( + name:"AK_ParcelDetailsWithCountV2_CaPaKey", + schema:"ParcelRegistryLegacy", + table:"ParcelDetailsWithCountV2", + column:"CaPaKey"); + + // Add back the foreign key + migrationBuilder.AddForeignKey( + name: "FK_ParcelAddressesWithCountV2_ParcelDetailsWithCountV2_ParcelId", + schema: "ParcelRegistryLegacy", + table: "ParcelAddressesWithCountV2", + column: "ParcelId", + principalSchema: "ParcelRegistryLegacy", + principalTable: "ParcelDetailsWithCountV2", + principalColumn: "ParcelId", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.Sql($@" +CREATE VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] +WITH SCHEMABINDING +AS +SELECT COUNT_BIG(*) as Count +FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailConfiguration.TableName}] +WHERE [Removed] = 0"); + + migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); + } + } +} diff --git a/src/ParcelRegistry.Projections.Legacy/Migrations/LegacyContextModelSnapshot.cs b/src/ParcelRegistry.Projections.Legacy/Migrations/LegacyContextModelSnapshot.cs index 2440de3f..107946a2 100644 --- a/src/ParcelRegistry.Projections.Legacy/Migrations/LegacyContextModelSnapshot.cs +++ b/src/ParcelRegistry.Projections.Legacy/Migrations/LegacyContextModelSnapshot.cs @@ -44,24 +44,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ProjectionStates", "ParcelRegistryLegacy"); }); - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailV2.ParcelDetailAddressV2", b => - { - b.Property("ParcelId") - .HasColumnType("uniqueidentifier"); - - b.Property("AddressPersistentLocalId") - .HasColumnType("int"); - - b.HasKey("ParcelId", "AddressPersistentLocalId"); - - SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("ParcelId", "AddressPersistentLocalId")); - - b.HasIndex("AddressPersistentLocalId"); - - b.ToTable("ParcelAddressesV2", "ParcelRegistryLegacy"); - }); - - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailV2.ParcelDetailV2", b => + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetail", b => { b.Property("ParcelId") .ValueGeneratedOnAdd() @@ -112,20 +95,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("StatusAsString"); - b.ToTable("ParcelDetailsV2", "ParcelRegistryLegacy"); + b.ToTable("ParcelDetails", "ParcelRegistryLegacy"); }); - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailV2.ParcelDetailV2ListViewCount", b => - { - b.Property("Count") - .HasColumnType("bigint"); - - b.ToTable((string)null); - - b.ToView("vw_ParcelDetailV2ListCount", "ParcelRegistryLegacy"); - }); - - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2.ParcelDetailAddressV2", b => + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetailAddress", b => { b.Property("ParcelId") .HasColumnType("uniqueidentifier"); @@ -144,61 +117,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("AddressPersistentLocalId"); - b.ToTable("ParcelAddressesWithCountV2", "ParcelRegistryLegacy"); + b.ToTable("ParcelDetailAddresses", "ParcelRegistryLegacy"); }); - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2.ParcelDetailV2", b => + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailV2ListViewCount", b => { - b.Property("ParcelId") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CaPaKey") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.Property("Gml") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("GmlType") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("LastEventHash") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Removed") - .HasColumnType("bit"); - - b.Property("StatusAsString") - .IsRequired() - .HasMaxLength(450) - .HasColumnType("nvarchar(450)") - .HasColumnName("Status"); - - b.Property("VersionTimestampAsDateTimeOffset") - .HasColumnType("datetimeoffset") - .HasColumnName("VersionTimestamp"); - - b.HasKey("ParcelId"); - - SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("ParcelId"), false); - - b.HasAlternateKey("CaPaKey"); - - b.HasIndex("CaPaKey"); - - SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CaPaKey")); - - b.HasIndex("Removed"); - - SqlServerIndexBuilderExtensions.IncludeProperties(b.HasIndex("Removed"), new[] { "CaPaKey", "StatusAsString", "VersionTimestampAsDateTimeOffset" }); + b.Property("Count") + .HasColumnType("bigint"); - b.HasIndex("StatusAsString"); + b.ToTable((string)null); - b.ToTable("ParcelDetailsWithCountV2", "ParcelRegistryLegacy"); + b.ToView("vw_ParcelDetailV2ListCount", "ParcelRegistryLegacy"); }); modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelSyndication.ParcelSyndicationItem", b => @@ -273,30 +202,16 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ParcelSyndication", "ParcelRegistryLegacy"); }); - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailV2.ParcelDetailAddressV2", b => + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetailAddress", b => { - b.HasOne("ParcelRegistry.Projections.Legacy.ParcelDetailV2.ParcelDetailV2", null) + b.HasOne("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetail", null) .WithMany("Addresses") .HasForeignKey("ParcelId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2.ParcelDetailAddressV2", b => - { - b.HasOne("ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2.ParcelDetailV2", null) - .WithMany("Addresses") - .HasForeignKey("ParcelId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailV2.ParcelDetailV2", b => - { - b.Navigation("Addresses"); - }); - - modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2.ParcelDetailV2", b => + modelBuilder.Entity("ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetail", b => { b.Navigation("Addresses"); }); diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetail.cs similarity index 81% rename from src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2.cs rename to src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetail.cs index b0a1470d..a8162fe7 100644 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2.cs +++ b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetail.cs @@ -1,4 +1,4 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2 +namespace ParcelRegistry.Projections.Legacy.ParcelDetail { using System; using System.Collections.Generic; @@ -9,18 +9,18 @@ namespace ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2 using NodaTime; using Parcel; - public class ParcelDetailV2 + public class ParcelDetail { - private ParcelDetailV2() + private ParcelDetail() { - Addresses = new List(); + Addresses = new List(); } - public ParcelDetailV2( + public ParcelDetail( Guid parcelId, string caPaKey, ParcelStatus status, - IEnumerable addresses, + IEnumerable addresses, string gml, string gmlType, bool removed, @@ -50,7 +50,7 @@ public ParcelStatus Status public string GmlType { get; set; } - public virtual List Addresses { get; set; } + public virtual List Addresses { get; set; } public bool Removed { get; set; } public string LastEventHash { get; set; } = string.Empty; @@ -63,12 +63,12 @@ public Instant VersionTimestamp } } - public class ParcelDetailV2Configuration : IEntityTypeConfiguration + public class ParcelDetailConfiguration : IEntityTypeConfiguration { - internal const string TableName = "ParcelDetailsWithCountV2"; - public static readonly string ProjectionStateName = typeof(ParcelDetailV2Projections).FullName!; + internal const string TableName = "ParcelDetails"; + public static readonly string ProjectionStateName = typeof(ParcelDetailProjections).FullName!; - public void Configure(EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { builder.ToTable(TableName, Schema.Legacy) .HasKey(p => p.ParcelId) diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailAddressV2.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailAddress.cs similarity index 70% rename from src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailAddressV2.cs rename to src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailAddress.cs index 2baba668..cbb54f8d 100644 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailAddressV2.cs +++ b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailAddress.cs @@ -1,16 +1,16 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2 +namespace ParcelRegistry.Projections.Legacy.ParcelDetail { using System; - using Infrastructure; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; + using ParcelRegistry.Infrastructure; - public class ParcelDetailAddressV2 + public class ParcelDetailAddress { - private ParcelDetailAddressV2() + private ParcelDetailAddress() { } - public ParcelDetailAddressV2(Guid parcelId, int persistentLocalId) + public ParcelDetailAddress(Guid parcelId, int persistentLocalId) { ParcelId = parcelId; AddressPersistentLocalId = persistentLocalId; @@ -22,11 +22,11 @@ public ParcelDetailAddressV2(Guid parcelId, int persistentLocalId) public int Count { get; set; } } - public class ParcelDetailAddressV2Configuration : IEntityTypeConfiguration + public class ParcelDetailAddressV2Configuration : IEntityTypeConfiguration { - private const string TableName = "ParcelAddressesWithCountV2"; + private const string TableName = "ParcelDetailAddresses"; - public void Configure(EntityTypeBuilder b) + public void Configure(EntityTypeBuilder b) { b.ToTable(TableName, Schema.Legacy) .HasKey(p => new { p.ParcelId, p.AddressPersistentLocalId }) diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2Extensions.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailExtensions.cs similarity index 61% rename from src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2Extensions.cs rename to src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailExtensions.cs index bf42ec51..f629af3f 100644 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2Extensions.cs +++ b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailExtensions.cs @@ -1,16 +1,16 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2 +namespace ParcelRegistry.Projections.Legacy.ParcelDetail { using System; using System.Threading; using System.Threading.Tasks; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; - public static class ParcelDetailV2Extensions + public static class ParcelDetailExtensions { - public static async Task FindAndUpdateParcelDetail( + public static async Task FindAndUpdateParcelDetail( this LegacyContext context, Guid parcelId, - Action updateFunc, + Action updateFunc, CancellationToken ct) { var parcel = await context @@ -24,7 +24,7 @@ public static async Task FindAndUpdateParcelDetail( return parcel; } - private static ProjectionItemNotFoundException DatabaseItemNotFound(Guid parcelId) - => new ProjectionItemNotFoundException(parcelId.ToString("D")); + private static ProjectionItemNotFoundException DatabaseItemNotFound(Guid parcelId) + => new ProjectionItemNotFoundException(parcelId.ToString("D")); } } diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2Projections.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailProjections.cs similarity index 94% rename from src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2Projections.cs rename to src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailProjections.cs index d16c4a2d..a817dd14 100644 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailWithCountV2/ParcelDetailV2Projections.cs +++ b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailProjections.cs @@ -1,4 +1,4 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2 +namespace ParcelRegistry.Projections.Legacy.ParcelDetail { using System; using System.Collections.Generic; @@ -17,7 +17,7 @@ namespace ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2 [ConnectedProjectionName("API endpoint detail/lijst percelen")] [ConnectedProjectionDescription("Projectie die de percelen data voor het percelen detail & lijst voorziet.")] - public class ParcelDetailV2Projections : ConnectedProjection + public class ParcelDetailProjections : ConnectedProjection { private string MapGeometryType(OgcGeometryType ogcGeometryType) { @@ -30,7 +30,7 @@ private string MapGeometryType(OgcGeometryType ogcGeometryType) }; } - public ParcelDetailV2Projections() + public ParcelDetailProjections() { var wkbReader = WKBReaderFactory.Create(); @@ -45,11 +45,11 @@ public ParcelDetailV2Projections() { var (geometryType, gml) = ToGml(message.Message.ExtendedWkbGeometry); - var item = new ParcelDetailV2( + var item = new ParcelDetail( message.Message.ParcelId, message.Message.CaPaKey, ParcelStatus.Parse(message.Message.ParcelStatus), - message.Message.AddressPersistentLocalIds.Select(x => new ParcelDetailAddressV2(message.Message.ParcelId, x)), + message.Message.AddressPersistentLocalIds.Select(x => new ParcelDetailAddress(message.Message.ParcelId, x)), gml, geometryType, message.Message.IsRemoved, @@ -74,7 +74,7 @@ await context.FindAndUpdateParcelDetail( parcelAddress.AddressPersistentLocalId == message.Message.AddressPersistentLocalId && parcelAddress.ParcelId == message.Message.ParcelId)) { - entity.Addresses.Add(new ParcelDetailAddressV2(message.Message.ParcelId, message.Message.AddressPersistentLocalId)); + entity.Addresses.Add(new ParcelDetailAddress(message.Message.ParcelId, message.Message.AddressPersistentLocalId)); } UpdateHash(entity, message); @@ -198,7 +198,7 @@ await context.FindAndUpdateParcelDetail( if (newAddress is null) { - entity.Addresses.Add(new ParcelDetailAddressV2(message.Message.ParcelId, message.Message.NewAddressPersistentLocalId)); + entity.Addresses.Add(new ParcelDetailAddress(message.Message.ParcelId, message.Message.NewAddressPersistentLocalId)); } else { @@ -240,7 +240,7 @@ await context.FindAndUpdateParcelDetail( if (relation is null) { - entity.Addresses.Add(new ParcelDetailAddressV2(message.Message.ParcelId, addressPersistentLocalId)); + entity.Addresses.Add(new ParcelDetailAddress(message.Message.ParcelId, addressPersistentLocalId)); } } @@ -254,11 +254,11 @@ await context.FindAndUpdateParcelDetail( { var (geometryType, gml) = ToGml(message.Message.ExtendedWkbGeometry); - var item = new ParcelDetailV2( + var item = new ParcelDetail( message.Message.ParcelId, message.Message.CaPaKey, ParcelStatus.Realized, - new List(), + new List(), gml, geometryType, false, @@ -320,7 +320,7 @@ await context.FindAndUpdateParcelDetail( }); } - private static void UpdateHash(ParcelDetailV2 entity, Envelope wrappedEvent) where T : IHaveHash, IMessage + private static void UpdateHash(ParcelDetail entity, Envelope wrappedEvent) where T : IHaveHash, IMessage { if (!wrappedEvent.Metadata.ContainsKey(AddEventHashPipe.HashMetadataKey)) { @@ -330,7 +330,7 @@ private static void UpdateHash(ParcelDetailV2 entity, Envelope wrappedEven entity.LastEventHash = wrappedEvent.Metadata[AddEventHashPipe.HashMetadataKey].ToString()!; } - private static void UpdateVersionTimestamp(ParcelDetailV2 item, Instant versionTimestamp) + private static void UpdateVersionTimestamp(ParcelDetail item, Instant versionTimestamp) => item.VersionTimestamp = versionTimestamp; } } diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailAddressV2.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailAddressV2.cs deleted file mode 100644 index 75c8e74e..00000000 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailAddressV2.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailV2 -{ - using System; - using Infrastructure; - using Microsoft.EntityFrameworkCore; - using Microsoft.EntityFrameworkCore.Metadata.Builders; - - public class ParcelDetailAddressV2 - { - private ParcelDetailAddressV2() - { } - - public ParcelDetailAddressV2(Guid parcelId, int persistentLocalId) - { - ParcelId = parcelId; - AddressPersistentLocalId = persistentLocalId; - } - - public Guid ParcelId { get; set; } - public int AddressPersistentLocalId { get; set; } - } - - public class ParcelDetailAddressV2Configuration : IEntityTypeConfiguration - { - private const string TableName = "ParcelAddressesV2"; - - public void Configure(EntityTypeBuilder b) - { - b.ToTable(TableName, Schema.Legacy) - .HasKey(p => new { p.ParcelId, p.AddressPersistentLocalId }) - .IsClustered(); - - b.HasIndex(x => x.AddressPersistentLocalId); - } - } -} diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2.cs deleted file mode 100644 index b396d2fd..00000000 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2.cs +++ /dev/null @@ -1,103 +0,0 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailV2 -{ - using System; - using System.Collections.Generic; - using System.Linq; - using Infrastructure; - using Microsoft.EntityFrameworkCore; - using Microsoft.EntityFrameworkCore.Metadata.Builders; - using NodaTime; - using Parcel; - - public class ParcelDetailV2 - { - private ParcelDetailV2() - { - Addresses = new List(); - } - - public ParcelDetailV2( - Guid parcelId, - string caPaKey, - ParcelStatus status, - IEnumerable addresses, - string gml, - string gmlType, - bool removed, - Instant versionTimeStamp) - { - ParcelId = parcelId; - CaPaKey = caPaKey; - Status = status; - Addresses = addresses.ToList(); - Gml = gml; - GmlType = gmlType; - Removed = removed; - VersionTimestamp = versionTimeStamp; - } - - public Guid ParcelId { get; set; } - public string CaPaKey { get; set; } - public ParcelStatus Status - { - get => ParcelStatus.Parse(StatusAsString); - set => StatusAsString = value.Status; - } - - public string StatusAsString { get; private set; } - - public string Gml { get; set; } - - public string GmlType { get; set; } - - public virtual List Addresses { get; set; } - - public bool Removed { get; set; } - public string LastEventHash { get; set; } = string.Empty; - public DateTimeOffset VersionTimestampAsDateTimeOffset { get; private set; } - - public Instant VersionTimestamp - { - get => Instant.FromDateTimeOffset(VersionTimestampAsDateTimeOffset); - set => VersionTimestampAsDateTimeOffset = value.ToDateTimeOffset(); - } - } - - public class ParcelDetailV2Configuration : IEntityTypeConfiguration - { - internal const string TableName = "ParcelDetailsV2"; - - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable(TableName, Schema.Legacy) - .HasKey(p => p.ParcelId) - .IsClustered(false); - - builder.Ignore(x => x.Status); - - builder.Property(p => p.Gml); - builder.Property(p => p.GmlType); - - builder.Property(p => p.CaPaKey); - builder.Property(x => x.StatusAsString).HasMaxLength(450) - .HasColumnName("Status"); - - builder.Property(p => p.Removed); - builder.Property(x => x.LastEventHash); - - builder.Property(p => p.VersionTimestampAsDateTimeOffset) - .HasColumnName("VersionTimestamp"); - builder.Ignore(x => x.VersionTimestamp); - - builder.HasMany(x => x.Addresses).WithOne() - .HasForeignKey(x => x.ParcelId); - - builder.HasIndex(x => x.CaPaKey).IsClustered(); - builder.HasAlternateKey(x => x.CaPaKey); - - builder.HasIndex(x => x.Removed) - .IncludeProperties(x => new { x.CaPaKey, x.StatusAsString, x.VersionTimestampAsDateTimeOffset }); - builder.HasIndex(x => x.StatusAsString); - } - } -} diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2Extensions.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2Extensions.cs deleted file mode 100644 index 83e04ee5..00000000 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2Extensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailV2 -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; - - public static class ParcelDetailV2Extensions - { - public static async Task FindAndUpdateParcelDetail( - this LegacyContext context, - Guid parcelId, - Action updateFunc, - CancellationToken ct) - { - var parcel = await context - .ParcelDetailV2 - .FindAsync(parcelId, cancellationToken: ct); - - if (parcel == null) - throw DatabaseItemNotFound(parcelId); - - updateFunc(parcel); - return parcel; - } - - private static ProjectionItemNotFoundException DatabaseItemNotFound(Guid parcelId) - => new ProjectionItemNotFoundException(parcelId.ToString("D")); - } -} diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2ListViewCount.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2ListViewCount.cs deleted file mode 100644 index b533e1ab..00000000 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2ListViewCount.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailV2 -{ - public class ParcelDetailV2ListViewCount - { - public long Count { get; set; } - } -} diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2Projections.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2Projections.cs deleted file mode 100644 index 85ea4efa..00000000 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetailV2/ParcelDetailV2Projections.cs +++ /dev/null @@ -1,287 +0,0 @@ -namespace ParcelRegistry.Projections.Legacy.ParcelDetailV2 -{ - using System; - using System.Collections.Generic; - using System.Linq; - using Be.Vlaanderen.Basisregisters.EventHandling; - using Be.Vlaanderen.Basisregisters.GrAr.Common; - using Be.Vlaanderen.Basisregisters.GrAr.Common.NetTopology; - using Be.Vlaanderen.Basisregisters.GrAr.Common.Pipes; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore; - using Be.Vlaanderen.Basisregisters.Utilities.HexByteConvertor; - using NetTopologySuite.Geometries; - using NetTopologySuite.IO; - using NodaTime; - using Parcel; - using Parcel.Events; - - [ConnectedProjectionName("API endpoint detail/lijst percelen")] - [ConnectedProjectionDescription("Projectie die de percelen data voor het percelen detail & lijst voorziet.")] - public class ParcelDetailV2Projections : ConnectedProjection - { - private string MapGeometryType(OgcGeometryType ogcGeometryType) - { - return ogcGeometryType switch - { - OgcGeometryType.Polygon => OgcGeometryType.Polygon.ToString(), - OgcGeometryType.MultiSurface => OgcGeometryType.MultiSurface.ToString(), - OgcGeometryType.MultiPolygon => OgcGeometryType.MultiSurface.ToString(), - _ => throw new ArgumentOutOfRangeException(nameof(ogcGeometryType), ogcGeometryType, null) - }; - } - - public ParcelDetailV2Projections() - { - var wkbReader = WKBReaderFactory.Create(); - - (string gmlType, string gml) ToGml(string extendedWkbGeometry) - { - var geometry = wkbReader.Read(extendedWkbGeometry.ToByteArray()); - var gml = geometry.ConvertToGml(); - return (MapGeometryType(geometry.OgcGeometryType), gml); - } - - When>(async (context, message, ct) => - { - var (geometryType, gml) = ToGml(message.Message.ExtendedWkbGeometry); - - var item = new ParcelDetailV2( - message.Message.ParcelId, - message.Message.CaPaKey, - ParcelStatus.Parse(message.Message.ParcelStatus), - message.Message.AddressPersistentLocalIds.Select(x => new ParcelDetailAddressV2(message.Message.ParcelId, x)), - gml, - geometryType, - message.Message.IsRemoved, - message.Message.Provenance.Timestamp); - - UpdateHash(item, message); - - await context - .ParcelDetailV2 - .AddAsync(item, ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - context.Entry(entity).Collection(x => x.Addresses).Load(); - - if (!entity.Addresses.Any(parcelAddress => - parcelAddress.AddressPersistentLocalId == message.Message.AddressPersistentLocalId - && parcelAddress.ParcelId == message.Message.ParcelId)) - { - entity.Addresses.Add(new ParcelDetailAddressV2(message.Message.ParcelId, message.Message.AddressPersistentLocalId)); - } - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - context.Entry(entity).Collection(x => x.Addresses).Load(); - - var addressToRemove = entity.Addresses.SingleOrDefault(parcelAddress => - parcelAddress.AddressPersistentLocalId == message.Message.AddressPersistentLocalId - && parcelAddress.ParcelId == message.Message.ParcelId); - if (addressToRemove is not null) - { - entity.Addresses.Remove(addressToRemove); - } - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - context.Entry(entity).Collection(x => x.Addresses).Load(); - - var addressToRemove = entity.Addresses.SingleOrDefault(parcelAddress => - parcelAddress.AddressPersistentLocalId == message.Message.AddressPersistentLocalId - && parcelAddress.ParcelId == message.Message.ParcelId); - if (addressToRemove is not null) - { - entity.Addresses.Remove(addressToRemove); - } - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - context.Entry(entity).Collection(x => x.Addresses).Load(); - - var addressToRemove = entity.Addresses.SingleOrDefault(parcelAddress => - parcelAddress.AddressPersistentLocalId == message.Message.AddressPersistentLocalId - && parcelAddress.ParcelId == message.Message.ParcelId); - if (addressToRemove is not null) - { - entity.Addresses.Remove(addressToRemove); - } - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - context.Entry(entity).Collection(x => x.Addresses).Load(); - - var addressToRemove = entity.Addresses.SingleOrDefault(parcelAddress => - parcelAddress.AddressPersistentLocalId == message.Message.AddressPersistentLocalId - && parcelAddress.ParcelId == message.Message.ParcelId); - if (addressToRemove is not null) - { - entity.Addresses.Remove(addressToRemove); - } - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - context.Entry(entity).Collection(x => x.Addresses).Load(); - - var addressToRemove = entity.Addresses.SingleOrDefault(parcelAddress => - parcelAddress.AddressPersistentLocalId == message.Message.PreviousAddressPersistentLocalId - && parcelAddress.ParcelId == message.Message.ParcelId); - if (addressToRemove is not null) - { - entity.Addresses.Remove(addressToRemove); - } - - if (!entity.Addresses.Any(parcelAddress => - parcelAddress.AddressPersistentLocalId == message.Message.NewAddressPersistentLocalId - && parcelAddress.ParcelId == message.Message.ParcelId)) - { - entity.Addresses.Add(new ParcelDetailAddressV2(message.Message.ParcelId, message.Message.NewAddressPersistentLocalId)); - } - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - - When>(async (context, message, ct) => - { - var (geometryType, gml) = ToGml(message.Message.ExtendedWkbGeometry); - - var item = new ParcelDetailV2( - message.Message.ParcelId, - message.Message.CaPaKey, - ParcelStatus.Realized, - new List(), - gml, - geometryType, - false, - message.Message.Provenance.Timestamp); - - UpdateHash(item, message); - - await context - .ParcelDetailV2 - .AddAsync(item, ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - entity.Status = ParcelStatus.Retired; - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - var geometry = wkbReader.Read(message.Message.ExtendedWkbGeometry.ToByteArray()); - entity.Gml = geometry.ConvertToGml(); - entity.GmlType = geometry.OgcGeometryType.ToString(); - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - - When>(async (context, message, ct) => - { - await context.FindAndUpdateParcelDetail( - message.Message.ParcelId, - entity => - { - var geometry = wkbReader.Read(message.Message.ExtendedWkbGeometry.ToByteArray()); - entity.Gml = geometry.ConvertToGml(); - entity.GmlType = geometry.OgcGeometryType.ToString(); - - entity.Status = ParcelStatus.Realized; - - UpdateHash(entity, message); - UpdateVersionTimestamp(entity, message.Message.Provenance.Timestamp); - }, - ct); - }); - } - - private static void UpdateHash(ParcelDetailV2 entity, Envelope wrappedEvent) where T : IHaveHash, IMessage - { - if (!wrappedEvent.Metadata.ContainsKey(AddEventHashPipe.HashMetadataKey)) - { - throw new InvalidOperationException($"Cannot find hash in metadata for event at position {wrappedEvent.Position}"); - } - - entity.LastEventHash = wrappedEvent.Metadata[AddEventHashPipe.HashMetadataKey].ToString()!; - } - - private static void UpdateVersionTimestamp(ParcelDetailV2 item, Instant versionTimestamp) - => item.VersionTimestamp = versionTimestamp; - } -} diff --git a/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs b/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs index f87ea993..eadc5a3e 100644 --- a/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs +++ b/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs @@ -24,9 +24,8 @@ namespace ParcelRegistry.Projector.Infrastructure.Modules using ParcelRegistry.Projections.Integration.ParcelVersion; using ParcelRegistry.Projections.LastChangedList; using ParcelRegistry.Projections.Legacy; - using ParcelRegistry.Projections.Legacy.ParcelDetailV2; + using ParcelRegistry.Projections.Legacy.ParcelDetail; using ParcelRegistry.Projections.Legacy.ParcelSyndication; - using ParcelDetailWithCountV2Projections = ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2.ParcelDetailV2Projections; using ParcelLinkExtractWithCountProjections = ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount.ParcelLinkExtractProjections; public class ApiModule : Module @@ -53,10 +52,6 @@ protected override void Load(ContainerBuilder builder) .RegisterType() .AsSelf(); - builder.Register(c => new CacheValidator(c.Resolve(), typeof(ParcelDetailV2Projections).FullName!)) - .AsSelf() - .AsImplementedInterfaces(); - builder.Populate(_services); } @@ -102,7 +97,7 @@ private void RegisterExtractV2Projections(ContainerBuilder builder) DbaseCodePage.Western_European_ANSI.ToEncoding()), ConnectedProjectionSettings.Default) .RegisterProjections( - context => new ParcelLinkExtractWithCountProjections(DbaseCodePage.Western_European_ANSI.ToEncoding()), + _ => new ParcelLinkExtractWithCountProjections(DbaseCodePage.Western_European_ANSI.ToEncoding()), ConnectedProjectionSettings.Default); } @@ -127,8 +122,7 @@ private void RegisterLegacyV2Projections(ContainerBuilder builder) .RegisterProjectionMigrator( _configuration, _loggerFactory) - .RegisterProjections(ConnectedProjectionSettings.Default) - .RegisterProjections(ConnectedProjectionSettings.Default) + .RegisterProjections(ConnectedProjectionSettings.Default) .RegisterProjections(ConnectedProjectionSettings.Default); } diff --git a/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests.cs b/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests.cs index 321a9eef..407169df 100644 --- a/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests.cs +++ b/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests.cs @@ -17,10 +17,10 @@ namespace ParcelRegistry.Tests.ProjectionTests.Legacy using FluentAssertions; using Parcel; using Parcel.Events; - using Projections.Legacy.ParcelDetailWithCountV2; + using Projections.Legacy.ParcelDetail; using Xunit; - public partial class ParcelDetailItemV2Tests : ParcelLegacyProjectionTest + public partial class ParcelDetailItemV2Tests : ParcelLegacyProjectionTest { private readonly Fixture _fixture; @@ -59,7 +59,7 @@ await Sut parcelDetailV2.GmlType.Should().Be("Polygon"); parcelDetailV2.Addresses.Should().BeEquivalentTo( message.AddressPersistentLocalIds.Select(x => - new ParcelDetailAddressV2(message.ParcelId, x))); + new ParcelDetailAddress(message.ParcelId, x))); parcelDetailV2.VersionTimestamp.Should().Be(message.Provenance.Timestamp); parcelDetailV2.LastEventHash.Should().Be(message.GetHash()); }); @@ -193,7 +193,7 @@ await Sut parcelDetailV2!.Addresses.Should().BeEquivalentTo( message.AddressPersistentLocalIds .Concat(new[] { addressWasAttached.AddressPersistentLocalId }) - .Select(x => new ParcelDetailAddressV2(addressWasAttached.ParcelId, x))); + .Select(x => new ParcelDetailAddress(addressWasAttached.ParcelId, x))); parcelDetailV2.VersionTimestamp.Should().Be(addressWasAttached.Provenance.Timestamp); parcelDetailV2.LastEventHash.Should().Be(addressWasAttached.GetHash()); }); @@ -243,7 +243,7 @@ private Envelope CreateEnvelope(TEvent @event) })); } - protected override ParcelDetailV2Projections CreateProjection() - => new ParcelDetailV2Projections(); + protected override ParcelDetailProjections CreateProjection() + => new ParcelDetailProjections(); } } From 22cde4c425f54bafb5ab9ddab8eedb0b395f0731 Mon Sep 17 00:00:00 2001 From: Arne Dumarey Date: Fri, 7 Jun 2024 17:02:54 +0200 Subject: [PATCH 2/6] feat(extract): cleanup old tables rename new --- .../ParcelRegistryExtractV2Builder.cs | 4 +- .../ParcelRegistryLinkExtractBuilder.cs | 2 +- .../ExtractContext.cs | 3 +- ...143051_DeleteOldLinksRenameNew.Designer.cs | 112 +++++++++++ .../20240607143051_DeleteOldLinksRenameNew.cs | 189 ++++++++++++++++++ .../Migrations/ExtractContextModelSnapshot.cs | 33 +-- .../{ParcelExtractV2.cs => ParcelExtract.cs} | 8 +- ...tensions.cs => ParcelExtractExtensions.cs} | 12 +- ...ections.cs => ParcelExtractProjections.cs} | 20 +- .../ParcelLinkExtract/ParcelLinkExtract.cs | 4 +- .../ParcelLinkExtractProjections.cs | 87 ++++++-- .../ParcelLinkDbaseRecord.cs | 27 --- .../ParcelLinkDbaseSchema.cs | 18 -- .../ParcelLinkExtract.cs | 37 ---- .../ParcelLinkExtractProjections.cs | 174 ---------------- .../output.sql | 43 ++++ .../Infrastructure/Modules/ApiModule.cs | 12 +- 17 files changed, 444 insertions(+), 341 deletions(-) create mode 100644 src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.Designer.cs create mode 100644 src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.cs rename src/ParcelRegistry.Projections.Extract/ParcelExtract/{ParcelExtractV2.cs => ParcelExtract.cs} (78%) rename src/ParcelRegistry.Projections.Extract/ParcelExtract/{ParcelExtractV2Extensions.cs => ParcelExtractExtensions.cs} (70%) rename src/ParcelRegistry.Projections.Extract/ParcelExtract/{ParcelExtractV2Projections.cs => ParcelExtractProjections.cs} (91%) delete mode 100644 src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkDbaseRecord.cs delete mode 100644 src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkDbaseSchema.cs delete mode 100644 src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkExtract.cs delete mode 100644 src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkExtractProjections.cs create mode 100644 src/ParcelRegistry.Projections.Extract/output.sql diff --git a/src/ParcelRegistry.Api.Extract/Extracts/ParcelRegistryExtractV2Builder.cs b/src/ParcelRegistry.Api.Extract/Extracts/ParcelRegistryExtractV2Builder.cs index d986fec4..db6f8de6 100644 --- a/src/ParcelRegistry.Api.Extract/Extracts/ParcelRegistryExtractV2Builder.cs +++ b/src/ParcelRegistry.Api.Extract/Extracts/ParcelRegistryExtractV2Builder.cs @@ -14,13 +14,13 @@ public static class ParcelRegistryExtractV2Builder public static IEnumerable CreateParcelFiles(ExtractContext context) { var extractItems = context - .ParcelExtractV2 + .ParcelExtract .AsNoTracking(); var parcelProjectionState = context .ProjectionStates .AsNoTracking() - .Single(m => m.Name == typeof(ParcelExtractV2Projections).FullName); + .Single(m => m.Name == typeof(ParcelExtractProjections).FullName); var extractMetadata = new Dictionary { { ExtractMetadataKeys.LatestEventId, parcelProjectionState.Position.ToString()} diff --git a/src/ParcelRegistry.Api.Extract/Extracts/ParcelRegistryLinkExtractBuilder.cs b/src/ParcelRegistry.Api.Extract/Extracts/ParcelRegistryLinkExtractBuilder.cs index bc96bb6f..27fea6e5 100644 --- a/src/ParcelRegistry.Api.Extract/Extracts/ParcelRegistryLinkExtractBuilder.cs +++ b/src/ParcelRegistry.Api.Extract/Extracts/ParcelRegistryLinkExtractBuilder.cs @@ -14,7 +14,7 @@ public class ParcelRegistryLinkExtractBuilder public static IEnumerable CreateParcelFiles(ExtractContext context) { var extractItems = context - .ParcelLinkExtractWithCount + .ParcelLinkExtract .AsNoTracking(); var parcelProjectionState = context diff --git a/src/ParcelRegistry.Projections.Extract/ExtractContext.cs b/src/ParcelRegistry.Projections.Extract/ExtractContext.cs index 97ead810..5d21a5df 100755 --- a/src/ParcelRegistry.Projections.Extract/ExtractContext.cs +++ b/src/ParcelRegistry.Projections.Extract/ExtractContext.cs @@ -10,9 +10,8 @@ public class ExtractContext : RunnerDbContext { public override string ProjectionStateSchema => Schema.Extract; - public DbSet ParcelExtractV2 { get; set; } + public DbSet ParcelExtract { get; set; } public DbSet ParcelLinkExtract { get; set; } - public DbSet ParcelLinkExtractWithCount { get; set; } // This needs to be here to please EF public ExtractContext() { } diff --git a/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.Designer.cs b/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.Designer.cs new file mode 100644 index 00000000..8c5aa97f --- /dev/null +++ b/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.Designer.cs @@ -0,0 +1,112 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ParcelRegistry.Projections.Extract; + +#nullable disable + +namespace ParcelRegistry.Projections.Extract.Migrations +{ + [DbContext(typeof(ExtractContext))] + [Migration("20240607143051_DeleteOldLinksRenameNew")] + partial class DeleteOldLinksRenameNew + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.ProjectionStates.ProjectionStateItem", b => + { + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("DesiredState") + .HasColumnType("nvarchar(max)"); + + b.Property("DesiredStateChangedAt") + .HasColumnType("datetimeoffset"); + + b.Property("ErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("Position") + .HasColumnType("bigint"); + + b.HasKey("Name"); + + b.ToTable("ProjectionStates", "ParcelRegistryExtract"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Extract.ParcelExtract.ParcelExtractItemV2", b => + { + b.Property("ParcelId") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CaPaKey") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("DbaseRecord") + .HasColumnType("varbinary(max)"); + + b.HasKey("ParcelId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("ParcelId"), false); + + b.HasIndex("CaPaKey"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CaPaKey")); + + b.ToTable("ParcelV2", "ParcelRegistryExtract"); + }); + + modelBuilder.Entity("ParcelRegistry.Projections.Extract.ParcelLinkExtract.ParcelLinkExtractItem", b => + { + b.Property("ParcelId") + .HasColumnType("uniqueidentifier"); + + b.Property("AddressPersistentLocalId") + .HasColumnType("int"); + + b.Property("CaPaKey") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Count") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(1); + + b.Property("DbaseRecord") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.HasKey("ParcelId", "AddressPersistentLocalId"); + + SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("ParcelId", "AddressPersistentLocalId"), false); + + b.HasIndex("AddressPersistentLocalId"); + + b.HasIndex("CaPaKey"); + + SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CaPaKey")); + + b.HasIndex("ParcelId"); + + b.ToTable("ParcelLinks", "ParcelRegistryExtract"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.cs b/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.cs new file mode 100644 index 00000000..d578b7f4 --- /dev/null +++ b/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.cs @@ -0,0 +1,189 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ParcelRegistry.Projections.Extract.Migrations +{ + /// + public partial class DeleteOldLinksRenameNew : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ParcelLinks", + schema: "ParcelRegistryExtract"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ParcelLinksWithCount", + schema: "ParcelRegistryExtract", + table: "ParcelLinksWithCount"); + + migrationBuilder.RenameTable( + name:"ParcelLinksWithCount", + schema: "ParcelRegistryExtract", + newName: "ParcelLinks", + newSchema: "ParcelRegistryExtract"); + + migrationBuilder.AddPrimaryKey( + name:"PK_ParcelLinks", + schema:"ParcelRegistryExtract", + table:"ParcelLinks", + columns: new[] { "ParcelId", "AddressPersistentLocalId" }) + .Annotation("SqlServer:Clustered", false); + + migrationBuilder.RenameIndex( + name: "IX_ParcelLinksWithCount_CaPaKey", + newName: "IX_ParcelLinks_CaPaKey", + schema: "ParcelRegistryExtract", + table: "ParcelLinks") + .Annotation("SqlServer:Clustered", true); + + migrationBuilder.RenameIndex( + name: "IX_ParcelLinksWithCount_AddressPersistentLocalId", + newName: "IX_ParcelLinks_AddressPersistentLocalId", + schema: "ParcelRegistryExtract", + table: "ParcelLinks"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelLinksWithCount_ParcelId", + newName: "IX_ParcelLinks_ParcelId", + schema: "ParcelRegistryExtract", + table: "ParcelLinks"); + + migrationBuilder.DropPrimaryKey( + name: "PK_ParcelV2", + table: "ParcelV2", + schema: "ParcelRegistryExtract"); + + migrationBuilder.RenameTable( + name: "ParcelV2", + schema: "ParcelRegistryExtract", + newName: "Parcels", + newSchema: "ParcelRegistryExtract"); + + migrationBuilder + .AddPrimaryKey( + name: "PK_Parcels", + schema: "ParcelRegistryExtract", + table: "Parcels", + column: "ParcelId") + .Annotation("SqlServer:Clustered", false); + + migrationBuilder.RenameIndex( + name:"IX_ParcelV2_CaPaKey", + newName: "IX_Parcels_CaPaKey", + schema: "ParcelRegistryExtract", + table: "Parcels"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + // Rename index back to original name + migrationBuilder.RenameIndex( + name: "IX_Parcels_CaPaKey", + newName: "IX_ParcelV2_CaPaKey", + schema: "ParcelRegistryExtract", + table: "Parcels"); + + // Drop primary key + migrationBuilder.DropPrimaryKey( + name: "PK_Parcels", + schema: "ParcelRegistryExtract", + table: "Parcels"); + + // Rename table back to original name + migrationBuilder.RenameTable( + name: "Parcels", + schema: "ParcelRegistryExtract", + newName: "ParcelV2", + newSchema: "ParcelRegistryExtract"); + + // Add back the primary key + migrationBuilder.AddPrimaryKey( + name: "PK_ParcelV2", + schema: "ParcelRegistryExtract", + table: "ParcelV2", + column: "ParcelId") + .Annotation("SqlServer:Clustered", false); + + // Rename indexes back to original names + migrationBuilder.RenameIndex( + name: "IX_ParcelLinks_ParcelId", + newName: "IX_ParcelLinksWithCount_ParcelId", + schema: "ParcelRegistryExtract", + table: "ParcelLinks"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelLinks_AddressPersistentLocalId", + newName: "IX_ParcelLinksWithCount_AddressPersistentLocalId", + schema: "ParcelRegistryExtract", + table: "ParcelLinks"); + + migrationBuilder.RenameIndex( + name: "IX_ParcelLinks_CaPaKey", + newName: "IX_ParcelLinksWithCount_CaPaKey", + schema: "ParcelRegistryExtract", + table: "ParcelLinks") + .Annotation("SqlServer:Clustered", true); + + // Drop primary key + migrationBuilder.DropPrimaryKey( + name: "PK_ParcelLinks", + schema: "ParcelRegistryExtract", + table: "ParcelLinks"); + + // Rename table back to original name + migrationBuilder.RenameTable( + name: "ParcelLinks", + schema: "ParcelRegistryExtract", + newName: "ParcelLinksWithCount", + newSchema: "ParcelRegistryExtract"); + + // Add back the primary key + migrationBuilder.AddPrimaryKey( + name: "PK_ParcelLinksWithCount", + schema: "ParcelRegistryExtract", + table: "ParcelLinksWithCount", + columns: new[] { "ParcelId", "AddressPersistentLocalId" }) + .Annotation("SqlServer:Clustered", false); + + migrationBuilder.CreateTable( + name: "ParcelLinks", + schema: "ParcelRegistryExtract", + columns: table => new + { + ParcelId = table.Column(type: "uniqueidentifier", nullable: false), + AddressPersistentLocalId = table.Column(type: "int", nullable: false), + CaPaKey = table.Column(type: "nvarchar(450)", nullable: false), + DbaseRecord = table.Column(type: "varbinary(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ParcelLinks", x => new { x.ParcelId, x.AddressPersistentLocalId }) + .Annotation("SqlServer:Clustered", false); + }); + + migrationBuilder.CreateIndex( + name: "IX_ParcelLinks_AddressPersistentLocalId", + schema: "ParcelRegistryExtract", + table: "ParcelLinks", + column: "AddressPersistentLocalId"); + + migrationBuilder.CreateIndex( + name: "IX_ParcelLinks_CaPaKey", + schema: "ParcelRegistryExtract", + table: "ParcelLinks", + column: "CaPaKey") + .Annotation("SqlServer:Clustered", true); + + migrationBuilder.CreateIndex( + name: "IX_ParcelLinks_ParcelId", + schema: "ParcelRegistryExtract", + table: "ParcelLinks", + column: "ParcelId"); + } + } +} diff --git a/src/ParcelRegistry.Projections.Extract/Migrations/ExtractContextModelSnapshot.cs b/src/ParcelRegistry.Projections.Extract/Migrations/ExtractContextModelSnapshot.cs index 7ce03cb1..b14ffe33 100644 --- a/src/ParcelRegistry.Projections.Extract/Migrations/ExtractContextModelSnapshot.cs +++ b/src/ParcelRegistry.Projections.Extract/Migrations/ExtractContextModelSnapshot.cs @@ -69,37 +69,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) }); modelBuilder.Entity("ParcelRegistry.Projections.Extract.ParcelLinkExtract.ParcelLinkExtractItem", b => - { - b.Property("ParcelId") - .HasColumnType("uniqueidentifier"); - - b.Property("AddressPersistentLocalId") - .HasColumnType("int"); - - b.Property("CaPaKey") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.Property("DbaseRecord") - .IsRequired() - .HasColumnType("varbinary(max)"); - - b.HasKey("ParcelId", "AddressPersistentLocalId"); - - SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("ParcelId", "AddressPersistentLocalId"), false); - - b.HasIndex("AddressPersistentLocalId"); - - b.HasIndex("CaPaKey"); - - SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CaPaKey")); - - b.HasIndex("ParcelId"); - - b.ToTable("ParcelLinks", "ParcelRegistryExtract"); - }); - - modelBuilder.Entity("ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount.ParcelLinkExtractItem", b => { b.Property("ParcelId") .HasColumnType("uniqueidentifier"); @@ -132,7 +101,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ParcelId"); - b.ToTable("ParcelLinksWithCount", "ParcelRegistryExtract"); + b.ToTable("ParcelLinks", "ParcelRegistryExtract"); }); #pragma warning restore 612, 618 } diff --git a/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2.cs b/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtract.cs similarity index 78% rename from src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2.cs rename to src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtract.cs index f8c2a230..4be144f2 100644 --- a/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2.cs +++ b/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtract.cs @@ -5,18 +5,18 @@ namespace ParcelRegistry.Projections.Extract.ParcelExtract using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; - public class ParcelExtractItemV2 + public class ParcelExtractItem { public Guid ParcelId { get; set; } public string CaPaKey { get; set; } public byte[]? DbaseRecord { get; set; } } - public class ParcelExtractItemV2Configuration : IEntityTypeConfiguration + public class ParcelExtractItemConfiguration : IEntityTypeConfiguration { - private const string TableName = "ParcelV2"; + private const string TableName = "Parcels"; - public void Configure(EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { builder.ToTable(TableName, Schema.Extract) .HasKey(p => p.ParcelId) diff --git a/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2Extensions.cs b/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractExtensions.cs similarity index 70% rename from src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2Extensions.cs rename to src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractExtensions.cs index 37442c91..3e8541b5 100644 --- a/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2Extensions.cs +++ b/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractExtensions.cs @@ -5,16 +5,16 @@ namespace ParcelRegistry.Projections.Extract.ParcelExtract using System.Threading; using System.Threading.Tasks; - public static class ParcelExtractV2Extensions + public static class ParcelExtractExtensions { - public static async Task FindAndUpdateParcelExtract( + public static async Task FindAndUpdateParcelExtract( this ExtractContext context, Guid parcelId, - Action updateFunc, + Action updateFunc, CancellationToken ct) { var parcel = await context - .ParcelExtractV2 + .ParcelExtract .FindAsync(parcelId, cancellationToken: ct); if (parcel == null) @@ -27,7 +27,7 @@ public static async Task FindAndUpdateParcelExtract( return parcel; } - private static ProjectionItemNotFoundException DatabaseItemNotFound(Guid parcelId) - => new ProjectionItemNotFoundException(parcelId.ToString("D")); + private static ProjectionItemNotFoundException DatabaseItemNotFound(Guid parcelId) + => new ProjectionItemNotFoundException(parcelId.ToString("D")); } } diff --git a/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2Projections.cs b/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractProjections.cs similarity index 91% rename from src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2Projections.cs rename to src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractProjections.cs index 2db836f9..e0f0be18 100644 --- a/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractV2Projections.cs +++ b/src/ParcelRegistry.Projections.Extract/ParcelExtract/ParcelExtractProjections.cs @@ -15,21 +15,21 @@ namespace ParcelRegistry.Projections.Extract.ParcelExtract [ConnectedProjectionName("Extract percelen")] [ConnectedProjectionDescription("Projectie die de percelen data voor het percelen extract voorziet.")] - public class ParcelExtractV2Projections : ConnectedProjection + public class ParcelExtractProjections : ConnectedProjection { private const string Realized = "Gerealiseerd"; private const string Retired = "Gehistoreerd"; private readonly Encoding _encoding; - public ParcelExtractV2Projections(IOptions extractConfig, Encoding encoding) + public ParcelExtractProjections(IOptions extractConfig, Encoding encoding) { _encoding = encoding ?? throw new ArgumentNullException(nameof(encoding)); When>(async (context, message, ct) => { await context - .ParcelExtractV2 - .AddAsync(new ParcelExtractItemV2 + .ParcelExtract + .AddAsync(new ParcelExtractItem { ParcelId = message.Message.ParcelId, CaPaKey = message.Message.CaPaKey, @@ -112,8 +112,8 @@ await context.FindAndUpdateParcelExtract( When>(async (context, message, ct) => { await context - .ParcelExtractV2 - .AddAsync(new ParcelExtractItemV2 + .ParcelExtract + .AddAsync(new ParcelExtractItem { ParcelId = message.Message.ParcelId, CaPaKey = message.Message.CaPaKey, @@ -163,7 +163,7 @@ await context.FindAndUpdateParcelExtract( }); } - private void SetDelete(ParcelExtractItemV2 parcel) + private void SetDelete(ParcelExtractItem parcel) => UpdateRecord(parcel, record => record.IsDeleted = true); private static readonly IDictionary StatusMapping = new Dictionary @@ -179,13 +179,13 @@ private string MapStatus(ParcelStatus parcelStatus) : throw new ArgumentOutOfRangeException(nameof(parcelStatus), parcelStatus, null); } - private void UpdateStatus(ParcelExtractItemV2 parcel, string status) + private void UpdateStatus(ParcelExtractItem parcel, string status) => UpdateRecord(parcel, record => record.status.Value = status); - private void UpdateVersie(ParcelExtractItemV2 parcel, Instant version) + private void UpdateVersie(ParcelExtractItem parcel, Instant version) => UpdateRecord(parcel, record => record.versieid.SetValue(version.ToBelgianDateTimeOffset())); - private void UpdateRecord(ParcelExtractItemV2 parcel, Action updateFunc) + private void UpdateRecord(ParcelExtractItem parcel, Action updateFunc) { if (parcel.DbaseRecord is not null) { diff --git a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtract/ParcelLinkExtract.cs b/src/ParcelRegistry.Projections.Extract/ParcelLinkExtract/ParcelLinkExtract.cs index 240c82da..c4f7b05c 100644 --- a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtract/ParcelLinkExtract.cs +++ b/src/ParcelRegistry.Projections.Extract/ParcelLinkExtract/ParcelLinkExtract.cs @@ -1,15 +1,16 @@ namespace ParcelRegistry.Projections.Extract.ParcelLinkExtract { using System; - using Infrastructure; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; + using ParcelRegistry.Infrastructure; public sealed class ParcelLinkExtractItem { public Guid ParcelId { get; set; } public string CaPaKey { get; set; } public int AddressPersistentLocalId { get; set; } + public int Count { get; set; } public byte[] DbaseRecord { get; set; } } @@ -26,6 +27,7 @@ public void Configure(EntityTypeBuilder builder) builder.Property(p => p.CaPaKey); builder.Property(p => p.DbaseRecord); builder.Property(p => p.AddressPersistentLocalId); + builder.Property(p => p.Count).HasDefaultValue(1); builder.HasIndex(p => p.CaPaKey).IsClustered(); builder.HasIndex(p => p.AddressPersistentLocalId); diff --git a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtract/ParcelLinkExtractProjections.cs b/src/ParcelRegistry.Projections.Extract/ParcelLinkExtract/ParcelLinkExtractProjections.cs index 40ec4e85..80beea1c 100644 --- a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtract/ParcelLinkExtractProjections.cs +++ b/src/ParcelRegistry.Projections.Extract/ParcelLinkExtract/ParcelLinkExtractProjections.cs @@ -4,11 +4,10 @@ namespace ParcelRegistry.Projections.Extract.ParcelLinkExtract using System.Text; using System.Threading; using System.Threading.Tasks; + using Be.Vlaanderen.Basisregisters.GrAr.Extracts; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; using Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore; - using Be.Vlaanderen.Basisregisters.GrAr.Extracts; - using Microsoft.Extensions.Options; - using Parcel.Events; + using ParcelRegistry.Parcel.Events; [ConnectedProjectionName("Extract perceelkoppelingen met adres")] [ConnectedProjectionDescription("Projectie die de perceel koppelingen data voor het adreskoppelingen extract voorziet.")] @@ -18,7 +17,7 @@ public sealed class ParcelLinkExtractProjections : ConnectedProjection extractConfig, Encoding encoding) + public ParcelLinkExtractProjections(Encoding encoding) { _encoding = encoding ?? throw new ArgumentNullException(nameof(encoding)); @@ -38,6 +37,7 @@ await context ParcelId = message.Message.ParcelId, CaPaKey = message.Message.CaPaKey, AddressPersistentLocalId = addressPersistentLocalId, + Count = 1, DbaseRecord = new ParcelLinkDbaseRecord { objecttype = { Value = ParcelObjectType }, @@ -57,6 +57,7 @@ await context ParcelId = message.Message.ParcelId, CaPaKey = message.Message.CaPaKey, AddressPersistentLocalId = message.Message.AddressPersistentLocalId, + Count = 1, DbaseRecord = new ParcelLinkDbaseRecord { objecttype = { Value = ParcelObjectType }, @@ -88,22 +89,72 @@ await context When>(async (context, message, ct) => { - await RemoveParcelLink(context, message.Message.ParcelId, message.Message.PreviousAddressPersistentLocalId, ct); + var previousAddress = await context + .ParcelLinkExtract + .FindAsync(new object?[] { message.Message.ParcelId, message.Message.PreviousAddressPersistentLocalId }, ct); - await context + if (previousAddress is not null && previousAddress.Count == 1) + { + context.ParcelLinkExtract.Remove(previousAddress); + } + else if (previousAddress is not null) + { + previousAddress.Count -= 1; + } + + var newAddress = await context .ParcelLinkExtract - .AddAsync(new ParcelLinkExtractItem - { - ParcelId = message.Message.ParcelId, - CaPaKey = message.Message.CaPaKey, - AddressPersistentLocalId = message.Message.NewAddressPersistentLocalId, - DbaseRecord = new ParcelLinkDbaseRecord + .FindAsync(new object?[] { message.Message.ParcelId, message.Message.NewAddressPersistentLocalId }, ct); + + if (newAddress is null) + { + await context + .ParcelLinkExtract + .AddAsync(new ParcelLinkExtractItem { - objecttype = { Value = ParcelObjectType }, - adresobjid = { Value = message.Message.CaPaKey }, - adresid = { Value = message.Message.NewAddressPersistentLocalId } - }.ToBytes(_encoding) - }, ct); + ParcelId = message.Message.ParcelId, + CaPaKey = message.Message.CaPaKey, + AddressPersistentLocalId = message.Message.NewAddressPersistentLocalId, + Count = 1, + DbaseRecord = new ParcelLinkDbaseRecord + { + objecttype = { Value = ParcelObjectType }, + adresobjid = { Value = message.Message.CaPaKey }, + adresid = { Value = message.Message.NewAddressPersistentLocalId } + }.ToBytes(_encoding) + }, ct); + } + else + { + newAddress.Count += 1; + } + }); + + When>(async (context, message, ct) => + { + foreach (var addressPersistentLocalId in message.Message.DetachedAddressPersistentLocalIds) + { + var relation = await context + .ParcelLinkExtract + .FindAsync([message.Message.ParcelId, addressPersistentLocalId], ct); + + if (relation is not null) + { + context.ParcelLinkExtract.Remove(relation); + } + } + + foreach (var addressPersistentLocalId in message.Message.AttachedAddressPersistentLocalIds) + { + var relation = await context + .ParcelLinkExtract + .FindAsync([message.Message.ParcelId, addressPersistentLocalId], ct); + + if (relation is not null) + { + await context.ParcelLinkExtract.AddAsync(relation, ct); + } + } }); } @@ -117,7 +168,7 @@ private static async Task RemoveParcelLink( .ParcelLinkExtract .FindAsync(new object?[] { parcelId, addressPersistentLocalId }, ct); - context.Remove(linkExtractItem); + context.Remove(linkExtractItem!); } } } diff --git a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkDbaseRecord.cs b/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkDbaseRecord.cs deleted file mode 100644 index b2481199..00000000 --- a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkDbaseRecord.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount -{ - using Be.Vlaanderen.Basisregisters.Shaperon; - - public sealed class ParcelLinkDbaseRecord : DbaseRecord - { - public static readonly ParcelLinkDbaseSchema Schema = new ParcelLinkDbaseSchema(); - - public DbaseCharacter objecttype { get; } - public DbaseCharacter adresobjid { get; } - public DbaseInt32 adresid { get; } - - public ParcelLinkDbaseRecord() - { - objecttype = new DbaseCharacter(Schema.objecttype); - adresobjid = new DbaseCharacter(Schema.adresobjid); - adresid = new DbaseInt32(Schema.adresid); - - Values = new DbaseFieldValue[] - { - objecttype, - adresobjid, - adresid - }; - } - } -} diff --git a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkDbaseSchema.cs b/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkDbaseSchema.cs deleted file mode 100644 index 98cecedc..00000000 --- a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkDbaseSchema.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount -{ - using Be.Vlaanderen.Basisregisters.Shaperon; - - public sealed class ParcelLinkDbaseSchema : DbaseSchema - { - public DbaseField objecttype => Fields[0]; - public DbaseField adresobjid => Fields[1]; - public DbaseField adresid => Fields[2]; - - public ParcelLinkDbaseSchema() => Fields = new[] - { - DbaseField.CreateCharacterField(new DbaseFieldName(nameof(objecttype)), new DbaseFieldLength(20)), - DbaseField.CreateCharacterField(new DbaseFieldName(nameof(adresobjid)), new DbaseFieldLength(30)), - DbaseField.CreateNumberField(new DbaseFieldName(nameof(adresid)), new DbaseFieldLength(DbaseInt32.MaximumIntegerDigits.ToInt32()), new DbaseDecimalCount(0)) - }; - } -} diff --git a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkExtract.cs b/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkExtract.cs deleted file mode 100644 index eb54a126..00000000 --- a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkExtract.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount -{ - using System; - using Infrastructure; - using Microsoft.EntityFrameworkCore; - using Microsoft.EntityFrameworkCore.Metadata.Builders; - - public sealed class ParcelLinkExtractItem - { - public Guid ParcelId { get; set; } - public string CaPaKey { get; set; } - public int AddressPersistentLocalId { get; set; } - public int Count { get; set; } - public byte[] DbaseRecord { get; set; } - } - - public sealed class ParcelLinkExtractItemConfiguration : IEntityTypeConfiguration - { - private const string TableName = "ParcelLinksWithCount"; - - public void Configure(EntityTypeBuilder builder) - { - builder.ToTable(TableName, Schema.Extract) - .HasKey(p => new { p.ParcelId, p.AddressPersistentLocalId }) - .IsClustered(false); - - builder.Property(p => p.CaPaKey); - builder.Property(p => p.DbaseRecord); - builder.Property(p => p.AddressPersistentLocalId); - builder.Property(p => p.Count).HasDefaultValue(1); - - builder.HasIndex(p => p.CaPaKey).IsClustered(); - builder.HasIndex(p => p.AddressPersistentLocalId); - builder.HasIndex(p => p.ParcelId); - } - } -} diff --git a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkExtractProjections.cs b/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkExtractProjections.cs deleted file mode 100644 index 9f369c25..00000000 --- a/src/ParcelRegistry.Projections.Extract/ParcelLinkExtractWithCount/ParcelLinkExtractProjections.cs +++ /dev/null @@ -1,174 +0,0 @@ -namespace ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount -{ - using System; - using System.Text; - using System.Threading; - using System.Threading.Tasks; - using Be.Vlaanderen.Basisregisters.GrAr.Extracts; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore; - using Parcel.Events; - - [ConnectedProjectionName("Extract perceelkoppelingen met adres")] - [ConnectedProjectionDescription("Projectie die de perceel koppelingen data voor het adreskoppelingen extract voorziet.")] - public sealed class ParcelLinkExtractProjections : ConnectedProjection - { - public const string ParcelObjectType = "Perceel"; - - private readonly Encoding _encoding; - - public ParcelLinkExtractProjections(Encoding encoding) - { - _encoding = encoding ?? throw new ArgumentNullException(nameof(encoding)); - - When>(async (context, message, ct) => - { - if (message.Message.IsRemoved) - { - return; - } - - foreach (var addressPersistentLocalId in message.Message.AddressPersistentLocalIds) - { - await context - .ParcelLinkExtractWithCount - .AddAsync(new ParcelLinkExtractItem - { - ParcelId = message.Message.ParcelId, - CaPaKey = message.Message.CaPaKey, - AddressPersistentLocalId = addressPersistentLocalId, - Count = 1, - DbaseRecord = new ParcelLinkDbaseRecord - { - objecttype = { Value = ParcelObjectType }, - adresobjid = { Value = message.Message.CaPaKey }, - adresid = { Value = addressPersistentLocalId } - }.ToBytes(_encoding) - }, ct); - } - }); - - When>(async (context, message, ct) => - { - await context - .ParcelLinkExtractWithCount - .AddAsync(new ParcelLinkExtractItem - { - ParcelId = message.Message.ParcelId, - CaPaKey = message.Message.CaPaKey, - AddressPersistentLocalId = message.Message.AddressPersistentLocalId, - Count = 1, - DbaseRecord = new ParcelLinkDbaseRecord - { - objecttype = { Value = ParcelObjectType }, - adresobjid = { Value = message.Message.CaPaKey }, - adresid = { Value = message.Message.AddressPersistentLocalId } - }.ToBytes(_encoding) - }, ct); - }); - - When>(async (context, message, ct) => - { - await RemoveParcelLink(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - await RemoveParcelLink(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - await RemoveParcelLink(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - await RemoveParcelLink(context, message.Message.ParcelId, message.Message.AddressPersistentLocalId, ct); - }); - - When>(async (context, message, ct) => - { - var previousAddress = await context - .ParcelLinkExtractWithCount - .FindAsync(new object?[] { message.Message.ParcelId, message.Message.PreviousAddressPersistentLocalId }, ct); - - if (previousAddress is not null && previousAddress.Count == 1) - { - context.ParcelLinkExtractWithCount.Remove(previousAddress); - } - else if (previousAddress is not null) - { - previousAddress.Count -= 1; - } - - var newAddress = await context - .ParcelLinkExtractWithCount - .FindAsync(new object?[] { message.Message.ParcelId, message.Message.NewAddressPersistentLocalId }, ct); - - if (newAddress is null) - { - await context - .ParcelLinkExtractWithCount - .AddAsync(new ParcelLinkExtractItem - { - ParcelId = message.Message.ParcelId, - CaPaKey = message.Message.CaPaKey, - AddressPersistentLocalId = message.Message.NewAddressPersistentLocalId, - Count = 1, - DbaseRecord = new ParcelLinkDbaseRecord - { - objecttype = { Value = ParcelObjectType }, - adresobjid = { Value = message.Message.CaPaKey }, - adresid = { Value = message.Message.NewAddressPersistentLocalId } - }.ToBytes(_encoding) - }, ct); - } - else - { - newAddress.Count += 1; - } - }); - - When>(async (context, message, ct) => - { - foreach (var addressPersistentLocalId in message.Message.DetachedAddressPersistentLocalIds) - { - var relation = await context - .ParcelLinkExtractWithCount - .FindAsync([message.Message.ParcelId, addressPersistentLocalId], ct); - - if (relation is not null) - { - context.ParcelLinkExtractWithCount.Remove(relation); - } - } - - foreach (var addressPersistentLocalId in message.Message.AttachedAddressPersistentLocalIds) - { - var relation = await context - .ParcelLinkExtractWithCount - .FindAsync([message.Message.ParcelId, addressPersistentLocalId], ct); - - if (relation is not null) - { - await context.ParcelLinkExtractWithCount.AddAsync(relation, ct); - } - } - }); - } - - private static async Task RemoveParcelLink( - ExtractContext context, - Guid parcelId, - int addressPersistentLocalId, - CancellationToken ct) - { - var linkExtractItem = await context - .ParcelLinkExtractWithCount - .FindAsync(new object?[] { parcelId, addressPersistentLocalId }, ct); - - context.Remove(linkExtractItem!); - } - } -} diff --git a/src/ParcelRegistry.Projections.Extract/output.sql b/src/ParcelRegistry.Projections.Extract/output.sql new file mode 100644 index 00000000..d3eb4b07 --- /dev/null +++ b/src/ParcelRegistry.Projections.Extract/output.sql @@ -0,0 +1,43 @@ +BEGIN TRANSACTION; +GO + +DROP TABLE [ParcelRegistryExtract].[ParcelLinks]; +GO + +ALTER TABLE [ParcelRegistryExtract].[ParcelLinksWithCount] DROP CONSTRAINT [PK_ParcelLinksWithCount]; +GO + +EXEC sp_rename N'[ParcelRegistryExtract].[ParcelLinksWithCount]', N'ParcelLinks'; +GO + +ALTER TABLE [ParcelRegistryExtract].[ParcelLinks] ADD CONSTRAINT [PK_ParcelLinks] PRIMARY KEY NONCLUSTERED ([ParcelId], [AddressPersistentLocalId]); +GO + +EXEC sp_rename N'[ParcelRegistryExtract].[ParcelLinks].[IX_ParcelLinksWithCount_CaPaKey]', N'IX_ParcelLinks_CaPaKey', N'INDEX'; +GO + +EXEC sp_rename N'[ParcelRegistryExtract].[ParcelLinks].[IX_ParcelLinksWithCount_AddressPersistentLocalId]', N'IX_ParcelLinks_AddressPersistentLocalId', N'INDEX'; +GO + +EXEC sp_rename N'[ParcelRegistryExtract].[ParcelLinks].[IX_ParcelLinksWithCount_ParcelId]', N'IX_ParcelLinks_ParcelId', N'INDEX'; +GO + +ALTER TABLE [ParcelRegistryExtract].[ParcelV2] DROP CONSTRAINT [PK_ParcelV2]; +GO + +EXEC sp_rename N'[ParcelRegistryExtract].[ParcelV2]', N'Parcels'; +GO + +ALTER TABLE [ParcelRegistryExtract].[Parcels] ADD CONSTRAINT [PK_Parcels] PRIMARY KEY NONCLUSTERED ([ParcelId]); +GO + +EXEC sp_rename N'[ParcelRegistryExtract].[Parcels].[IX_ParcelV2_CaPaKey]', N'IX_Parcels_CaPaKey', N'INDEX'; +GO + +INSERT INTO [ParcelRegistryExtract].[__EFMigrationsHistoryExtract] ([MigrationId], [ProductVersion]) +VALUES (N'20240607143051_DeleteOldLinksRenameNew', N'8.0.3'); +GO + +COMMIT; +GO + diff --git a/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs b/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs index eadc5a3e..5437551c 100644 --- a/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs +++ b/src/ParcelRegistry.Projector/Infrastructure/Modules/ApiModule.cs @@ -17,7 +17,6 @@ namespace ParcelRegistry.Projector.Infrastructure.Modules using ParcelRegistry.Infrastructure; using ParcelRegistry.Projections.Extract; using ParcelRegistry.Projections.Extract.ParcelExtract; - using ParcelRegistry.Projections.Extract.ParcelLinkExtract; using ParcelRegistry.Projections.Integration; using ParcelRegistry.Projections.Integration.Infrastructure; using ParcelRegistry.Projections.Integration.ParcelLatestItem; @@ -26,7 +25,7 @@ namespace ParcelRegistry.Projector.Infrastructure.Modules using ParcelRegistry.Projections.Legacy; using ParcelRegistry.Projections.Legacy.ParcelDetail; using ParcelRegistry.Projections.Legacy.ParcelSyndication; - using ParcelLinkExtractWithCountProjections = ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount.ParcelLinkExtractProjections; + using ParcelLinkExtractWithCountProjections = ParcelRegistry.Projections.Extract.ParcelLinkExtract.ParcelLinkExtractProjections; public class ApiModule : Module { @@ -86,13 +85,8 @@ private void RegisterExtractV2Projections(ContainerBuilder builder) .RegisterProjectionMigrator( _configuration, _loggerFactory) - .RegisterProjections( - context => new ParcelExtractV2Projections( - context.Resolve>(), - DbaseCodePage.Western_European_ANSI.ToEncoding()), - ConnectedProjectionSettings.Default) - .RegisterProjections( - context => new ParcelLinkExtractProjections( + .RegisterProjections( + context => new ParcelExtractProjections( context.Resolve>(), DbaseCodePage.Western_European_ANSI.ToEncoding()), ConnectedProjectionSettings.Default) From 530f9793be6d66df4e33605e4141d6f451760134 Mon Sep 17 00:00:00 2001 From: Arne Dumarey Date: Fri, 7 Jun 2024 20:08:06 +0200 Subject: [PATCH 3/6] feat: add add sync to oslo --- .../Convertors/ParcelStatus.cs | 8 + .../AtomFeedConfigurationBuilder.cs | 37 +++ .../Infrastructure/Modules/MediatRModule.cs | 2 + .../Parcel/ParcelController.cs | 25 ++ .../Parcel/Sync/ParcelSyndicationQuery.cs | 253 +++++++++++++++++ .../Parcel/Sync/ParcelSyndicationResponse.cs | 268 ++++++++++++++++++ .../Parcel/Sync/SyncHandler.cs | 105 +++++++ .../Parcel/Sync/SyncRequest.cs | 7 + src/ParcelRegistry.Api.Oslo/appsettings.json | 17 ++ 9 files changed, 722 insertions(+) create mode 100644 src/ParcelRegistry.Api.Oslo/Infrastructure/AtomFeedConfigurationBuilder.cs create mode 100644 src/ParcelRegistry.Api.Oslo/Parcel/Sync/ParcelSyndicationQuery.cs create mode 100644 src/ParcelRegistry.Api.Oslo/Parcel/Sync/ParcelSyndicationResponse.cs create mode 100644 src/ParcelRegistry.Api.Oslo/Parcel/Sync/SyncHandler.cs create mode 100644 src/ParcelRegistry.Api.Oslo/Parcel/Sync/SyncRequest.cs diff --git a/src/ParcelRegistry.Api.Oslo/Convertors/ParcelStatus.cs b/src/ParcelRegistry.Api.Oslo/Convertors/ParcelStatus.cs index 5a1e645a..31794b8b 100755 --- a/src/ParcelRegistry.Api.Oslo/Convertors/ParcelStatus.cs +++ b/src/ParcelRegistry.Api.Oslo/Convertors/ParcelStatus.cs @@ -14,5 +14,13 @@ public static ParcelStatus MapToParcelStatus(this PerceelStatus perceelStatus) => perceelStatus == PerceelStatus.Gehistoreerd ? ParcelStatus.Retired : ParcelStatus.Realized; + + public static PerceelStatus? MapToPerceelStatusSyndication(this ParcelRegistry.Legacy.ParcelStatus? status) + => status.HasValue ? MapToPerceelStatus(status.Value) : (PerceelStatus?)null; + + public static PerceelStatus MapToPerceelStatus(this ParcelRegistry.Legacy.ParcelStatus parcelStatus) + => parcelStatus == ParcelStatus.Retired + ? PerceelStatus.Gehistoreerd + : PerceelStatus.Gerealiseerd; } } diff --git a/src/ParcelRegistry.Api.Oslo/Infrastructure/AtomFeedConfigurationBuilder.cs b/src/ParcelRegistry.Api.Oslo/Infrastructure/AtomFeedConfigurationBuilder.cs new file mode 100644 index 00000000..2c65049d --- /dev/null +++ b/src/ParcelRegistry.Api.Oslo/Infrastructure/AtomFeedConfigurationBuilder.cs @@ -0,0 +1,37 @@ +namespace ParcelRegistry.Api.Oslo.Infrastructure +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using Be.Vlaanderen.Basisregisters.Api.Syndication; + using Microsoft.Extensions.Configuration; + using Microsoft.SyndicationFeed; + using Microsoft.SyndicationFeed.Atom; + + public static class AtomFeedConfigurationBuilder + { + public static AtomFeedConfiguration CreateFrom(IConfigurationSection configuration, DateTimeOffset lastUpdated) + { + return new AtomFeedConfiguration( + configuration["Id"], + configuration["Title"], + configuration["Subtitle"], + configuration["GeneratorTitle"], + configuration["GeneratorUri"], + Assembly.GetEntryAssembly()?.GetName().Version?.ToString(), + configuration["Rights"], + lastUpdated, + new SyndicationPerson(configuration["AuthorName"], configuration["AuthorEmail"], AtomContributorTypes.Author), + new SyndicationLink(new Uri(configuration["Self"]), AtomLinkTypes.Self), + new List(), + configuration + .GetSection("Related") + .GetChildren() + .Select(c => + new SyndicationLink(new Uri(c.Value), AtomLinkTypes.Related)) + .ToList() + ); + } + } +} diff --git a/src/ParcelRegistry.Api.Oslo/Infrastructure/Modules/MediatRModule.cs b/src/ParcelRegistry.Api.Oslo/Infrastructure/Modules/MediatRModule.cs index e02d2c68..86d497cf 100644 --- a/src/ParcelRegistry.Api.Oslo/Infrastructure/Modules/MediatRModule.cs +++ b/src/ParcelRegistry.Api.Oslo/Infrastructure/Modules/MediatRModule.cs @@ -5,6 +5,7 @@ namespace ParcelRegistry.Api.Oslo.Infrastructure.Modules using Parcel.Count; using Parcel.Detail; using Parcel.List; + using Parcel.Sync; using Module = Autofac.Module; public class MediatRModule : Module @@ -19,6 +20,7 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().AsImplementedInterfaces(); builder.RegisterType().AsImplementedInterfaces(); builder.RegisterType().AsImplementedInterfaces(); + builder.RegisterType().AsImplementedInterfaces(); } } } diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/ParcelController.cs b/src/ParcelRegistry.Api.Oslo/Parcel/ParcelController.cs index 5d407691..3402771e 100755 --- a/src/ParcelRegistry.Api.Oslo/Parcel/ParcelController.cs +++ b/src/ParcelRegistry.Api.Oslo/Parcel/ParcelController.cs @@ -1,5 +1,6 @@ namespace ParcelRegistry.Api.Oslo.Parcel { + using System.Net.Mime; using System.Threading; using System.Threading.Tasks; using Asp.Versioning; @@ -17,6 +18,7 @@ namespace ParcelRegistry.Api.Oslo.Parcel using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Filters; + using Sync; using ProblemDetails = Be.Vlaanderen.Basisregisters.BasicApiProblem.ProblemDetails; [ApiVersion("2.0")] @@ -110,5 +112,28 @@ public async Task Count( return Ok(await _mediator.Send(new ParcelCountOsloRequest(filtering, sorting, pagination), cancellationToken)); } + + /// + /// Vraag een lijst met wijzigingen van percelen op. + /// + /// + /// + [HttpGet("sync")] + [Produces("text/xml")] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] + [SwaggerResponseExample(StatusCodes.Status200OK, typeof(ParcelSyndicationResponseExamples))] + [SwaggerResponseExample(StatusCodes.Status400BadRequest, typeof(BadRequestResponseExamples))] + [SwaggerResponseExample(StatusCodes.Status500InternalServerError, typeof(InternalServerErrorResponseExamples))] + public async Task Sync(CancellationToken cancellationToken = default) + { + return new ContentResult + { + Content = await _mediator.Send(new SyncRequest(Request), cancellationToken), + ContentType = MediaTypeNames.Text.Xml, + StatusCode = StatusCodes.Status200OK + }; + } } } diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/Sync/ParcelSyndicationQuery.cs b/src/ParcelRegistry.Api.Oslo/Parcel/Sync/ParcelSyndicationQuery.cs new file mode 100644 index 00000000..41b0a60b --- /dev/null +++ b/src/ParcelRegistry.Api.Oslo/Parcel/Sync/ParcelSyndicationQuery.cs @@ -0,0 +1,253 @@ +namespace ParcelRegistry.Api.Oslo.Parcel.Sync +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Linq.Expressions; + using Be.Vlaanderen.Basisregisters.Api.Search; + using Be.Vlaanderen.Basisregisters.Api.Search.Filtering; + using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using Microsoft.EntityFrameworkCore; + using NodaTime; + using ParcelRegistry.Projections.Legacy; + using ParcelRegistry.Projections.Legacy.ParcelSyndication; + using ParcelStatus = Legacy.ParcelStatus; + + public class ParcelSyndicationQueryResult + { + public bool ContainsEvent { get; } + public bool ContainsObject { get; } + + public Guid ParcelId { get; } + public long Position { get; } + public string CaPaKey { get; } + public string ChangeType { get; } + public Instant RecordCreatedAt { get; } + public Instant LastChangedOn { get; } + public ParcelStatus? Status { get; } + public IEnumerable AddressIds { get; } = new List(); + public byte[]? ExtendedWkbGeometry { get; } + public Organisation? Organisation { get; } + public string Reason { get; } + public string EventDataAsXml { get; } + + public ParcelSyndicationQueryResult( + Guid parcelId, + long position, + string caPaKey, + string changeType, + Instant recordCreateAt, + Instant lastChangedOn, + Organisation? organisation, + string reason) + { + ContainsObject = false; + ContainsEvent = false; + + ParcelId = parcelId; + Position = position; + CaPaKey = caPaKey; + ChangeType = changeType; + RecordCreatedAt = recordCreateAt; + LastChangedOn = lastChangedOn; + Organisation = organisation; + Reason = reason; + } + + public ParcelSyndicationQueryResult( + Guid parcelId, + long position, + string caPaKey, + string changeType, + Instant recordCreateAt, + Instant lastChangedOn, + Organisation? organisation, + string reason, + string eventDataAsXml) + : this( + parcelId, + position, + caPaKey, + changeType, + recordCreateAt, + lastChangedOn, + organisation, + reason) + { + ContainsEvent = true; + + EventDataAsXml = eventDataAsXml; + } + + public ParcelSyndicationQueryResult( + Guid parcelId, + long position, + string caPaKey, + string changeType, + Instant recordCreateAt, + Instant lastChangedOn, + ParcelStatus? status, + IEnumerable addressIds, + IEnumerable addressPersistentLocalIds, + Organisation? organisation, + byte[]? extendedWkbGeometry, + string reason) + : this( + parcelId, + position, + caPaKey, + changeType, + recordCreateAt, + lastChangedOn, + organisation, + reason) + { + ContainsObject = true; + + Status = status; + AddressIds = addressIds.Select(y => y.ToString()).Concat(addressPersistentLocalIds.Select(y => y.ToString())).ToList(); + ExtendedWkbGeometry = extendedWkbGeometry; + } + + public ParcelSyndicationQueryResult( + Guid parcelId, + long position, + string caPaKey, + string changeType, + Instant recordCreateAt, + Instant lastChangedOn, + ParcelStatus? status, + IEnumerable addressIds, + IEnumerable addressPersistentLocalIds, + Organisation? organisation, + byte[]? extendedWkbGeometry, + string reason, + string eventDataAsXml) + : this( + parcelId, + position, + caPaKey, + changeType, + recordCreateAt, + lastChangedOn, + status, + addressIds, + addressPersistentLocalIds, + organisation, + extendedWkbGeometry, + reason) + { + ContainsEvent = true; + + EventDataAsXml = eventDataAsXml; + } + } + + public class ParcelSyndicationQuery : Query + { + private readonly LegacyContext _context; + private readonly bool _embedEvent; + private readonly bool _embedObject; + + public ParcelSyndicationQuery(LegacyContext context, SyncEmbedValue embed) + { + _context = context; + _embedEvent = embed?.Event ?? false; + _embedObject = embed?.Object ?? false; + } + + protected override ISorting Sorting => new ParcelSyndicationSorting(); + + protected override Expression> Transformation + { + get + { + if (_embedObject && _embedEvent) + return x => new ParcelSyndicationQueryResult( + x.ParcelId.Value, + x.Position, + x.CaPaKey, + x.ChangeType, + x.RecordCreatedAt, + x.LastChangedOn, + x.Status, + x.AddressIds, + x.AddressPersistentLocalIds, + x.Organisation, + x.ExtendedWkbGeometry, + x.Reason, + x.EventDataAsXml); + + if (_embedEvent) + return x => new ParcelSyndicationQueryResult( + x.ParcelId.Value, + x.Position, + x.CaPaKey, + x.ChangeType, + x.RecordCreatedAt, + x.LastChangedOn, + x.Organisation, + x.Reason, + x.EventDataAsXml); + + if (_embedObject) + return x => new ParcelSyndicationQueryResult( + x.ParcelId.Value, + x.Position, + x.CaPaKey, + x.ChangeType, + x.RecordCreatedAt, + x.LastChangedOn, + x.Status, + x.AddressIds, + x.AddressPersistentLocalIds, + x.Organisation, + x.ExtendedWkbGeometry, + x.Reason); + + return x => new ParcelSyndicationQueryResult( + x.ParcelId.Value, + x.Position, + x.CaPaKey, + x.ChangeType, + x.RecordCreatedAt, + x.LastChangedOn, + x.Organisation, + x.Reason); + } + } + + protected override IQueryable Filter(FilteringHeader filtering) + { + var parcels = _context + .ParcelSyndication + .OrderBy(x => x.Position) + .AsNoTracking(); + + if (!filtering.ShouldFilter) + return parcels; + + if (filtering.Filter.Position.HasValue) + parcels = parcels.Where(m => m.Position >= filtering.Filter.Position); + + return parcels; + } + } + + public class ParcelSyndicationSorting : ISorting + { + public IEnumerable SortableFields { get; } = new[] + { + nameof(ParcelSyndicationItem.Position) + }; + + public SortingHeader DefaultSortingHeader { get; } = new SortingHeader(nameof(ParcelSyndicationItem.Position), SortOrder.Ascending); + } + + public class ParcelSyndicationFilter + { + public long? Position { get; set; } + public SyncEmbedValue Embed { get; set; } + } +} diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/Sync/ParcelSyndicationResponse.cs b/src/ParcelRegistry.Api.Oslo/Parcel/Sync/ParcelSyndicationResponse.cs new file mode 100644 index 00000000..50b63c0a --- /dev/null +++ b/src/ParcelRegistry.Api.Oslo/Parcel/Sync/ParcelSyndicationResponse.cs @@ -0,0 +1,268 @@ +namespace ParcelRegistry.Api.Oslo.Parcel.Sync +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Runtime.Serialization; + using System.Threading.Tasks; + using System.Xml; + using Be.Vlaanderen.Basisregisters.GrAr.Common; + using Be.Vlaanderen.Basisregisters.GrAr.Common.Syndication; + using Be.Vlaanderen.Basisregisters.GrAr.Legacy; + using Be.Vlaanderen.Basisregisters.GrAr.Legacy.Perceel; + using Be.Vlaanderen.Basisregisters.GrAr.Legacy.SpatialTools; + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using Convertors; + using Infrastructure.Options; + using Microsoft.Extensions.Options; + using Microsoft.SyndicationFeed; + using Microsoft.SyndicationFeed.Atom; + using NetTopologySuite.Geometries; + using NetTopologySuite.IO; + using Swashbuckle.AspNetCore.Filters; + using Polygon = NetTopologySuite.Geometries.Polygon; + using Provenance = Be.Vlaanderen.Basisregisters.GrAr.Provenance.Syndication.Provenance; + + public static class ParcelSyndicationResponse + { + private static readonly WKBReader WkbReader = WKBReaderFactory.Create(); + + public static async Task WriteParcel( + this ISyndicationFeedWriter writer, + IOptions responseOptions, + AtomFormatter formatter, + string category, + ParcelSyndicationQueryResult parcel) + { + var item = new SyndicationItem + { + Id = parcel.Position.ToString(CultureInfo.InvariantCulture), + Title = $"{parcel.ChangeType}-{parcel.Position}", + Published = parcel.RecordCreatedAt.ToBelgianDateTimeOffset(), + LastUpdated = parcel.LastChangedOn.ToBelgianDateTimeOffset(), + Description = BuildDescription(parcel, responseOptions.Value.Naamruimte) + }; + + item.AddLink( + new SyndicationLink( + new Uri($"{responseOptions.Value.Naamruimte}/{parcel.CaPaKey}"), + AtomLinkTypes.Related)); + + //item.AddLink( + // new SyndicationLink( + // new Uri(string.Format(responseOptions.Value.DetailUrl, parcel.CaPaKey)), + // AtomLinkTypes.Self)); + + //item.AddLink( + // new SyndicationLink( + // new Uri(string.Format($"{responseOptions.Value.DetailUrl}.xml", parcel.CaPaKey)), + // AtomLinkTypes.Alternate) + // { MediaType = MediaTypeNames.Application.Xml }); + + //item.AddLink( + // new SyndicationLink( + // new Uri(string.Format($"{responseOptions.Value.DetailUrl}.json", parcel.CaPaKey)), + // AtomLinkTypes.Alternate) + // { MediaType = MediaTypeNames.Application.Json }); + + item.AddCategory( + new SyndicationCategory(category)); + + item.AddContributor( + new SyndicationPerson( + parcel.Organisation == null ? Organisation.Unknown.ToName() : parcel.Organisation.Value.ToName(), + string.Empty, + AtomContributorTypes.Author)); + + await writer.Write(item); + } + + private static string BuildDescription(ParcelSyndicationQueryResult parcel, string naamruimte) + { + if (!parcel.ContainsEvent && !parcel.ContainsObject) + return "No data embedded"; + + var content = new SyndicationContent(); + if(parcel.ContainsObject) + { + var geometry = parcel.ExtendedWkbGeometry is null + ? null + : WkbReader.Read(parcel.ExtendedWkbGeometry); + + content.Object = new ParcelSyndicationContent( + parcel.ParcelId, + naamruimte, + parcel.CaPaKey, + parcel.LastChangedOn.ToBelgianDateTimeOffset(), + parcel.Status.MapToPerceelStatusSyndication(), + parcel.AddressIds, + geometry is MultiPolygon + ? GmlMultiSurfaceBuilder.Build(parcel.ExtendedWkbGeometry!, WkbReader) + : null, + geometry is Polygon + ? PolygonBuilder.Build(parcel.ExtendedWkbGeometry!, WkbReader)?.XmlPolygon + : null, + parcel.Organisation, + parcel.Reason); + } + + if (parcel.ContainsEvent) + { + var doc = new XmlDocument(); + doc.LoadXml(parcel.EventDataAsXml); + content.Event = doc.DocumentElement; + } + + return content.ToXml(); + } + } + + [DataContract(Name = "Content", Namespace = "")] + public class SyndicationContent : SyndicationContentBase + { + [DataMember(Name = "Event")] + public XmlElement Event { get; set; } + + [DataMember(Name = "Object")] + public ParcelSyndicationContent Object { get; set; } + } + + [DataContract(Name = "Perceel", Namespace = "")] + public class ParcelSyndicationContent + { + /// + /// De technische id van het perceel. + /// + [DataMember(Name = "Id", Order = 1)] + public Guid ParcelId { get; set; } + + /// + /// De identificator van het perceel. + /// + [DataMember(Name = "Identificator", Order = 2)] + public PerceelIdentificator Identificator { get; set; } + + /// + /// De status van het perceel. + /// + [DataMember(Name = "PerceelStatus", Order = 3)] + public PerceelStatus? Status { get; set; } + + /// + /// De aan het perceel gelinkte adressen + /// + [DataMember(Name = "AdressenIds", Order = 4)] + public List AddressIds { get; set; } + + /// + /// De geometrie multi-polygoon van het perceel. + /// + [DataMember(Name = "GeometrieMultiPolygoon", Order = 5)] + public SyndicationMultiSurface MultiSurfacePolygon { get; set; } + + /// + /// De geometrie polygoon van het perceel. + /// + [DataMember(Name = "GeometriePolygoon", Order = 6)] + public SyndicationPolygon Polygon { get; set; } + + /// + /// Creatie data ivm het item. + /// + [DataMember(Name = "Creatie", Order = 7)] + public Provenance Provenance { get; set; } + + public ParcelSyndicationContent( + Guid parcelId, + string naamruimte, + string caPaKey, + DateTimeOffset version, + PerceelStatus? status, + IEnumerable addressIds, + GmlMultiSurface? gmlMultiSurface, + GmlPolygon? gmlPolygon, + Organisation? organisation, + string reason) + { + ParcelId = parcelId; + Identificator = new PerceelIdentificator(naamruimte, string.IsNullOrEmpty(caPaKey) ? string.Empty : caPaKey, version); + Status = status; + AddressIds = addressIds.ToList(); + if (gmlMultiSurface != null) + { + MultiSurfacePolygon = new SyndicationMultiSurface { XmlMultiSurface = gmlMultiSurface }; + } + + if (gmlPolygon != null) + { + Polygon = new SyndicationPolygon { XmlPolygon = gmlPolygon }; + } + + Provenance = new Provenance(version, organisation, new Reason(reason)); + } + } + + public class ParcelSyndicationResponseExamples : IExamplesProvider + { + private const string RawXml = @" + + https://api.basisregisters.vlaanderen.be/v1/feeds/percelen.atom + Basisregisters Vlaanderen - feed 'percelen' + Deze Atom feed geeft leestoegang tot events op de resource 'percelen'. + Basisregisters Vlaanderen + Gratis hergebruik volgens https://overheid.vlaanderen.be/sites/default/files/documenten/ict-egov/licenties/hergebruik/modellicentie_gratis_hergebruik_v1_0.html + 2020-11-06T19:36:06Z + + Digitaal Vlaanderen + digitaal.vlaanderen@vlaanderen.be + + + + + + + + 0 + ParcelWasRegistered-0 + 2012-09-23T23:13:50+02:00 + 2012-09-23T23:13:50+02:00 + + + Gemeente + + + + 10ad670a-ab6e-5fda-9a8a-733e11f5990202012-09-23T21:13:50ZMunicipalityDecentrale bijhouding CRAB + + 10ad670a-ab6e-5fda-9a8a-733e11f59902https://data.vlaanderen.be/id/perceel/0https://data.vlaanderen.be/id/perceel02012-09-23T23:13:50+02:00Gerealiseerd2012-09-23T23:13:50+02:00GemeenteDecentrale bijhouding CRAB + ]]> + + + + 1 + ParcelWasRealized-1 + 2012-09-23T23:13:50+02:00 + 2012-09-23T23:13:50+02:00 + + + Gemeente + + + + 10ad670a-ab6e-5fda-9a8a-733e11f599022012-09-23T21:13:50ZMunicipalityDecentrale bijhouding CRAB + + 10ad670a-ab6e-5fda-9a8a-733e11f59902https://data.vlaanderen.be/id/perceel/0https://data.vlaanderen.be/id/perceel02012-09-23T23:13:50+02:00Gerealiseerd2012-09-23T23:13:50+02:00GemeenteDecentrale bijhouding CRAB + ]]> + + +"; + + public XmlElement GetExamples() + { + var example = new XmlDocument(); + example.LoadXml(RawXml); + return example.DocumentElement; + } + } +} diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/Sync/SyncHandler.cs b/src/ParcelRegistry.Api.Oslo/Parcel/Sync/SyncHandler.cs new file mode 100644 index 00000000..a23b2138 --- /dev/null +++ b/src/ParcelRegistry.Api.Oslo/Parcel/Sync/SyncHandler.cs @@ -0,0 +1,105 @@ +namespace ParcelRegistry.Api.Oslo.Parcel.Sync +{ + using System; + using System.Linq; + using System.Text; + using System.Threading; + using System.Threading.Tasks; + using System.Xml; + using Be.Vlaanderen.Basisregisters.Api.Search.Filtering; + using Be.Vlaanderen.Basisregisters.Api.Search.Pagination; + using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; + using Be.Vlaanderen.Basisregisters.Api.Syndication; + using Be.Vlaanderen.Basisregisters.GrAr.Common; + using Infrastructure; + using Infrastructure.Options; + using MediatR; + using Microsoft.EntityFrameworkCore; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.Options; + using Microsoft.SyndicationFeed; + using Microsoft.SyndicationFeed.Atom; + using ParcelRegistry.Projections.Legacy; + + public class SyncHandler : IRequestHandler + { + private readonly IConfiguration _configuration; + private readonly LegacyContext _context; + private readonly IOptions _responseOptions; + + public SyncHandler( + IConfiguration configuration, + LegacyContext context, + IOptions responseOptions) + { + _configuration = configuration; + _context = context; + _responseOptions = responseOptions; + } + public async Task Handle(SyncRequest request, CancellationToken cancellationToken) + { + var filtering = request.HttpRequest.ExtractFilteringRequest(); + var sorting = request.HttpRequest.ExtractSortingRequest(); + var pagination = request.HttpRequest.ExtractPaginationRequest(); + + var lastFeedUpdate = await _context + .ParcelSyndication + .AsNoTracking() + .OrderByDescending(item => item.Position) + .Select(item => item.SyndicationItemCreatedAt) + .FirstOrDefaultAsync(cancellationToken); + + if (lastFeedUpdate == default) + lastFeedUpdate = new DateTimeOffset(2020, 1, 1, 0, 0, 0, TimeSpan.Zero); + + var pagedParcels = new ParcelSyndicationQuery( + _context, + filtering.Filter?.Embed) + .Fetch(filtering, sorting, pagination); + + return await BuildAtomFeed(lastFeedUpdate, pagedParcels, _responseOptions, _configuration); + } + + private static async Task BuildAtomFeed( + DateTimeOffset lastUpdate, + PagedQueryable pagedParcels, + IOptions responseOptions, + IConfiguration configuration) + { + var sw = new StringWriterWithEncoding(Encoding.UTF8); + + using (var xmlWriter = XmlWriter.Create(sw, new XmlWriterSettings { Async = true, Indent = true, Encoding = sw.Encoding })) + { + var formatter = new AtomFormatter(null, xmlWriter.Settings) { UseCDATA = true }; + var writer = new AtomFeedWriter(xmlWriter, null, formatter); + var syndicationConfiguration = configuration.GetSection("Syndication"); + var atomConfiguration = AtomFeedConfigurationBuilder.CreateFrom(syndicationConfiguration, lastUpdate); + + await writer.WriteDefaultMetadata(atomConfiguration); + + var parcels = pagedParcels.Items.ToList(); + var nextFrom = parcels.Any() + ? parcels.Max(x => x.Position) + 1 + : (long?)null; + + var nextUri = BuildNextSyncUri(pagedParcels.PaginationInfo.Limit, nextFrom, syndicationConfiguration["NextUri"]); + if (nextUri != null) + await writer.Write(new SyndicationLink(nextUri, "next")); + + foreach (var parcel in pagedParcels.Items) + await writer.WriteParcel(responseOptions, formatter, syndicationConfiguration["Category"], parcel); + + xmlWriter.Flush(); + } + + return sw.ToString(); + } + + private static Uri BuildNextSyncUri(int limit, long? from, string nextUrlBase) + { + return from.HasValue + ? new Uri(string.Format(nextUrlBase, from, limit)) + : null; + } + } +} diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/Sync/SyncRequest.cs b/src/ParcelRegistry.Api.Oslo/Parcel/Sync/SyncRequest.cs new file mode 100644 index 00000000..6f316e3c --- /dev/null +++ b/src/ParcelRegistry.Api.Oslo/Parcel/Sync/SyncRequest.cs @@ -0,0 +1,7 @@ +namespace ParcelRegistry.Api.Oslo.Parcel.Sync +{ + using MediatR; + using Microsoft.AspNetCore.Http; + + public record SyncRequest(HttpRequest HttpRequest) : IRequest; +} diff --git a/src/ParcelRegistry.Api.Oslo/appsettings.json b/src/ParcelRegistry.Api.Oslo/appsettings.json index 3bb1aa00..54a75d1b 100755 --- a/src/ParcelRegistry.Api.Oslo/appsettings.json +++ b/src/ParcelRegistry.Api.Oslo/appsettings.json @@ -17,6 +17,23 @@ "ContextUrlList": "https://docs.basisregisters.dev-vlaanderen.be/context/perceel/2022-01-11/perceel_list.jsonld", "ContextUrlDetail": "https://docs.basisregisters.dev-vlaanderen.be/context/perceel/2022-01-11/perceel_detail.jsonld", + "Syndication": { + "Category": "percelen", + "Id": "https://legacy.staging-basisregisters.vlaanderen/v1/feeds/percelen.atom", + "Title": "Basisregisters Vlaanderen - Percelenregister", + "Subtitle": "Deze Atom feed geeft leestoegang tot events op de resource 'percelen'.", + "GeneratorTitle": "Basisregisters Vlaanderen", + "GeneratorUri": "", + "Rights": "Gratis hergebruik volgens https://overheid.vlaanderen.be/sites/default/files/documenten/ict-egov/licenties/hergebruik/modellicentie_gratis_hergebruik_v1_0.html", + "AuthorName": "Digitaal Vlaanderen", + "AuthorEmail": "digitaal.vlaanderen@vlaanderen.be", + "Self": "https://legacy.staging-basisregisters.vlaanderen/syndication/feed/parcel", + "NextUri": "https://legacy.staging-basisregisters.vlaanderen/v1/feeds/parcel.atom?from={0}&limit={1}", + "Related": [ + "https://legacy.staging-basisregisters.vlaanderen" + ] + }, + "Serilog": { "MinimumLevel": { "Default": "Information" From 3f2afb826b47cc28f55a30118e3e9e934546e1d3 Mon Sep 17 00:00:00 2001 From: Arne Dumarey Date: Fri, 7 Jun 2024 20:13:26 +0200 Subject: [PATCH 4/6] ci: remove old staging --- .github/workflows/release.yml | 181 ---------------------------------- 1 file changed, 181 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7c3d6ed8..028a8d61 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -712,68 +712,6 @@ jobs: SEMVER: ${{ needs.release.outputs.version }} WORKSPACE: ${{ github.workspace }} - push_images_to_staging: - if: needs.release.outputs.version != 'none' - needs: [ release ] - name: Push images to Staging - runs-on: ubuntu-latest - strategy: - matrix: - image: [ - 'api-backoffice', - 'api-legacy', - 'api-oslo', - 'api-extract', - 'projector', - 'projections-backoffice', - 'projections-last-changed-list-console', - 'consumer-address', - 'producer', - 'producer-snapshot-oslo', - 'importer-grb', - 'snapshot-verifier' - ] - steps: - - name: Configure AWS credentials (Staging) - uses: aws-actions/configure-aws-credentials@v4.0.2 - with: - aws-access-key-id: ${{ secrets.VBR_AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.VBR_AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ secrets.VBR_AWS_REGION_PRD }} - - - name: Login to Amazon ECR (Staging) - uses: aws-actions/amazon-ecr-login@v2 - - # Download artifact - - name: Download artifact - uses: actions/download-artifact@v4 - continue-on-error: false - with: - name: ${{ matrix.image }}-${{ needs.release.outputs.version }} - path: ~/ - - # Load artifact - - name: Load artifact - shell: bash - run: | - echo pr-$IMAGE-image.tar - docker image load -i ~/pr-$IMAGE-image.tar - env: - IMAGE: ${{ matrix.image }} - - - name: Push artifacts to ECR Staging - shell: bash - run: | - echo $IMAGE:$SEMVER - docker tag $BUILD_DOCKER_REGISTRY_TST/parcel-registry/$IMAGE:$SEMVER $BUILD_DOCKER_REGISTRY/parcel-registry/$IMAGE:$SEMVER - docker push $BUILD_DOCKER_REGISTRY/parcel-registry/$IMAGE:$SEMVER - env: - BUILD_DOCKER_REGISTRY_TST: ${{ vars.VBR_DEVOPS_DOCKER_REGISTRY }} - BUILD_DOCKER_REGISTRY: ${{ secrets.VBR_BUILD_DOCKER_REGISTRY }} - IMAGE: ${{ matrix.image }} - SEMVER: ${{ needs.release.outputs.version }} - WORKSPACE: ${{ github.workspace }} - deploy_to_test_start_slack: if: github.repository_owner == 'Informatievlaanderen' needs: [ push_images, upload-lambda, release ] @@ -1085,122 +1023,3 @@ jobs: SLACK_BOT_TOKEN: ${{ secrets.VBR_SLACK_BOT_TOKEN }} SLACK_CHANNEL: ${{ secrets.VBR_NOTIFIER_CHANNEL_NAME }} REPOSITORY_NAME: ${{ env.REPOSITORY_NAME }} - - deploy_to_staging_start_slack: - if: github.repository_owner == 'Informatievlaanderen' - needs: [ push_images_to_staging, upload-lambda, release ] - name: Deploy to staging started - environment: stg - runs-on: ubuntu-latest - - steps: - - name: Parse repository name - run: echo REPOSITORY_NAME=$(echo ""$GITHUB_REPOSITORY"" | awk -F / '{print $2}' | sed -e ""s/:refs//"") >> $GITHUB_ENV - shell: bash - - - name: Notify deployment started - uses: slackapi/slack-github-action@v1.25.0 - with: - channel-id: '#team-dinosaur-dev' - slack-message: Deployment of parcel-registry to staging has started - env: - SLACK_BOT_TOKEN: ${{ secrets.VBR_SLACK_BOT_TOKEN }} - SLACK_CHANNEL: ${{ secrets.VBR_NOTIFIER_CHANNEL_NAME }} - REPOSITORY_NAME: ${{ env.REPOSITORY_NAME }} - - deploy_to_staging: - if: github.repository_owner == 'Informatievlaanderen' - needs: [ deploy_to_staging_start_slack, release ] - name: Deploy to staging - runs-on: ubuntu-latest - strategy: - matrix: - services: [ - 'parcel-registry-api', - 'parcel-registry-backoffice-api', - 'parcel-registry-consumer-address', - 'parcel-registry-producer', - 'parcel-registry-producer-snapshot-oslo', - 'parcel-registry-projections', - 'parcel-registry-projections-backoffice', - 'parcel-registry-importer-grb', - 'parcel-registry-snapshot-verifier' - ] - steps: - - name: CD services - env: - BUILD_URL: ${{ secrets.VBR_AWS_BUILD_API }}/${{matrix.services}} - STATUS_URL: ${{ secrets.VBR_AWS_BUILD_STATUS_API }}/${{matrix.services}} - uses: informatievlaanderen/awscurl-polling-action/polling-action@main - with: - environment: stg - version: ${{ needs.release.outputs.version }} - status-url: $STATUS_URL - deploy-url: $BUILD_URL - access-key: ${{ secrets.VBR_AWS_BUILD_USER_ACCESS_KEY_ID }} - secret-key: ${{ secrets.VBR_AWS_BUILD_USER_SECRET_ACCESS_KEY }} - region: eu-west-1 - interval: 2 - - - name: output CD services - shell: bash - run: | - echo build-uuid: ${{ steps.awscurl-polling-action.outputs.build-uuid }} - echo Status: ${{ steps.awscurl-polling-action.outputs.status }} - echo ${{ steps.awscurl-polling-action.outputs.final-message }} - - deploy_lambda_to_staging: - if: github.repository_owner == 'Informatievlaanderen' - needs: [ deploy_to_staging, release ] - name: Deploy lambda to staging - runs-on: ubuntu-latest - - steps: - - name: CD Lambda(s) Configure credentials - uses: aws-actions/configure-aws-credentials@v4.0.2 - with: - aws-access-key-id: ${{ secrets.VBR_AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.VBR_AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ secrets.VBR_AWS_REGION_PRD }} - - - name: Prepare Lambda(s) - shell: bash - run: | - echo aws s3 cp s3://s3-vbr-stg-basisregisters-lam-pr-sqsbackofficehandlerfunction/$VERSION/lambda.zip s3://s3-vbr-stg-basisregisters-lam-pr-sqsbackofficehandlerfunction/lambda.zip --copy-props none - aws s3 cp s3://s3-vbr-stg-basisregisters-lam-pr-sqsbackofficehandlerfunction/$VERSION/lambda.zip s3://s3-vbr-stg-basisregisters-lam-pr-sqsbackofficehandlerfunction/lambda.zip --copy-props none - env: - VERSION: ${{ needs.release.outputs.version }} - - - name: Promote Lambda(s) - shell: bash - run: | - echo pulling awscurl docker image - docker pull ghcr.io/okigan/awscurl:latest - echo docker run --rm okigan/awscurl --access_key $ACCESS_KEY_ID --secret_key $SECRET_ACCESS_KEY_ID --region $REGION -X POST -d '{ "functionName": "pr-sqsbackofficehandlerfunction", "project": "basisregisters", "domain": "basisregisters" }' $PROMOTEURL/stg - docker run --rm okigan/awscurl --access_key $ACCESS_KEY_ID --secret_key $SECRET_ACCESS_KEY_ID --region $REGION -X POST -d '{ "functionName": "pr-sqsbackofficehandlerfunction", "project": "basisregisters", "domain": "basisregisters" }' $PROMOTEURL/stg - env: - ACCESS_KEY_ID: ${{ secrets.VBR_AWS_ACCESS_KEY_ID_TST }} - SECRET_ACCESS_KEY_ID: ${{ secrets.VBR_AWS_SECRET_ACCESS_KEY_TST }} - REGION: ${{ secrets.VBR_AWS_REGION_PRD }} - PROMOTEURL: ${{ secrets.VBR_AWS_PROMOTE_LAMBDA_BASEURL }} - - deploy_to_staging_finish_slack: - if: github.repository_owner == 'Informatievlaanderen' - needs: [ deploy_lambda_to_staging ] - name: Deploy to staging finished - runs-on: ubuntu-latest - - steps: - - name: Parse repository name - run: echo REPOSITORY_NAME=$(echo ""$GITHUB_REPOSITORY"" | awk -F / '{print $2}' | sed -e ""s/:refs//"") >> $GITHUB_ENV - shell: bash - - - name: Notify deployment finished - uses: slackapi/slack-github-action@v1.25.0 - with: - channel-id: '#team-dinosaur-dev' - slack-message: Deployment of parcel-registry to staging has finished - env: - SLACK_BOT_TOKEN: ${{ secrets.VBR_SLACK_BOT_TOKEN }} - SLACK_CHANNEL: ${{ secrets.VBR_NOTIFIER_CHANNEL_NAME }} - REPOSITORY_NAME: ${{ env.REPOSITORY_NAME }} From 0292b26c4db9aa5248052aff6b35ec44b5eaf085 Mon Sep 17 00:00:00 2001 From: Arne Dumarey Date: Fri, 7 Jun 2024 20:20:51 +0200 Subject: [PATCH 5/6] feat: remove api legacy --- .github/workflows/release.yml | 45 --- ParcelRegistry.sln | 7 - .../Convertors/ParcelStatus.cs | 25 -- src/ParcelRegistry.Api.Legacy/Dockerfile | 30 -- .../AtomFeedConfigurationBuilder.cs | 37 --- .../AddNoCacheHeadersMiddleware.cs | 23 -- .../Infrastructure/EmptyController.cs | 20 -- .../Infrastructure/Modules/ApiModule.cs | 40 --- .../Infrastructure/Modules/MediatRModule.cs | 27 -- .../Infrastructure/Options/ResponseOptions.cs | 10 - .../Infrastructure/PaginationInfoExtension.cs | 18 -- .../Infrastructure/Program.cs | 30 -- .../Infrastructure/Startup.cs | 158 ----------- .../Parcel/Count/ParcelCountRequest.cs | 14 - .../Parcel/Count/ParcelCountV2Handler.cs | 38 --- .../Parcel/Count/TotalCountResponseExample.cs | 16 -- .../Parcel/Detail/ParcelDetailRequest.cs | 6 - .../Parcel/Detail/ParcelDetailResponse.cs | 122 -------- .../Detail/ParcelDetailResponseWithEtag.cs | 14 - .../Parcel/Detail/ParcelDetailV2Handler.cs | 62 ---- .../Parcel/List/ParcelListRequest.cs | 12 - .../Parcel/List/ParcelListResponse.cs | 110 ------- .../Parcel/List/ParcelListV2Handler.cs | 50 ---- .../Parcel/List/ParcelListV2Query.cs | 92 ------ .../Parcel/List/ParcelListV2QueryItem.cs | 18 -- .../Parcel/ParcelController.cs | 137 --------- .../Parcel/Sync/ParcelSyndicationQuery.cs | 254 ----------------- .../Parcel/Sync/ParcelSyndicationResponse.cs | 268 ------------------ .../Parcel/Sync/SyncHandler.cs | 105 ------- .../Parcel/Sync/SyncRequest.cs | 7 - .../ParcelRegistry.Api.Legacy.csproj | 39 --- .../Properties/AssemblyInfo.cs | 10 - .../Properties/launchSettings.json | 26 -- .../appsettings.json | 53 ---- src/ParcelRegistry.Api.Legacy/init.sh | 7 - .../paket.references | 12 - src/ParcelRegistry.Api.Legacy/paket.template | 31 -- .../ParcelRegistry.Tests.csproj | 2 +- 38 files changed, 1 insertion(+), 1974 deletions(-) delete mode 100755 src/ParcelRegistry.Api.Legacy/Convertors/ParcelStatus.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Dockerfile delete mode 100644 src/ParcelRegistry.Api.Legacy/Infrastructure/AtomFeedConfigurationBuilder.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Infrastructure/Configuration/AddNoCacheHeadersMiddleware.cs delete mode 100755 src/ParcelRegistry.Api.Legacy/Infrastructure/EmptyController.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Infrastructure/Modules/ApiModule.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Infrastructure/Modules/MediatRModule.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Infrastructure/Options/ResponseOptions.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Infrastructure/PaginationInfoExtension.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Infrastructure/Program.cs delete mode 100755 src/ParcelRegistry.Api.Legacy/Infrastructure/Startup.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Count/ParcelCountRequest.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Count/ParcelCountV2Handler.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Count/TotalCountResponseExample.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailRequest.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailResponse.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailResponseWithEtag.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailV2Handler.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListRequest.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListResponse.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Handler.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Query.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2QueryItem.cs delete mode 100755 src/ParcelRegistry.Api.Legacy/Parcel/ParcelController.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Sync/ParcelSyndicationQuery.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Sync/ParcelSyndicationResponse.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Sync/SyncHandler.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Parcel/Sync/SyncRequest.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/ParcelRegistry.Api.Legacy.csproj delete mode 100644 src/ParcelRegistry.Api.Legacy/Properties/AssemblyInfo.cs delete mode 100644 src/ParcelRegistry.Api.Legacy/Properties/launchSettings.json delete mode 100755 src/ParcelRegistry.Api.Legacy/appsettings.json delete mode 100755 src/ParcelRegistry.Api.Legacy/init.sh delete mode 100644 src/ParcelRegistry.Api.Legacy/paket.references delete mode 100644 src/ParcelRegistry.Api.Legacy/paket.template diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 028a8d61..a0ca835e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -70,21 +70,6 @@ jobs: dotnet-version: ${{ vars.VBR_DOTNET_VERSION_8 }} secrets: inherit - build-api-legacy: - name: Build Api Legacy - uses: Informatievlaanderen/build-pipeline/.github/workflows/build-image.yml@main - needs: [ set-release-version ] - if: ${{ (github.repository_owner == 'Informatievlaanderen') && (needs.set-release-version.outputs.version != 'none') }} - with: - registry: ${{ vars.VBR_DEVOPS_DOCKER_REGISTRY }}/parcel-registry - image-file: pr-api-legacy-image.tar - image-name: api-legacy - test-project: ParcelRegistry.Tests - build-project: ParcelRegistry.Api.Legacy - semver: ${{ needs.set-release-version.outputs.version }} - dotnet-version: ${{ vars.VBR_DOTNET_VERSION_8 }} - secrets: inherit - build-api-oslo: name: Build Api Oslo uses: Informatievlaanderen/build-pipeline/.github/workflows/build-image.yml@main @@ -262,19 +247,6 @@ jobs: dotnet-version: ${{ vars.VBR_DOTNET_VERSION_8 }} secrets: inherit - pack-api-legacy: - name: Pack Api Legacy - uses: Informatievlaanderen/build-pipeline/.github/workflows/pack.yml@main - needs: [ set-release-version ] - if: ${{ (github.repository_owner == 'Informatievlaanderen') && (needs.set-release-version.outputs.version != 'none') }} - with: - pack-file: Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.Legacy - test-project: ParcelRegistry.Tests - build-project: ParcelRegistry.Api.Legacy - semver: ${{ needs.set-release-version.outputs.version }} - dotnet-version: ${{ vars.VBR_DOTNET_VERSION_8 }} - secrets: inherit - pack-api-oslo: name: Pack Api Oslo uses: Informatievlaanderen/build-pipeline/.github/workflows/pack.yml@main @@ -321,11 +293,9 @@ jobs: needs: [ set-release-version, #pack-api-backoffice, pack-api-backoffice-abstractions, - pack-api-legacy, pack-api-oslo, pack-api-extract, build-api-backoffice, - build-api-legacy, build-api-oslo, build-api-extract, build-projector, @@ -406,13 +376,6 @@ jobs: name: nuget-Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.BackOffice.Abstractions-${{ needs.set-release-version.outputs.version }} path: dist/nuget/ - - name: Download NuGet Api Legacy - uses: actions/download-artifact@v4 - continue-on-error: false - with: - name: nuget-Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.Legacy-${{ needs.set-release-version.outputs.version }} - path: dist/nuget/ - - name: Download NuGet Api Oslo uses: actions/download-artifact@v4 continue-on-error: false @@ -560,12 +523,6 @@ jobs: name: nuget-Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.BackOffice.Abstractions-${{ needs.release.outputs.version }} path: ~/ - - name: Download NuGet package api-legacy - uses: actions/download-artifact@v4 - with: - name: nuget-Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.Legacy-${{ needs.release.outputs.version }} - path: ~/ - - name: Download NuGet package api-oslo uses: actions/download-artifact@v4 with: @@ -583,7 +540,6 @@ jobs: # dotnet nuget push ~/Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.BackOffice.$SEMVER.nupkg --source nuget.org --api-key $NUGET_API_KEY run: | dotnet nuget push ~/Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.BackOffice.Abstractions.$SEMVER.nupkg --source nuget.org --api-key $NUGET_API_KEY - dotnet nuget push ~/Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.Legacy.$SEMVER.nupkg --source nuget.org --api-key $NUGET_API_KEY dotnet nuget push ~/Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.Oslo.$SEMVER.nupkg --source nuget.org --api-key $NUGET_API_KEY dotnet nuget push ~/Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.Extract.$SEMVER.nupkg --source nuget.org --api-key $NUGET_API_KEY env: @@ -661,7 +617,6 @@ jobs: matrix: image: [ 'api-backoffice', - 'api-legacy', 'api-oslo', 'api-extract', 'projector', diff --git a/ParcelRegistry.sln b/ParcelRegistry.sln index b520ac99..e2ee14b7 100644 --- a/ParcelRegistry.sln +++ b/ParcelRegistry.sln @@ -23,8 +23,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{A1CB15D5-7 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ParcelRegistry", "src\ParcelRegistry\ParcelRegistry.csproj", "{8FE01FF7-515C-448A-A549-EE56080BE1BA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ParcelRegistry.Api.Legacy", "src\ParcelRegistry.Api.Legacy\ParcelRegistry.Api.Legacy.csproj", "{2343237C-031B-4896-9958-57519E455DE1}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ParcelRegistry.Infrastructure", "src\ParcelRegistry.Infrastructure\ParcelRegistry.Infrastructure.csproj", "{1F7349F4-ACAB-4DAC-8476-71736E65FE41}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ParcelRegistry.Projections.Legacy", "src\ParcelRegistry.Projections.Legacy\ParcelRegistry.Projections.Legacy.csproj", "{713526B9-1FE5-409E-8754-11B8B50E3BC1}" @@ -85,10 +83,6 @@ Global {8FE01FF7-515C-448A-A549-EE56080BE1BA}.Debug|Any CPU.Build.0 = Debug|Any CPU {8FE01FF7-515C-448A-A549-EE56080BE1BA}.Release|Any CPU.ActiveCfg = Release|Any CPU {8FE01FF7-515C-448A-A549-EE56080BE1BA}.Release|Any CPU.Build.0 = Release|Any CPU - {2343237C-031B-4896-9958-57519E455DE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2343237C-031B-4896-9958-57519E455DE1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2343237C-031B-4896-9958-57519E455DE1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2343237C-031B-4896-9958-57519E455DE1}.Release|Any CPU.Build.0 = Release|Any CPU {1F7349F4-ACAB-4DAC-8476-71736E65FE41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1F7349F4-ACAB-4DAC-8476-71736E65FE41}.Debug|Any CPU.Build.0 = Debug|Any CPU {1F7349F4-ACAB-4DAC-8476-71736E65FE41}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -183,7 +177,6 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {8FE01FF7-515C-448A-A549-EE56080BE1BA} = {B483712F-241C-411F-8CC7-D46B3530DF65} - {2343237C-031B-4896-9958-57519E455DE1} = {B483712F-241C-411F-8CC7-D46B3530DF65} {1F7349F4-ACAB-4DAC-8476-71736E65FE41} = {B483712F-241C-411F-8CC7-D46B3530DF65} {713526B9-1FE5-409E-8754-11B8B50E3BC1} = {B483712F-241C-411F-8CC7-D46B3530DF65} {951C912B-E9B2-4941-BE18-C5125FC0D9E6} = {DF5FFD7D-3020-4F80-87EF-BE2D2CACD27E} diff --git a/src/ParcelRegistry.Api.Legacy/Convertors/ParcelStatus.cs b/src/ParcelRegistry.Api.Legacy/Convertors/ParcelStatus.cs deleted file mode 100755 index feabe183..00000000 --- a/src/ParcelRegistry.Api.Legacy/Convertors/ParcelStatus.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Convertors -{ - using Be.Vlaanderen.Basisregisters.GrAr.Legacy.Perceel; - using ParcelRegistry.Legacy; - - public static class ParcelStatusExtensions - { - public static PerceelStatus? MapToPerceelStatusSyndication(this ParcelStatus? status) - => status.HasValue ? MapToPerceelStatus(status.Value) : (PerceelStatus?)null; - - public static PerceelStatus MapToPerceelStatus(this ParcelStatus parcelStatus) - => parcelStatus == ParcelStatus.Retired - ? PerceelStatus.Gehistoreerd - : PerceelStatus.Gerealiseerd; - public static ParcelStatus MapToParcelStatus(this PerceelStatus perceelStatus) - => perceelStatus == PerceelStatus.Gehistoreerd - ? ParcelStatus.Retired - : ParcelStatus.Realized; - - public static PerceelStatus MapToPerceelStatus(this ParcelRegistry.Parcel.ParcelStatus parcelStatus) - => parcelStatus == ParcelStatus.Retired - ? PerceelStatus.Gehistoreerd - : PerceelStatus.Gerealiseerd; - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Dockerfile b/src/ParcelRegistry.Api.Legacy/Dockerfile deleted file mode 100644 index 1e3e8fe5..00000000 --- a/src/ParcelRegistry.Api.Legacy/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -FROM mcr.microsoft.com/dotnet/runtime-deps:8.0.2-bookworm-slim-amd64 - -# create work dir and set permissions as WORKDIR sets permissions as root -RUN mkdir /app && chown -R app:app /app -WORKDIR /app - -LABEL maintainer="Digitaal Vlaanderen " -LABEL registry="parcel-registry" - -COPY / /app -WORKDIR /app - -RUN apt-get update && \ - apt-get install curl jq -y && \ - chmod +x ./init.sh - -EXPOSE 7002/tcp -ENV ASPNETCORE_URLS http://*:7002 -ENV CORECLR_ENABLE_PROFILING=1 -ENV CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8} -ENV CORECLR_PROFILER_PATH=/app/datadog/linux-x64/Datadog.Trace.ClrProfiler.Native.so -ENV DD_DOTNET_TRACER_HOME=/app/datadog - -# Run the createLogPath script on Linux to ensure the automatic instrumentation logs are generated without permission issues -RUN /app/datadog/createLogPath.sh - -# switch to created user -USER app - -ENTRYPOINT ["./init.sh"] diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/AtomFeedConfigurationBuilder.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/AtomFeedConfigurationBuilder.cs deleted file mode 100644 index fb306013..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/AtomFeedConfigurationBuilder.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - using Be.Vlaanderen.Basisregisters.Api.Syndication; - using Microsoft.Extensions.Configuration; - using Microsoft.SyndicationFeed; - using Microsoft.SyndicationFeed.Atom; - - public static class AtomFeedConfigurationBuilder - { - public static AtomFeedConfiguration CreateFrom(IConfigurationSection configuration, DateTimeOffset lastUpdated) - { - return new AtomFeedConfiguration( - configuration["Id"], - configuration["Title"], - configuration["Subtitle"], - configuration["GeneratorTitle"], - configuration["GeneratorUri"], - Assembly.GetEntryAssembly()?.GetName().Version?.ToString(), - configuration["Rights"], - lastUpdated, - new SyndicationPerson(configuration["AuthorName"], configuration["AuthorEmail"], AtomContributorTypes.Author), - new SyndicationLink(new Uri(configuration["Self"]), AtomLinkTypes.Self), - new List(), - configuration - .GetSection("Related") - .GetChildren() - .Select(c => - new SyndicationLink(new Uri(c.Value), AtomLinkTypes.Related)) - .ToList() - ); - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/Configuration/AddNoCacheHeadersMiddleware.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/Configuration/AddNoCacheHeadersMiddleware.cs deleted file mode 100644 index aeb02cea..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/Configuration/AddNoCacheHeadersMiddleware.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure.Configuration -{ - using System.Threading.Tasks; - using Microsoft.AspNetCore.Http; - - /// - /// Add headers to the response to prevent any caching. - /// - public class AddNoCacheHeadersMiddleware - { - private readonly RequestDelegate _next; - - public AddNoCacheHeadersMiddleware(RequestDelegate next) => _next = next; - - public Task Invoke(HttpContext context) - { - context.Response.Headers.Add("cache-control", "no-store, no-cache, must-revalidate"); - context.Response.Headers.Add("pragma", "no-cache"); - - return _next(context); - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/EmptyController.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/EmptyController.cs deleted file mode 100755 index e75b88ff..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/EmptyController.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure -{ - using System.Reflection; - using Asp.Versioning; - using Microsoft.AspNetCore.Mvc; - using Microsoft.Net.Http.Headers; - using Be.Vlaanderen.Basisregisters.Api; - - [ApiVersionNeutral] - [Route("")] - public class EmptyController : ApiController - { - [HttpGet] - [ApiExplorerSettings(IgnoreApi = true)] - public IActionResult Get() - => Request.Headers[HeaderNames.Accept].ToString().Contains("text/html") - ? (IActionResult)new RedirectResult("/docs") - : new OkObjectResult($"Welcome to the Basisregisters Vlaanderen Parcel Legacy Api {Assembly.GetEntryAssembly().GetVersionText()}."); - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/Modules/ApiModule.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/Modules/ApiModule.cs deleted file mode 100644 index bbbacdc1..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/Modules/ApiModule.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure.Modules -{ - using Autofac; - using Autofac.Extensions.DependencyInjection; - using Be.Vlaanderen.Basisregisters.Api.Exceptions; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Logging; - using Projections.Legacy; - - public class ApiModule : Module - { - private readonly IConfiguration _configuration; - private readonly IServiceCollection _services; - private readonly ILoggerFactory _loggerFactory; - - public ApiModule( - IConfiguration configuration, - IServiceCollection services, - ILoggerFactory loggerFactory) - { - _configuration = configuration; - _services = services; - _loggerFactory = loggerFactory; - } - - protected override void Load(ContainerBuilder builder) - { - builder - .RegisterModule(new MediatRModule()) - .RegisterModule(new LegacyModule(_configuration, _services, _loggerFactory)); - - builder - .RegisterType() - .AsSelf(); - - builder.Populate(_services); - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/Modules/MediatRModule.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/Modules/MediatRModule.cs deleted file mode 100644 index 53629b9a..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/Modules/MediatRModule.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure.Modules -{ - using Autofac; - using MediatR; - using Parcel.Count; - using Parcel.List; - using Parcel.Sync; - using ParcelRegistry.Api.Legacy.Parcel.Detail; - using Module = Autofac.Module; - - public class MediatRModule : Module - { - protected override void Load(ContainerBuilder builder) - { - builder - .RegisterType() - .As() - .InstancePerLifetimeScope(); - - builder.RegisterType().AsImplementedInterfaces(); - - builder.RegisterType().AsImplementedInterfaces(); - builder.RegisterType().AsImplementedInterfaces(); - builder.RegisterType().AsImplementedInterfaces(); - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/Options/ResponseOptions.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/Options/ResponseOptions.cs deleted file mode 100644 index 220f5aaf..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/Options/ResponseOptions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure.Options -{ - public class ResponseOptions - { - public string Naamruimte { get; set; } - public string VolgendeUrl { get; set; } - public string DetailUrl { get; set; } - public string AdresDetailUrl { get; set; } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/PaginationInfoExtension.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/PaginationInfoExtension.cs deleted file mode 100644 index 3d12c165..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/PaginationInfoExtension.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure -{ - using System; - using Be.Vlaanderen.Basisregisters.Api.Search.Pagination; - - public static class PaginationInfoExtension - { - public static Uri? BuildVolgendeUri(this PaginationInfo paginationInfo, int itemsInCollection, string nextUrlBase) - { - var offset = paginationInfo.Offset; - var limit = paginationInfo.Limit; - - return paginationInfo.HasNextPage(itemsInCollection) - ? new Uri(string.Format(nextUrlBase, offset + limit, limit)) - : null; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/Program.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/Program.cs deleted file mode 100644 index df5fdefb..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/Program.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure -{ - using Be.Vlaanderen.Basisregisters.Api; - using Microsoft.AspNetCore.Hosting; - - public static class Program - { - public static void Main(string[] args) => CreateWebHostBuilder(args).Build().Run(); - - public static IWebHostBuilder CreateWebHostBuilder(string[] args) - => new WebHostBuilder() - .UseDefaultForApi( - new ProgramOptions - { - Hosting = - { - HttpPort = 7002 - }, - Logging = - { - WriteTextToConsole = false, - WriteJsonToConsole = false - }, - Runtime = - { - CommandLineArgs = args - } - }); - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Infrastructure/Startup.cs b/src/ParcelRegistry.Api.Legacy/Infrastructure/Startup.cs deleted file mode 100755 index eb84fe75..00000000 --- a/src/ParcelRegistry.Api.Legacy/Infrastructure/Startup.cs +++ /dev/null @@ -1,158 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Infrastructure -{ - using System; - using System.Linq; - using System.Reflection; - using Asp.Versioning.ApiExplorer; - using Autofac; - using Autofac.Extensions.DependencyInjection; - using Be.Vlaanderen.Basisregisters.Api; - using Configuration; - using Microsoft.AspNetCore.Builder; - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Diagnostics.HealthChecks; - using Microsoft.Extensions.Hosting; - using Microsoft.Extensions.Logging; - using Microsoft.OpenApi.Models; - using Modules; - using Options; - - /// Represents the startup process for the application. - public class Startup - { - private const string DatabaseTag = "db"; - - private IContainer _applicationContainer; - - private readonly IConfiguration _configuration; - private readonly ILoggerFactory _loggerFactory; - - public Startup( - IConfiguration configuration, - ILoggerFactory loggerFactory) - { - _configuration = configuration; - _loggerFactory = loggerFactory; - } - - /// Configures services for the application. - /// The collection of services to configure the application with. - public IServiceProvider ConfigureServices(IServiceCollection services) - { - var baseUrl = _configuration.GetValue("BaseUrl"); - var baseUrlForExceptions = baseUrl.EndsWith("/") - ? baseUrl.Substring(0, baseUrl.Length - 1) - : baseUrl; - - services - .ConfigureDefaultForApi(new StartupConfigureOptions - { - Cors = - { - Origins = _configuration - .GetSection("Cors") - .GetChildren() - .Select(c => c.Value) - .ToArray() - }, - Server = - { - BaseUrl = baseUrlForExceptions - }, - Swagger = - { - ApiInfo = (provider, description) => new OpenApiInfo - { - Version = description.ApiVersion.ToString(), - Title = "Basisregisters Vlaanderen Parcel Registry API", - Description = GetApiLeadingText(description), - Contact = new OpenApiContact - { - Name = "Digitaal Vlaanderen", - Email = "digitaal.vlaanderen@vlaanderen.be", - Url = new Uri("https://legacy.basisregisters.vlaanderen") - } - }, - XmlCommentPaths = new[] {typeof(Startup).GetTypeInfo().Assembly.GetName().Name} - }, - MiddlewareHooks = - { - FluentValidation = fv => fv.RegisterValidatorsFromAssemblyContaining(), - - AfterHealthChecks = health => - { - var connectionStrings = _configuration - .GetSection("ConnectionStrings") - .GetChildren(); - - foreach (var connectionString in connectionStrings) - health.AddSqlServer( - connectionString.Value, - name: $"sqlserver-{connectionString.Key.ToLowerInvariant()}", - tags: new[] { DatabaseTag, "sql", "sqlserver" }); - } - } - }) - .Configure(_configuration); - - var containerBuilder = new ContainerBuilder(); - containerBuilder.RegisterModule(new ApiModule(_configuration, services, _loggerFactory)); - _applicationContainer = containerBuilder.Build(); - - return new AutofacServiceProvider(_applicationContainer); - } - - public void Configure( - IServiceProvider serviceProvider, - IApplicationBuilder app, - IWebHostEnvironment env, - IHostApplicationLifetime appLifetime, - ILoggerFactory loggerFactory, - IApiVersionDescriptionProvider apiVersionProvider, - HealthCheckService healthCheckService) - { - StartupHelpers.CheckDatabases(healthCheckService, DatabaseTag, loggerFactory).GetAwaiter().GetResult(); - - app - .UseDefaultForApi(new StartupUseOptions - { - Common = - { - ApplicationContainer = _applicationContainer, - ServiceProvider = serviceProvider, - HostingEnvironment = env, - ApplicationLifetime = appLifetime, - LoggerFactory = loggerFactory, - }, - Api = - { - VersionProvider = apiVersionProvider, - Info = groupName => $"Basisregisters Vlaanderen - Parcel Registry API {groupName}", - CSharpClientOptions = - { - ClassName = "ParcelRegistry", - Namespace = "Be.Vlaanderen.Basisregisters" - }, - TypeScriptClientOptions = - { - ClassName = "ParcelRegistry" - } - }, - Server = - { - PoweredByName = "Vlaamse overheid - Basisregisters Vlaanderen", - ServerName = "Digitaal Vlaanderen" - }, - MiddlewareHooks = - { - AfterMiddleware = x => x.UseMiddleware(), - } - }); - } - - private static string GetApiLeadingText(ApiVersionDescription description) - => $"Momenteel leest u de documentatie voor versie {description.ApiVersion} van de Basisregisters Vlaanderen Parcel Registry API{string.Format(description.IsDeprecated ? ", **deze API versie is niet meer ondersteund * *." : ".")}"; - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Count/ParcelCountRequest.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Count/ParcelCountRequest.cs deleted file mode 100644 index 798e3cac..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Count/ParcelCountRequest.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Count -{ - using Be.Vlaanderen.Basisregisters.Api.Search.Filtering; - using Be.Vlaanderen.Basisregisters.Api.Search.Pagination; - using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy; - using List; - using MediatR; - - public record ParcelCountRequest( - FilteringHeader Filtering, - SortingHeader Sorting, - IPaginationRequest Pagination) : IRequest; -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Count/ParcelCountV2Handler.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Count/ParcelCountV2Handler.cs deleted file mode 100644 index 6f15f809..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Count/ParcelCountV2Handler.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Count -{ - using System; - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy; - using List; - using MediatR; - using Microsoft.EntityFrameworkCore; - using ParcelRegistry.Projections.Legacy; - - public class ParcelCountV2Handler : IRequestHandler - { - private readonly LegacyContext _context; - - public ParcelCountV2Handler(LegacyContext context) - { - _context = context; - } - - public async Task Handle(ParcelCountRequest request, CancellationToken cancellationToken) - { - return new TotaalAantalResponse - { - Aantal = request.Filtering.ShouldFilter - ? await new ParcelListV2Query(_context) - .Fetch(request.Filtering, request.Sorting, request.Pagination) - .Items - .CountAsync(cancellationToken) - : Convert.ToInt32(_context - .ParcelDetailV2ListViewCount - .First() - .Count) - }; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Count/TotalCountResponseExample.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Count/TotalCountResponseExample.cs deleted file mode 100644 index 1cf14b94..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Count/TotalCountResponseExample.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Count -{ - using Be.Vlaanderen.Basisregisters.GrAr.Legacy; - using Swashbuckle.AspNetCore.Filters; - - public class TotalCountResponseExample : IExamplesProvider - { - public TotaalAantalResponse GetExamples() - { - return new TotaalAantalResponse - { - Aantal = 574512 - }; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailRequest.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailRequest.cs deleted file mode 100644 index a9cde6b7..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailRequest.cs +++ /dev/null @@ -1,6 +0,0 @@ -using MediatR; - -namespace ParcelRegistry.Api.Legacy.Parcel.Detail -{ - public record ParcelDetailRequest(string CaPaKey) : IRequest; -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailResponse.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailResponse.cs deleted file mode 100644 index c9dbd215..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailResponse.cs +++ /dev/null @@ -1,122 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Detail -{ - using Be.Vlaanderen.Basisregisters.GrAr.Legacy; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy.Perceel; - using Infrastructure.Options; - using Microsoft.AspNetCore.Http; - using Microsoft.Extensions.Options; - using Swashbuckle.AspNetCore.Filters; - using System; - using System.Collections.Generic; - using System.Linq; - using System.Runtime.Serialization; - using Be.Vlaanderen.Basisregisters.Api.Exceptions; - using Be.Vlaanderen.Basisregisters.GrAr.Common; - using Newtonsoft.Json; - using ProblemDetails = Be.Vlaanderen.Basisregisters.BasicApiProblem.ProblemDetails; - - [DataContract(Name = "PerceelDetail", Namespace = "")] - public class ParcelDetailResponse - { - /// - /// De identificator van het perceel. - /// - [DataMember(Name = "Identificator", Order = 1)] - [JsonProperty(Required = Required.DisallowNull)] - public PerceelIdentificator Identificator { get; set; } - - /// - /// De status van het perceel - /// - [DataMember(Name = "PerceelStatus", Order = 2)] - [JsonProperty(Required = Required.DisallowNull)] - public PerceelStatus PerceelStatus { get; set; } - - /// - /// De aan het perceel gekoppelde adressen. - /// - [DataMember(Name = "Adressen", Order = 3)] - [JsonProperty(Required = Required.DisallowNull)] - public List Adressen { get; set; } - - public ParcelDetailResponse( - string naamruimte, - PerceelStatus status, - string caPaKey, - DateTimeOffset version, - List addressPersistentLocalIds, - string adresDetailUrl) - { - Identificator = new PerceelIdentificator(naamruimte, caPaKey, version); - PerceelStatus = status; - - Adressen = addressPersistentLocalIds - .Where(x => !string.IsNullOrWhiteSpace(x)) - .Select(x => PerceelDetailAdres.Create(x, new Uri(string.Format(adresDetailUrl, x)))) - .ToList(); - } - } - - public class ParcelResponseExamples : IExamplesProvider - { - private readonly ResponseOptions _responseOptions; - - public ParcelResponseExamples(IOptions responseOptionsProvider) - => _responseOptions = responseOptionsProvider.Value; - - public ParcelDetailResponse GetExamples() - => new ParcelDetailResponse( - _responseOptions.Naamruimte, - PerceelStatus.Gerealiseerd, - "11001B0001-00S000", - DateTimeOffset.Now.ToExampleOffset(), - new List { "200001" }, - _responseOptions.AdresDetailUrl); - } - - public class ParcelNotFoundResponseExamples : IExamplesProvider - { - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly ProblemDetailsHelper _problemDetailsHelper; - - public ParcelNotFoundResponseExamples( - IHttpContextAccessor httpContextAccessor, - ProblemDetailsHelper problemDetailsHelper) - { - _httpContextAccessor = httpContextAccessor; - _problemDetailsHelper = problemDetailsHelper; - } - - public ProblemDetails GetExamples() => new ProblemDetails - { - ProblemTypeUri = "urn:be.vlaanderen.basisregisters.api:parcel:not-found", - HttpStatus = StatusCodes.Status404NotFound, - Title = ProblemDetails.DefaultTitle, - Detail = "Onbestaand perceel.", - ProblemInstanceUri = _problemDetailsHelper.GetInstanceUri(_httpContextAccessor.HttpContext, "v1") - }; - } - - public class ParcelGoneResponseExamples : IExamplesProvider - { - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly ProblemDetailsHelper _problemDetailsHelper; - - public ParcelGoneResponseExamples( - IHttpContextAccessor httpContextAccessor, - ProblemDetailsHelper problemDetailsHelper) - { - _httpContextAccessor = httpContextAccessor; - _problemDetailsHelper = problemDetailsHelper; - } - - public ProblemDetails GetExamples() => new ProblemDetails - { - ProblemTypeUri = "urn:be.vlaanderen.basisregisters.api:parcel:gone", - HttpStatus = StatusCodes.Status410Gone, - Title = ProblemDetails.DefaultTitle, - Detail = "Verwijderd perceel.", - ProblemInstanceUri = _problemDetailsHelper.GetInstanceUri(_httpContextAccessor.HttpContext, "v1") - }; - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailResponseWithEtag.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailResponseWithEtag.cs deleted file mode 100644 index bcb8af44..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailResponseWithEtag.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Detail -{ - public class ParcelResponseWithEtag - { - public ParcelDetailResponse ParcelResponse { get; } - public string? LastEventHash { get; } - - public ParcelResponseWithEtag(ParcelDetailResponse parcelResponse, string? lastEventHash = null) - { - ParcelResponse = parcelResponse; - LastEventHash = lastEventHash; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailV2Handler.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailV2Handler.cs deleted file mode 100644 index ca9d2e03..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Detail/ParcelDetailV2Handler.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Detail -{ - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using Be.Vlaanderen.Basisregisters.Api.Exceptions; - using Be.Vlaanderen.Basisregisters.GrAr.Common; - using Convertors; - using Infrastructure.Options; - using MediatR; - using Microsoft.AspNetCore.Http; - using Microsoft.EntityFrameworkCore; - using Microsoft.Extensions.Options; - using Projections.Legacy; - - public class ParcelDetailV2Handler : IRequestHandler - { - private readonly LegacyContext _context; - private readonly IOptions _responseOptions; - - public ParcelDetailV2Handler( - LegacyContext context, - IOptions responseOptions) - { - _context = context; - _responseOptions = responseOptions; - } - - public async Task Handle(ParcelDetailRequest request, CancellationToken cancellationToken) - { - var parcel = - await _context - .ParcelDetailWithCountV2 - .Include(x => x.Addresses) - .AsNoTracking() - .SingleOrDefaultAsync(item => item.CaPaKey == request.CaPaKey, cancellationToken); - - if (parcel is null) - { - throw new ApiException("Onbestaand perceel.", StatusCodes.Status404NotFound); - } - - if (parcel is { Removed: true }) - { - throw new ApiException("Perceel werd verwijderd.", StatusCodes.Status410Gone); - } - - var response = new ParcelDetailResponse( - _responseOptions.Value.Naamruimte, - parcel.Status.MapToPerceelStatus(), - parcel.CaPaKey, - parcel.VersionTimestamp.ToBelgianDateTimeOffset(), - parcel.Addresses - .Select(x => x.AddressPersistentLocalId.ToString()) - .OrderBy(x => x) - .ToList(), - _responseOptions.Value.AdresDetailUrl); - - return new ParcelResponseWithEtag(response, parcel.LastEventHash); - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListRequest.cs b/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListRequest.cs deleted file mode 100644 index e49ae060..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListRequest.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.List -{ - using Be.Vlaanderen.Basisregisters.Api.Search.Filtering; - using Be.Vlaanderen.Basisregisters.Api.Search.Pagination; - using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; - using MediatR; - - public record ParcelListRequest( - FilteringHeader Filtering, - SortingHeader Sorting, - IPaginationRequest Pagination) : IRequest; -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListResponse.cs b/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListResponse.cs deleted file mode 100644 index 58ce744b..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListResponse.cs +++ /dev/null @@ -1,110 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.List -{ - using System; - using System.Collections.Generic; - using System.Runtime.Serialization; - using Be.Vlaanderen.Basisregisters.Api.Search.Pagination; - using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; - using Be.Vlaanderen.Basisregisters.GrAr.Common; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy.Perceel; - using Microsoft.Extensions.Options; - using Newtonsoft.Json; - using ParcelRegistry.Api.Legacy.Infrastructure.Options; - using Swashbuckle.AspNetCore.Filters; - - [DataContract(Name = "PerceelCollectie", Namespace = "")] - public class ParcelListResponse - { - /// - /// De verzameling van percelen. - /// - [DataMember(Name = "Percelen", Order = 0)] - [JsonProperty(Required = Required.DisallowNull)] - public List Percelen { get; set; } - - /// - /// Het totaal aantal percelen die overeenkomen met de vraag. - /// - //[DataMember(Name = "TotaalAantal", Order = 1)] - //[JsonProperty(Required = Required.DisallowNull)] - //public long TotaalAantal { get; set; } - - /// - /// De URL voor het ophalen van de volgende verzameling. - /// - [DataMember(Name = "Volgende", Order = 2, EmitDefaultValue = false)] - [JsonProperty(Required = Required.Default, DefaultValueHandling = DefaultValueHandling.Ignore)] - public Uri Volgende { get; set; } - - [JsonIgnore] - [IgnoreDataMember] - public SortingHeader Sorting { get; set; } - - [JsonIgnore] - [IgnoreDataMember] - public PaginationInfo Pagination { get; set; } - } - - [DataContract(Name = "PerceelCollectieItem", Namespace = "")] - public class ParcelListItemResponse - { - /// - /// De identificator van het perceel. - /// - [DataMember(Name = "Identificator", Order = 1)] - [JsonProperty(Required = Required.DisallowNull)] - public PerceelIdentificator Identificator { get; set; } - - /// - /// De URL die de details van de meest recente versie van het perceel weergeeft. - /// - [DataMember(Name = "Detail", Order = 2)] - [JsonProperty(Required = Required.DisallowNull)] - public Uri Detail { get; set; } - - /// - /// De status van het perceel - /// - [DataMember(Name = "PerceelStatus", Order = 3)] - [JsonProperty(Required = Required.DisallowNull)] - public PerceelStatus PerceelStatus { get; set; } - - public ParcelListItemResponse( - string id, - string naamruimte, - string detail, - PerceelStatus status, - DateTimeOffset version) - { - Identificator = new PerceelIdentificator(naamruimte, id, version); - Detail = new Uri(string.Format(detail, id)); - PerceelStatus = status; - } - } - - public class ParcelListResponseExamples : IExamplesProvider - { - private readonly ResponseOptions _responseOptions; - - public ParcelListResponseExamples(IOptions responseOptionsProvider) - { - _responseOptions = responseOptionsProvider.Value; - } - - public ParcelListResponse GetExamples() - { - var samples = new List - { - new ParcelListItemResponse("11001B0001-00S000", _responseOptions.Naamruimte, _responseOptions.DetailUrl, PerceelStatus.Gerealiseerd, DateTimeOffset.Now.ToExampleOffset()), - new ParcelListItemResponse("11001B0009-00G004", _responseOptions.Naamruimte, _responseOptions.DetailUrl, PerceelStatus.Gerealiseerd, DateTimeOffset.Now.AddHours(-40).ToExampleOffset()) - }; - - return new ParcelListResponse - { - Percelen = samples, - Volgende = new Uri(string.Format(_responseOptions.VolgendeUrl, 2, 10)) - }; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Handler.cs b/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Handler.cs deleted file mode 100644 index 72a7dfa8..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Handler.cs +++ /dev/null @@ -1,50 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.List -{ - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using Be.Vlaanderen.Basisregisters.GrAr.Common; - using MediatR; - using Microsoft.EntityFrameworkCore; - using Microsoft.Extensions.Options; - using Convertors; - using Infrastructure; - using Infrastructure.Options; - using ParcelRegistry.Projections.Legacy; - - public class ParcelListV2Handler : IRequestHandler - { - private readonly LegacyContext _context; - private readonly IOptions _responseOptions; - - public ParcelListV2Handler( - LegacyContext context, - IOptions responseOptions) - { - _context = context; - _responseOptions = responseOptions; - } - public async Task Handle(ParcelListRequest request, CancellationToken cancellationToken) - { - var pagedParcels = new ParcelListV2Query(_context) - .Fetch(request.Filtering, request.Sorting, request.Pagination); - - var parcelListItemResponses = await pagedParcels.Items - .Select(m => new ParcelListItemResponse( - m.CaPaKey, - _responseOptions.Value.Naamruimte, - _responseOptions.Value.DetailUrl, - m.Status.MapToPerceelStatus(), - m.VersionTimestamp.ToBelgianDateTimeOffset())) - .ToListAsync(cancellationToken); - - return new ParcelListResponse - { - Percelen = parcelListItemResponses, - Volgende = pagedParcels.PaginationInfo.BuildVolgendeUri(parcelListItemResponses.Count, _responseOptions.Value.VolgendeUrl), - Sorting = pagedParcels.Sorting, - Pagination = pagedParcels.PaginationInfo - }; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Query.cs b/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Query.cs deleted file mode 100644 index dea4df14..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2Query.cs +++ /dev/null @@ -1,92 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.List -{ - using System; - using System.Collections.Generic; - using System.Linq; - using Be.Vlaanderen.Basisregisters.Api.Search; - using Be.Vlaanderen.Basisregisters.Api.Search.Filtering; - using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy.Perceel; - using Convertors; - using Microsoft.EntityFrameworkCore; - using ParcelRegistry.Projections.Legacy; - using Projections.Legacy.ParcelDetail; - - public class ParcelListV2Query : Query - { - private readonly LegacyContext _context; - - protected override ISorting Sorting => new ParcelSortingV2(); - - public ParcelListV2Query(LegacyContext context) => _context = context; - - protected override IQueryable Filter(FilteringHeader filtering) - { - var parcels = _context - .ParcelDetailWithCountV2 - .AsNoTracking() - .OrderBy(x => x.CaPaKey) - .Where(x => !x.Removed); - - if (!filtering.ShouldFilter) - { - return parcels - .Select(x => new ParcelListV2QueryItem - { - CaPaKey = x.CaPaKey, - StatusAsString = x.StatusAsString, - VersionTimestampAsDateTimeOffset = x.VersionTimestampAsDateTimeOffset - }); - } - - if (!string.IsNullOrEmpty(filtering.Filter.AddressId)) - { - if (int.TryParse(filtering.Filter.AddressId, out var addressId)) - { - parcels = parcels.Where(x => x.Addresses.Any(parcelDetailAddress => parcelDetailAddress.AddressPersistentLocalId == addressId)); - } - else - { - return new List().AsQueryable(); - } - } - - if (!string.IsNullOrEmpty(filtering.Filter.Status)) - { - if (Enum.TryParse(typeof(PerceelStatus), filtering.Filter.Status, true, out var status)) - { - var parcelStatus = ((PerceelStatus)status).MapToParcelStatus(); - parcels = parcels.Where(m => m.StatusAsString == parcelStatus.Status); - } - else - { - return new List().AsQueryable(); - } - } - - return parcels - .Select(x => new ParcelListV2QueryItem - { - CaPaKey = x.CaPaKey, - StatusAsString = x.StatusAsString, - VersionTimestampAsDateTimeOffset = x.VersionTimestampAsDateTimeOffset - });; - } - } - - public class ParcelFilter - { - public string Status { get; set; } - public string AddressId { get; set; } - } - - public class ParcelSortingV2 : ISorting - { - public IEnumerable SortableFields { get; } = new[] - { - nameof(ParcelDetail.CaPaKey), - }; - - public SortingHeader DefaultSortingHeader { get; } = new SortingHeader(nameof(ParcelDetail.CaPaKey), SortOrder.Ascending); - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2QueryItem.cs b/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2QueryItem.cs deleted file mode 100644 index 222d2e40..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/List/ParcelListV2QueryItem.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.List -{ - using System; - using NodaTime; - using ParcelRegistry.Parcel; - - public sealed class ParcelListV2QueryItem - { - public string CaPaKey { get; init; } - public ParcelStatus Status => ParcelStatus.Parse(StatusAsString); - - public string StatusAsString { get; init; } - - public DateTimeOffset VersionTimestampAsDateTimeOffset { get; init; } - - public Instant VersionTimestamp => Instant.FromDateTimeOffset(VersionTimestampAsDateTimeOffset); - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/ParcelController.cs b/src/ParcelRegistry.Api.Legacy/Parcel/ParcelController.cs deleted file mode 100755 index 1b689cd9..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/ParcelController.cs +++ /dev/null @@ -1,137 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel -{ - using System.Net.Mime; - using System.Threading; - using System.Threading.Tasks; - using Asp.Versioning; - using Be.Vlaanderen.Basisregisters.Api; - using Be.Vlaanderen.Basisregisters.Api.ETag; - using Be.Vlaanderen.Basisregisters.Api.Exceptions; - using Be.Vlaanderen.Basisregisters.Api.Search.Filtering; - using Be.Vlaanderen.Basisregisters.Api.Search.Pagination; - using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy; - using Count; - using List; - using MediatR; - using Microsoft.AspNetCore.Http; - using Microsoft.AspNetCore.Mvc; - using Detail; - using Swashbuckle.AspNetCore.Filters; - using Sync; - using ProblemDetails = Be.Vlaanderen.Basisregisters.BasicApiProblem.ProblemDetails; - - [ApiVersion("1.0")] - [AdvertiseApiVersions("1.0")] - [ApiRoute("percelen")] - [ApiExplorerSettings(GroupName = "Percelen")] - public class ParcelController : ApiController - { - private readonly IMediator _mediator; - - public ParcelController(IMediator mediator) - { - _mediator = mediator; - } - - /// - /// Vraag een perceel op. - /// - /// Identificator van het perceel. - /// - /// Als het perceel gevonden is. - /// Als het perceel niet gevonden kan worden. - /// Als het perceel verwijderd is. - /// Als er een interne fout is opgetreden. - [HttpGet("{caPaKey}")] - [ProducesResponseType(typeof(ParcelDetailResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status410Gone)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] - [SwaggerResponseExample(StatusCodes.Status200OK, typeof(ParcelResponseExamples))] - [SwaggerResponseExample(StatusCodes.Status404NotFound, typeof(ParcelNotFoundResponseExamples))] - [SwaggerResponseExample(StatusCodes.Status410Gone, typeof(ParcelGoneResponseExamples))] - [SwaggerResponseExample(StatusCodes.Status500InternalServerError, typeof(InternalServerErrorResponseExamples))] - public async Task Get( - [FromRoute] string caPaKey, - CancellationToken cancellationToken = default) - { - var response = await _mediator.Send(new ParcelDetailRequest(caPaKey), cancellationToken); - - return string.IsNullOrWhiteSpace(response.LastEventHash) - ? Ok(response.ParcelResponse) - : new OkWithLastObservedPositionAsETagResult(response.ParcelResponse, response.LastEventHash); - } - - /// - /// Vraag een lijst met actieve percelen op. - /// - /// - /// Als de opvraging van een lijst met percelen gelukt is. - /// Als er een interne fout is opgetreden. - [HttpGet] - [ProducesResponseType(typeof(ParcelListResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] - [SwaggerResponseExample(StatusCodes.Status200OK, typeof(ParcelListResponseExamples))] - [SwaggerResponseExample(StatusCodes.Status500InternalServerError, typeof(InternalServerErrorResponseExamples))] - public async Task List( - CancellationToken cancellationToken = default) - { - var filtering = Request.ExtractFilteringRequest(); - var sorting = Request.ExtractSortingRequest(); - var pagination = Request.ExtractPaginationRequest(); - - var result = await _mediator.Send(new ParcelListRequest(filtering, sorting, pagination), cancellationToken); - - Response.AddPaginationResponse(result.Pagination); - Response.AddSortingResponse(result.Sorting); - - return Ok(result); - } - - /// - /// Vraag het totaal aantal actieve percelen op. - /// - /// - /// Als de opvraging van het totaal aantal gelukt is. - /// Als er een interne fout is opgetreden. - [HttpGet("totaal-aantal")] - [ProducesResponseType(typeof(TotaalAantalResponse), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] - [SwaggerResponseExample(StatusCodes.Status200OK, typeof(TotalCountResponseExample))] - [SwaggerResponseExample(StatusCodes.Status500InternalServerError, typeof(InternalServerErrorResponseExamples))] - public async Task Count(CancellationToken cancellationToken = default) - { - var filtering = Request.ExtractFilteringRequest(); - var sorting = Request.ExtractSortingRequest(); - var pagination = new NoPaginationRequest(); - - var result = await _mediator.Send(new ParcelCountRequest(filtering, sorting, pagination), cancellationToken); - - return Ok(result); - } - - /// - /// Vraag een lijst met wijzigingen van percelen op. - /// - /// - /// - [HttpGet("sync")] - [Produces("text/xml")] - [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] - [SwaggerResponseExample(StatusCodes.Status200OK, typeof(ParcelSyndicationResponseExamples))] - [SwaggerResponseExample(StatusCodes.Status400BadRequest, typeof(BadRequestResponseExamples))] - [SwaggerResponseExample(StatusCodes.Status500InternalServerError, typeof(InternalServerErrorResponseExamples))] - public async Task Sync(CancellationToken cancellationToken = default) - { - return new ContentResult - { - Content = await _mediator.Send(new SyncRequest(Request), cancellationToken), - ContentType = MediaTypeNames.Text.Xml, - StatusCode = StatusCodes.Status200OK - }; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Sync/ParcelSyndicationQuery.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Sync/ParcelSyndicationQuery.cs deleted file mode 100644 index 4a9af6c1..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Sync/ParcelSyndicationQuery.cs +++ /dev/null @@ -1,254 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Sync -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Linq.Expressions; - using Be.Vlaanderen.Basisregisters.Api.Search; - using Be.Vlaanderen.Basisregisters.Api.Search.Filtering; - using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; - using Be.Vlaanderen.Basisregisters.GrAr.Provenance; - using Microsoft.EntityFrameworkCore; - using NodaTime; - using ParcelRegistry.Parcel; - using ParcelRegistry.Projections.Legacy; - using ParcelRegistry.Projections.Legacy.ParcelSyndication; - using ParcelStatus = ParcelRegistry.Legacy.ParcelStatus; - - public class ParcelSyndicationQueryResult - { - public bool ContainsEvent { get; } - public bool ContainsObject { get; } - - public Guid ParcelId { get; } - public long Position { get; } - public string CaPaKey { get; } - public string ChangeType { get; } - public Instant RecordCreatedAt { get; } - public Instant LastChangedOn { get; } - public ParcelStatus? Status { get; } - public IEnumerable AddressIds { get; } = new List(); - public byte[]? ExtendedWkbGeometry { get; } - public Organisation? Organisation { get; } - public string Reason { get; } - public string EventDataAsXml { get; } - - public ParcelSyndicationQueryResult( - Guid parcelId, - long position, - string caPaKey, - string changeType, - Instant recordCreateAt, - Instant lastChangedOn, - Organisation? organisation, - string reason) - { - ContainsObject = false; - ContainsEvent = false; - - ParcelId = parcelId; - Position = position; - CaPaKey = caPaKey; - ChangeType = changeType; - RecordCreatedAt = recordCreateAt; - LastChangedOn = lastChangedOn; - Organisation = organisation; - Reason = reason; - } - - public ParcelSyndicationQueryResult( - Guid parcelId, - long position, - string caPaKey, - string changeType, - Instant recordCreateAt, - Instant lastChangedOn, - Organisation? organisation, - string reason, - string eventDataAsXml) - : this( - parcelId, - position, - caPaKey, - changeType, - recordCreateAt, - lastChangedOn, - organisation, - reason) - { - ContainsEvent = true; - - EventDataAsXml = eventDataAsXml; - } - - public ParcelSyndicationQueryResult( - Guid parcelId, - long position, - string caPaKey, - string changeType, - Instant recordCreateAt, - Instant lastChangedOn, - ParcelStatus? status, - IEnumerable addressIds, - IEnumerable addressPersistentLocalIds, - Organisation? organisation, - byte[]? extendedWkbGeometry, - string reason) - : this( - parcelId, - position, - caPaKey, - changeType, - recordCreateAt, - lastChangedOn, - organisation, - reason) - { - ContainsObject = true; - - Status = status; - AddressIds = addressIds.Select(y => y.ToString()).Concat(addressPersistentLocalIds.Select(y => y.ToString())).ToList(); - ExtendedWkbGeometry = extendedWkbGeometry; - } - - public ParcelSyndicationQueryResult( - Guid parcelId, - long position, - string caPaKey, - string changeType, - Instant recordCreateAt, - Instant lastChangedOn, - ParcelStatus? status, - IEnumerable addressIds, - IEnumerable addressPersistentLocalIds, - Organisation? organisation, - byte[]? extendedWkbGeometry, - string reason, - string eventDataAsXml) - : this( - parcelId, - position, - caPaKey, - changeType, - recordCreateAt, - lastChangedOn, - status, - addressIds, - addressPersistentLocalIds, - organisation, - extendedWkbGeometry, - reason) - { - ContainsEvent = true; - - EventDataAsXml = eventDataAsXml; - } - } - - public class ParcelSyndicationQuery : Query - { - private readonly LegacyContext _context; - private readonly bool _embedEvent; - private readonly bool _embedObject; - - public ParcelSyndicationQuery(LegacyContext context, SyncEmbedValue embed) - { - _context = context; - _embedEvent = embed?.Event ?? false; - _embedObject = embed?.Object ?? false; - } - - protected override ISorting Sorting => new ParcelSyndicationSorting(); - - protected override Expression> Transformation - { - get - { - if (_embedObject && _embedEvent) - return x => new ParcelSyndicationQueryResult( - x.ParcelId.Value, - x.Position, - x.CaPaKey, - x.ChangeType, - x.RecordCreatedAt, - x.LastChangedOn, - x.Status, - x.AddressIds, - x.AddressPersistentLocalIds, - x.Organisation, - x.ExtendedWkbGeometry, - x.Reason, - x.EventDataAsXml); - - if (_embedEvent) - return x => new ParcelSyndicationQueryResult( - x.ParcelId.Value, - x.Position, - x.CaPaKey, - x.ChangeType, - x.RecordCreatedAt, - x.LastChangedOn, - x.Organisation, - x.Reason, - x.EventDataAsXml); - - if (_embedObject) - return x => new ParcelSyndicationQueryResult( - x.ParcelId.Value, - x.Position, - x.CaPaKey, - x.ChangeType, - x.RecordCreatedAt, - x.LastChangedOn, - x.Status, - x.AddressIds, - x.AddressPersistentLocalIds, - x.Organisation, - x.ExtendedWkbGeometry, - x.Reason); - - return x => new ParcelSyndicationQueryResult( - x.ParcelId.Value, - x.Position, - x.CaPaKey, - x.ChangeType, - x.RecordCreatedAt, - x.LastChangedOn, - x.Organisation, - x.Reason); - } - } - - protected override IQueryable Filter(FilteringHeader filtering) - { - var parcels = _context - .ParcelSyndication - .OrderBy(x => x.Position) - .AsNoTracking(); - - if (!filtering.ShouldFilter) - return parcels; - - if (filtering.Filter.Position.HasValue) - parcels = parcels.Where(m => m.Position >= filtering.Filter.Position); - - return parcels; - } - } - - public class ParcelSyndicationSorting : ISorting - { - public IEnumerable SortableFields { get; } = new[] - { - nameof(ParcelSyndicationItem.Position) - }; - - public SortingHeader DefaultSortingHeader { get; } = new SortingHeader(nameof(ParcelSyndicationItem.Position), SortOrder.Ascending); - } - - public class ParcelSyndicationFilter - { - public long? Position { get; set; } - public SyncEmbedValue Embed { get; set; } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Sync/ParcelSyndicationResponse.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Sync/ParcelSyndicationResponse.cs deleted file mode 100644 index 1991e837..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Sync/ParcelSyndicationResponse.cs +++ /dev/null @@ -1,268 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Sync -{ - using System; - using System.Collections.Generic; - using System.Globalization; - using System.Linq; - using System.Runtime.Serialization; - using System.Threading.Tasks; - using System.Xml; - using Be.Vlaanderen.Basisregisters.GrAr.Common; - using Be.Vlaanderen.Basisregisters.GrAr.Common.Syndication; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy.Perceel; - using Be.Vlaanderen.Basisregisters.GrAr.Legacy.SpatialTools; - using Be.Vlaanderen.Basisregisters.GrAr.Provenance; - using Convertors; - using Infrastructure.Options; - using Microsoft.Extensions.Options; - using Microsoft.SyndicationFeed; - using Microsoft.SyndicationFeed.Atom; - using NetTopologySuite.Geometries; - using NetTopologySuite.IO; - using Swashbuckle.AspNetCore.Filters; - using Polygon = NetTopologySuite.Geometries.Polygon; - using Provenance = Be.Vlaanderen.Basisregisters.GrAr.Provenance.Syndication.Provenance; - - public static class ParcelSyndicationResponse - { - private static readonly WKBReader WkbReader = WKBReaderFactory.Create(); - - public static async Task WriteParcel( - this ISyndicationFeedWriter writer, - IOptions responseOptions, - AtomFormatter formatter, - string category, - ParcelSyndicationQueryResult parcel) - { - var item = new SyndicationItem - { - Id = parcel.Position.ToString(CultureInfo.InvariantCulture), - Title = $"{parcel.ChangeType}-{parcel.Position}", - Published = parcel.RecordCreatedAt.ToBelgianDateTimeOffset(), - LastUpdated = parcel.LastChangedOn.ToBelgianDateTimeOffset(), - Description = BuildDescription(parcel, responseOptions.Value.Naamruimte) - }; - - item.AddLink( - new SyndicationLink( - new Uri($"{responseOptions.Value.Naamruimte}/{parcel.CaPaKey}"), - AtomLinkTypes.Related)); - - //item.AddLink( - // new SyndicationLink( - // new Uri(string.Format(responseOptions.Value.DetailUrl, parcel.CaPaKey)), - // AtomLinkTypes.Self)); - - //item.AddLink( - // new SyndicationLink( - // new Uri(string.Format($"{responseOptions.Value.DetailUrl}.xml", parcel.CaPaKey)), - // AtomLinkTypes.Alternate) - // { MediaType = MediaTypeNames.Application.Xml }); - - //item.AddLink( - // new SyndicationLink( - // new Uri(string.Format($"{responseOptions.Value.DetailUrl}.json", parcel.CaPaKey)), - // AtomLinkTypes.Alternate) - // { MediaType = MediaTypeNames.Application.Json }); - - item.AddCategory( - new SyndicationCategory(category)); - - item.AddContributor( - new SyndicationPerson( - parcel.Organisation == null ? Organisation.Unknown.ToName() : parcel.Organisation.Value.ToName(), - string.Empty, - AtomContributorTypes.Author)); - - await writer.Write(item); - } - - private static string BuildDescription(ParcelSyndicationQueryResult parcel, string naamruimte) - { - if (!parcel.ContainsEvent && !parcel.ContainsObject) - return "No data embedded"; - - var content = new SyndicationContent(); - if(parcel.ContainsObject) - { - var geometry = parcel.ExtendedWkbGeometry is null - ? null - : WkbReader.Read(parcel.ExtendedWkbGeometry); - - content.Object = new ParcelSyndicationContent( - parcel.ParcelId, - naamruimte, - parcel.CaPaKey, - parcel.LastChangedOn.ToBelgianDateTimeOffset(), - parcel.Status.MapToPerceelStatusSyndication(), - parcel.AddressIds, - geometry is MultiPolygon - ? GmlMultiSurfaceBuilder.Build(parcel.ExtendedWkbGeometry!, WkbReader) - : null, - geometry is Polygon - ? PolygonBuilder.Build(parcel.ExtendedWkbGeometry!, WkbReader)?.XmlPolygon - : null, - parcel.Organisation, - parcel.Reason); - } - - if (parcel.ContainsEvent) - { - var doc = new XmlDocument(); - doc.LoadXml(parcel.EventDataAsXml); - content.Event = doc.DocumentElement; - } - - return content.ToXml(); - } - } - - [DataContract(Name = "Content", Namespace = "")] - public class SyndicationContent : SyndicationContentBase - { - [DataMember(Name = "Event")] - public XmlElement Event { get; set; } - - [DataMember(Name = "Object")] - public ParcelSyndicationContent Object { get; set; } - } - - [DataContract(Name = "Perceel", Namespace = "")] - public class ParcelSyndicationContent - { - /// - /// De technische id van het perceel. - /// - [DataMember(Name = "Id", Order = 1)] - public Guid ParcelId { get; set; } - - /// - /// De identificator van het perceel. - /// - [DataMember(Name = "Identificator", Order = 2)] - public PerceelIdentificator Identificator { get; set; } - - /// - /// De status van het perceel. - /// - [DataMember(Name = "PerceelStatus", Order = 3)] - public PerceelStatus? Status { get; set; } - - /// - /// De aan het perceel gelinkte adressen - /// - [DataMember(Name = "AdressenIds", Order = 4)] - public List AddressIds { get; set; } - - /// - /// De geometrie multi-polygoon van het perceel. - /// - [DataMember(Name = "GeometrieMultiPolygoon", Order = 5)] - public SyndicationMultiSurface MultiSurfacePolygon { get; set; } - - /// - /// De geometrie polygoon van het perceel. - /// - [DataMember(Name = "GeometriePolygoon", Order = 6)] - public SyndicationPolygon Polygon { get; set; } - - /// - /// Creatie data ivm het item. - /// - [DataMember(Name = "Creatie", Order = 7)] - public Provenance Provenance { get; set; } - - public ParcelSyndicationContent( - Guid parcelId, - string naamruimte, - string caPaKey, - DateTimeOffset version, - PerceelStatus? status, - IEnumerable addressIds, - GmlMultiSurface? gmlMultiSurface, - GmlPolygon? gmlPolygon, - Organisation? organisation, - string reason) - { - ParcelId = parcelId; - Identificator = new PerceelIdentificator(naamruimte, string.IsNullOrEmpty(caPaKey) ? string.Empty : caPaKey, version); - Status = status; - AddressIds = addressIds.ToList(); - if (gmlMultiSurface != null) - { - MultiSurfacePolygon = new SyndicationMultiSurface { XmlMultiSurface = gmlMultiSurface }; - } - - if (gmlPolygon != null) - { - Polygon = new SyndicationPolygon { XmlPolygon = gmlPolygon }; - } - - Provenance = new Provenance(version, organisation, new Reason(reason)); - } - } - - public class ParcelSyndicationResponseExamples : IExamplesProvider - { - private const string RawXml = @" - - https://api.basisregisters.vlaanderen.be/v1/feeds/percelen.atom - Basisregisters Vlaanderen - feed 'percelen' - Deze Atom feed geeft leestoegang tot events op de resource 'percelen'. - Basisregisters Vlaanderen - Gratis hergebruik volgens https://overheid.vlaanderen.be/sites/default/files/documenten/ict-egov/licenties/hergebruik/modellicentie_gratis_hergebruik_v1_0.html - 2020-11-06T19:36:06Z - - Digitaal Vlaanderen - digitaal.vlaanderen@vlaanderen.be - - - - - - - - 0 - ParcelWasRegistered-0 - 2012-09-23T23:13:50+02:00 - 2012-09-23T23:13:50+02:00 - - - Gemeente - - - - 10ad670a-ab6e-5fda-9a8a-733e11f5990202012-09-23T21:13:50ZMunicipalityDecentrale bijhouding CRAB - - 10ad670a-ab6e-5fda-9a8a-733e11f59902https://data.vlaanderen.be/id/perceel/0https://data.vlaanderen.be/id/perceel02012-09-23T23:13:50+02:00Gerealiseerd2012-09-23T23:13:50+02:00GemeenteDecentrale bijhouding CRAB - ]]> - - - - 1 - ParcelWasRealized-1 - 2012-09-23T23:13:50+02:00 - 2012-09-23T23:13:50+02:00 - - - Gemeente - - - - 10ad670a-ab6e-5fda-9a8a-733e11f599022012-09-23T21:13:50ZMunicipalityDecentrale bijhouding CRAB - - 10ad670a-ab6e-5fda-9a8a-733e11f59902https://data.vlaanderen.be/id/perceel/0https://data.vlaanderen.be/id/perceel02012-09-23T23:13:50+02:00Gerealiseerd2012-09-23T23:13:50+02:00GemeenteDecentrale bijhouding CRAB - ]]> - - -"; - - public XmlElement GetExamples() - { - var example = new XmlDocument(); - example.LoadXml(RawXml); - return example.DocumentElement; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Sync/SyncHandler.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Sync/SyncHandler.cs deleted file mode 100644 index 38544dd5..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Sync/SyncHandler.cs +++ /dev/null @@ -1,105 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Sync -{ - using System; - using System.Linq; - using System.Text; - using System.Threading; - using System.Threading.Tasks; - using System.Xml; - using Be.Vlaanderen.Basisregisters.Api.Search.Filtering; - using Be.Vlaanderen.Basisregisters.Api.Search.Pagination; - using Be.Vlaanderen.Basisregisters.Api.Search.Sorting; - using Be.Vlaanderen.Basisregisters.Api.Syndication; - using Be.Vlaanderen.Basisregisters.GrAr.Common; - using MediatR; - using Microsoft.EntityFrameworkCore; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Options; - using Microsoft.SyndicationFeed; - using Microsoft.SyndicationFeed.Atom; - using ParcelRegistry.Api.Legacy.Infrastructure; - using ParcelRegistry.Api.Legacy.Infrastructure.Options; - using ParcelRegistry.Projections.Legacy; - - public class SyncHandler : IRequestHandler - { - private readonly IConfiguration _configuration; - private readonly LegacyContext _context; - private readonly IOptions _responseOptions; - - public SyncHandler( - IConfiguration configuration, - LegacyContext context, - IOptions responseOptions) - { - _configuration = configuration; - _context = context; - _responseOptions = responseOptions; - } - public async Task Handle(SyncRequest request, CancellationToken cancellationToken) - { - var filtering = request.HttpRequest.ExtractFilteringRequest(); - var sorting = request.HttpRequest.ExtractSortingRequest(); - var pagination = request.HttpRequest.ExtractPaginationRequest(); - - var lastFeedUpdate = await _context - .ParcelSyndication - .AsNoTracking() - .OrderByDescending(item => item.Position) - .Select(item => item.SyndicationItemCreatedAt) - .FirstOrDefaultAsync(cancellationToken); - - if (lastFeedUpdate == default) - lastFeedUpdate = new DateTimeOffset(2020, 1, 1, 0, 0, 0, TimeSpan.Zero); - - var pagedParcels = new ParcelSyndicationQuery( - _context, - filtering.Filter?.Embed) - .Fetch(filtering, sorting, pagination); - - return await BuildAtomFeed(lastFeedUpdate, pagedParcels, _responseOptions, _configuration); - } - - private static async Task BuildAtomFeed( - DateTimeOffset lastUpdate, - PagedQueryable pagedParcels, - IOptions responseOptions, - IConfiguration configuration) - { - var sw = new StringWriterWithEncoding(Encoding.UTF8); - - using (var xmlWriter = XmlWriter.Create(sw, new XmlWriterSettings { Async = true, Indent = true, Encoding = sw.Encoding })) - { - var formatter = new AtomFormatter(null, xmlWriter.Settings) { UseCDATA = true }; - var writer = new AtomFeedWriter(xmlWriter, null, formatter); - var syndicationConfiguration = configuration.GetSection("Syndication"); - var atomConfiguration = AtomFeedConfigurationBuilder.CreateFrom(syndicationConfiguration, lastUpdate); - - await writer.WriteDefaultMetadata(atomConfiguration); - - var parcels = pagedParcels.Items.ToList(); - var nextFrom = parcels.Any() - ? parcels.Max(x => x.Position) + 1 - : (long?)null; - - var nextUri = BuildNextSyncUri(pagedParcels.PaginationInfo.Limit, nextFrom, syndicationConfiguration["NextUri"]); - if (nextUri != null) - await writer.Write(new SyndicationLink(nextUri, "next")); - - foreach (var parcel in pagedParcels.Items) - await writer.WriteParcel(responseOptions, formatter, syndicationConfiguration["Category"], parcel); - - xmlWriter.Flush(); - } - - return sw.ToString(); - } - - private static Uri BuildNextSyncUri(int limit, long? from, string nextUrlBase) - { - return from.HasValue - ? new Uri(string.Format(nextUrlBase, from, limit)) - : null; - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/Parcel/Sync/SyncRequest.cs b/src/ParcelRegistry.Api.Legacy/Parcel/Sync/SyncRequest.cs deleted file mode 100644 index 73d58c20..00000000 --- a/src/ParcelRegistry.Api.Legacy/Parcel/Sync/SyncRequest.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ParcelRegistry.Api.Legacy.Parcel.Sync -{ - using MediatR; - using Microsoft.AspNetCore.Http; - - public record SyncRequest(HttpRequest HttpRequest) : IRequest; -} diff --git a/src/ParcelRegistry.Api.Legacy/ParcelRegistry.Api.Legacy.csproj b/src/ParcelRegistry.Api.Legacy/ParcelRegistry.Api.Legacy.csproj deleted file mode 100644 index 15adf512..00000000 --- a/src/ParcelRegistry.Api.Legacy/ParcelRegistry.Api.Legacy.csproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - false - true - false - - - - bin\Debug\net8.0\ParcelRegistry.Api.Legacy.xml - 1701;1702;1705;1591 - TRACE;DEBUG;NETCOREAPP;NET8_0 - - - bin\Release\net8.0\ParcelRegistry.Api.Legacy.xml - 1701;1702;1705;1591 - - - false - - - - - - - - - - - - - - - - - - diff --git a/src/ParcelRegistry.Api.Legacy/Properties/AssemblyInfo.cs b/src/ParcelRegistry.Api.Legacy/Properties/AssemblyInfo.cs deleted file mode 100644 index 4e300892..00000000 --- a/src/ParcelRegistry.Api.Legacy/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyDescription("Perceelregister Legacy API")] - -[assembly: AssemblyProduct("Basisregisters Vlaanderen")] -[assembly: AssemblyCopyright("Copyright (c) Vlaamse overheid")] -[assembly: AssemblyCompany("Vlaamse overheid")] -[assembly: ComVisible(false)] -[assembly: Guid("63c9c5f5-ef8d-41c3-9261-25659bf67ee2")] diff --git a/src/ParcelRegistry.Api.Legacy/Properties/launchSettings.json b/src/ParcelRegistry.Api.Legacy/Properties/launchSettings.json deleted file mode 100644 index b2a2d4ac..00000000 --- a/src/ParcelRegistry.Api.Legacy/Properties/launchSettings.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:13215/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "ParcelRegistry.Api": { - "commandName": "Project", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:5000/" - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/appsettings.json b/src/ParcelRegistry.Api.Legacy/appsettings.json deleted file mode 100755 index d29dfb5e..00000000 --- a/src/ParcelRegistry.Api.Legacy/appsettings.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "ConnectionStrings": { - "Events": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.ParcelRegistry;Trusted_Connection=True;TrustServerCertificate=True;", - "LegacyProjections": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.ParcelRegistry;Trusted_Connection=True;TrustServerCertificate=True;" - }, - - "Cors": [ - "http://localhost:3000", - "http://localhost:5000" - ], - - "BaseUrl": "https://api.staging-basisregisters.vlaanderen/", - - "Syndication": { - "Category": "percelen", - "Id": "https://legacy.staging-basisregisters.vlaanderen/v1/feeds/percelen.atom", - "Title": "Basisregisters Vlaanderen - Percelenregister", - "Subtitle": "Deze Atom feed geeft leestoegang tot events op de resource 'percelen'.", - "GeneratorTitle": "Basisregisters Vlaanderen", - "GeneratorUri": "", - "Rights": "Gratis hergebruik volgens https://overheid.vlaanderen.be/sites/default/files/documenten/ict-egov/licenties/hergebruik/modellicentie_gratis_hergebruik_v1_0.html", - "AuthorName": "Digitaal Vlaanderen", - "AuthorEmail": "digitaal.vlaanderen@vlaanderen.be", - "Self": "https://legacy.staging-basisregisters.vlaanderen/syndication/feed/parcel", - "NextUri": "https://legacy.staging-basisregisters.vlaanderen/v1/feeds/parcel.atom?from={0}&limit={1}", - "Related": [ - "https://legacy.staging-basisregisters.vlaanderen" - ] - }, - - "Naamruimte": "https://data.vlaanderen.be/id/perceel", - "DetailUrl": "https://basisregisters.vlaanderen.be/api/v1/percelen/{0}", - "VolgendeUrl": "https://basisregisters.vlaanderen.be/api/v1/percelen?offset={0}&limit={1}", - "AdresDetailUrl": "https://basisregisters.vlaanderen.be/api/v1/adressen/{0}", - - "Serilog": { - "MinimumLevel": { - "Default": "Information" - }, - "WriteTo": [ - { - "Name": "Console", - "Args": { - "formatter": "Serilog.Formatting.Compact.RenderedCompactJsonFormatter, Serilog.Formatting.Compact" - } - } - ], - "Properties": { - "Application": "ParcelRegistry - Legacy API", - "ContainerId": "REPLACE_CONTAINERID" - } - } -} diff --git a/src/ParcelRegistry.Api.Legacy/init.sh b/src/ParcelRegistry.Api.Legacy/init.sh deleted file mode 100755 index f7859d9f..00000000 --- a/src/ParcelRegistry.Api.Legacy/init.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -CONTAINERID=$(curl -s http://169.254.170.2/v2/metadata | jq -r ".Containers[] | select(.Labels[\"com.amazonaws.ecs.container-name\"] | startswith(\"basisregisters-\") and endswith(\"-legacy\")) | .DockerId") - -sed -i "s/REPLACE_CONTAINERID/$CONTAINERID/g" appsettings.json - -./ParcelRegistry.Api.Legacy diff --git a/src/ParcelRegistry.Api.Legacy/paket.references b/src/ParcelRegistry.Api.Legacy/paket.references deleted file mode 100644 index 1a80221c..00000000 --- a/src/ParcelRegistry.Api.Legacy/paket.references +++ /dev/null @@ -1,12 +0,0 @@ -AspNetCore.HealthChecks.SqlServer - -Be.Vlaanderen.Basisregisters.Api - -Datadog.Trace.Bundle - -Microsoft.SyndicationFeed.ReaderWriter - -SourceLink.Embed.AllSourceFiles -SourceLink.Copy.PdbFiles - -MediatR diff --git a/src/ParcelRegistry.Api.Legacy/paket.template b/src/ParcelRegistry.Api.Legacy/paket.template deleted file mode 100644 index 841a4d29..00000000 --- a/src/ParcelRegistry.Api.Legacy/paket.template +++ /dev/null @@ -1,31 +0,0 @@ -type file -version 1.0.0 - -id Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.Legacy -title Be.Vlaanderen.Basisregisters.ParcelRegistry.Api.Legacy - -authors Basisregisters Vlaanderen -owners Digitaal Vlaanderen -copyright Copyright (c) Digitaal Vlaanderen -requireLicenseAcceptance false -projectUrl https://github.com/Informatievlaanderen/parcel-registry -iconUrl https://raw.githubusercontent.com/Informatievlaanderen/build-pipeline/master/logo.png -licenseUrl https://opensource.org/licenses/EUPL-1.2 - -description Parcel Registry. - -dependencies - framework: net8.0 - Be.Vlaanderen.Basisregisters.GrAr.Legacy >= LOCKEDVERSION - -files - ParcelRegistry.Api.Legacy.dll => lib\net8.0 - ParcelRegistry.Api.Legacy.pdb => lib\net8.0 - ParcelRegistry.Api.Legacy.xml => lib\net8.0 - ParcelRegistry.Api.Legacy.xml => content - - ParcelRegistry.Projections.Legacy.dll => lib\net8.0 - ParcelRegistry.Projections.Legacy.pdb => lib\net8.0 - - ParcelRegistry.dll => lib\net8.0 - ParcelRegistry.pdb => lib\net8.0 diff --git a/test/ParcelRegistry.Tests/ParcelRegistry.Tests.csproj b/test/ParcelRegistry.Tests/ParcelRegistry.Tests.csproj index 9f6fc1a0..40557c97 100644 --- a/test/ParcelRegistry.Tests/ParcelRegistry.Tests.csproj +++ b/test/ParcelRegistry.Tests/ParcelRegistry.Tests.csproj @@ -4,11 +4,11 @@ - + From da1a6182718f1fe023fea9406969e3941a0eb3d3 Mon Sep 17 00:00:00 2001 From: Arne Dumarey Date: Sun, 9 Jun 2024 09:17:18 +0200 Subject: [PATCH 6/6] refactor: update projection states + rename --- .../Parcel/Count/ParcelCountOsloV2Handler.cs | 2 +- .../Parcel/Detail/ParcelDetailOsloV2Handler.cs | 2 +- .../Parcel/List/ParcelListOsloV2Query.cs | 2 +- .../20240607143051_DeleteOldLinksRenameNew.cs | 11 +++++++++++ .../LegacyContext.cs | 8 ++++---- .../20221123144056_AddV2Tables_P2.cs | 8 ++++---- ...4255_UpdateListCountViewToWithCountTable.cs | 10 +++++----- ...0240607120641_DeleteOldRenameV2WithCount.cs | 18 ++++++++++++------ .../ParcelDetail/ParcelDetailExtensions.cs | 2 +- .../ParcelDetail/ParcelDetailProjections.cs | 4 ++-- .../ParcelDetailItemV2Tests-Readdress.cs | 8 ++++---- .../Legacy/ParcelDetailItemV2Tests.cs | 14 +++++++------- 12 files changed, 53 insertions(+), 36 deletions(-) diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/Count/ParcelCountOsloV2Handler.cs b/src/ParcelRegistry.Api.Oslo/Parcel/Count/ParcelCountOsloV2Handler.cs index ee3ce48d..17f30f62 100644 --- a/src/ParcelRegistry.Api.Oslo/Parcel/Count/ParcelCountOsloV2Handler.cs +++ b/src/ParcelRegistry.Api.Oslo/Parcel/Count/ParcelCountOsloV2Handler.cs @@ -29,7 +29,7 @@ public async Task Handle(ParcelCountOsloRequest request, C .Items .CountAsync(cancellationToken) : Convert.ToInt32(_context - .ParcelDetailV2ListViewCount + .ParcelDetailListViewCount .First() .Count) }; diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/Detail/ParcelDetailOsloV2Handler.cs b/src/ParcelRegistry.Api.Oslo/Parcel/Detail/ParcelDetailOsloV2Handler.cs index e6261699..364b4c0f 100644 --- a/src/ParcelRegistry.Api.Oslo/Parcel/Detail/ParcelDetailOsloV2Handler.cs +++ b/src/ParcelRegistry.Api.Oslo/Parcel/Detail/ParcelDetailOsloV2Handler.cs @@ -30,7 +30,7 @@ public async Task Handle(ParcelDetailOsloReque { var parcel = await _context - .ParcelDetailWithCountV2 + .ParcelDetails .Include(x => x.Addresses) .AsNoTracking() .SingleOrDefaultAsync(item => item.CaPaKey == request.CaPaKey, cancellationToken); diff --git a/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListOsloV2Query.cs b/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListOsloV2Query.cs index c73cd678..8c7bec6f 100644 --- a/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListOsloV2Query.cs +++ b/src/ParcelRegistry.Api.Oslo/Parcel/List/ParcelListOsloV2Query.cs @@ -23,7 +23,7 @@ public class ParcelListOsloV2Query : Query protected override IQueryable Filter(FilteringHeader filtering) { var parcels = _context - .ParcelDetailWithCountV2 + .ParcelDetails .AsNoTracking() .OrderBy(x => x.CaPaKey) .Where(x => !x.Removed); diff --git a/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.cs b/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.cs index d578b7f4..7b611076 100644 --- a/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.cs +++ b/src/ParcelRegistry.Projections.Extract/Migrations/20240607143051_DeleteOldLinksRenameNew.cs @@ -5,6 +5,9 @@ namespace ParcelRegistry.Projections.Extract.Migrations { + using Infrastructure; + using Microsoft.EntityFrameworkCore; + /// public partial class DeleteOldLinksRenameNew : Migration { @@ -76,6 +79,11 @@ protected override void Up(MigrationBuilder migrationBuilder) newName: "IX_Parcels_CaPaKey", schema: "ParcelRegistryExtract", table: "Parcels"); + + migrationBuilder.Sql( + $"DELETE FROM [{Schema.Extract}].[ProjectionStates] WHERE [Name] in ('ParcelRegistry.Projections.Extract.ParcelExtract.ParcelExtractProjections', 'ParcelRegistry.Projections.Extract.ParcelLinkExtract.ParcelLinkExtractProjections')"); + migrationBuilder.Sql($"UPDATE [{Schema.Extract}].[ProjectionStates] SET [Name] = 'ParcelRegistry.Projections.Extract.ParcelLinkExtract.ParcelLinkExtractProjections' WHERE [Name] = 'ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount.ParcelLinkExtractProjections'"); + migrationBuilder.Sql($"UPDATE [{Schema.Extract}].[ProjectionStates] SET [Name] = 'ParcelRegistry.Projections.Extract.ParcelExtract.ParcelExtractProjections' WHERE [Name] = 'ParcelRegistry.Projections.Extract.ParcelExtract.ParcelExtractV2Projections'"); } /// @@ -184,6 +192,9 @@ protected override void Down(MigrationBuilder migrationBuilder) schema: "ParcelRegistryExtract", table: "ParcelLinks", column: "ParcelId"); + + migrationBuilder.Sql($"UPDATE [{Schema.Extract}].[ProjectionStates] SET [Name] = 'ParcelRegistry.Projections.Extract.ParcelLinkExtractWithCount.ParcelLinkExtractProjections' WHERE [Name] = 'ParcelRegistry.Projections.Extract.ParcelLinkExtract.ParcelLinkExtractProjections'"); + migrationBuilder.Sql($"UPDATE [{Schema.Extract}].[ProjectionStates] SET [Name] = 'ParcelRegistry.Projections.Extract.ParcelExtract.ParcelExtractV2Projections' WHERE [Name] = 'ParcelRegistry.Projections.Extract.ParcelExtract.ParcelExtractProjections'"); } } } diff --git a/src/ParcelRegistry.Projections.Legacy/LegacyContext.cs b/src/ParcelRegistry.Projections.Legacy/LegacyContext.cs index 38ad3dca..f23581d7 100755 --- a/src/ParcelRegistry.Projections.Legacy/LegacyContext.cs +++ b/src/ParcelRegistry.Projections.Legacy/LegacyContext.cs @@ -8,12 +8,12 @@ namespace ParcelRegistry.Projections.Legacy public class LegacyContext : RunnerDbContext { public override string ProjectionStateSchema => Schema.Legacy; - internal const string ParcelDetailV2ListCountName = "vw_ParcelDetailV2ListCount"; - public DbSet ParcelDetailWithCountV2 { get; set; } + internal const string ParcelDetailListCountName = "vw_ParcelDetailListCount"; + public DbSet ParcelDetails { get; set; } public DbSet ParcelSyndication { get; set; } - public DbSet ParcelDetailV2ListViewCount { get; set; } + public DbSet ParcelDetailListViewCount { get; set; } // This needs to be here to please EF public LegacyContext() { } @@ -28,7 +28,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity() .HasNoKey() - .ToView(ParcelDetailV2ListCountName, Schema.Legacy); + .ToView(ParcelDetailListCountName, Schema.Legacy); } } diff --git a/src/ParcelRegistry.Projections.Legacy/Migrations/20221123144056_AddV2Tables_P2.cs b/src/ParcelRegistry.Projections.Legacy/Migrations/20221123144056_AddV2Tables_P2.cs index a4fef04b..af9e7a06 100644 --- a/src/ParcelRegistry.Projections.Legacy/Migrations/20221123144056_AddV2Tables_P2.cs +++ b/src/ParcelRegistry.Projections.Legacy/Migrations/20221123144056_AddV2Tables_P2.cs @@ -16,14 +16,14 @@ protected override void Up(MigrationBuilder migrationBuilder) nullable: true); migrationBuilder.Sql($@" - CREATE VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] + CREATE VIEW [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount] WITH SCHEMABINDING AS SELECT COUNT_BIG(*) as Count FROM [{Infrastructure.Schema.Legacy}].[ParcelDetailsV2] WHERE [Removed] = 0"); - migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); + migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_vw_ParcelDetailV2ListCount ON [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount] (Count)"); } protected override void Down(MigrationBuilder migrationBuilder) @@ -33,8 +33,8 @@ protected override void Down(MigrationBuilder migrationBuilder) schema: "ParcelRegistryLegacy", table: "ParcelSyndication"); - migrationBuilder.Sql($@"DROP INDEX [IX_{LegacyContext.ParcelDetailV2ListCountName}] ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}]"); - migrationBuilder.Sql($@"DROP VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}]"); + migrationBuilder.Sql($@"DROP INDEX [IX_{LegacyContext.ParcelDetailListCountName}] ON [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount]"); + migrationBuilder.Sql($@"DROP VIEW [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount]"); } } } diff --git a/src/ParcelRegistry.Projections.Legacy/Migrations/20240528134255_UpdateListCountViewToWithCountTable.cs b/src/ParcelRegistry.Projections.Legacy/Migrations/20240528134255_UpdateListCountViewToWithCountTable.cs index e15fad69..68910de2 100644 --- a/src/ParcelRegistry.Projections.Legacy/Migrations/20240528134255_UpdateListCountViewToWithCountTable.cs +++ b/src/ParcelRegistry.Projections.Legacy/Migrations/20240528134255_UpdateListCountViewToWithCountTable.cs @@ -13,28 +13,28 @@ public partial class UpdateListCountViewToWithCountTable : Migration protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.Sql($@" - ALTER VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] + ALTER VIEW [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount] WITH SCHEMABINDING AS SELECT COUNT_BIG(*) as Count - FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailConfiguration.TableName}] + FROM [{Infrastructure.Schema.Legacy}].[ParcelDetailsV2WithCount] WHERE [Removed] = 0"); - migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); + migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_vw_ParcelDetailV2ListCount ON [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount] (Count)"); } /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.Sql($@" - ALTER VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] + ALTER VIEW [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount] WITH SCHEMABINDING AS SELECT COUNT_BIG(*) as Count FROM [{Infrastructure.Schema.Legacy}].[ParcelDetailsV2] WHERE [Removed] = 0"); - migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); + migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_vw_ParcelDetailV2ListCount ON [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount] (Count)"); } } } diff --git a/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.cs b/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.cs index 29c9a1e9..b5dccaaf 100644 --- a/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.cs +++ b/src/ParcelRegistry.Projections.Legacy/Migrations/20240607120641_DeleteOldRenameV2WithCount.cs @@ -5,6 +5,7 @@ namespace ParcelRegistry.Projections.Legacy.Migrations { + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.ProjectionStates; using ParcelDetail; /// @@ -13,7 +14,7 @@ public partial class DeleteOldRenameV2WithCount : Migration /// protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.Sql($@"DROP VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}]"); + migrationBuilder.Sql($@"DROP VIEW [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount]"); migrationBuilder.DropTable( name: "ParcelAddressesV2", @@ -110,20 +111,23 @@ protected override void Up(MigrationBuilder migrationBuilder) newName: "IX_ParcelDetails_Status"); migrationBuilder.Sql($@" -CREATE VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] +CREATE VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailListCountName}] WITH SCHEMABINDING AS SELECT COUNT_BIG(*) as Count FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailConfiguration.TableName}] WHERE [Removed] = 0"); - migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); + migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailListCountName}] (Count)"); + + migrationBuilder.Sql($"DELETE FROM [{Infrastructure.Schema.Legacy}].[ProjectionStates] WHERE [Name] = 'ParcelRegistry.Projections.Legacy.ParcelDetailV2.ParcelDetailV2Projections'"); + migrationBuilder.Sql($"UPDATE [{Infrastructure.Schema.Legacy}].[ProjectionStates] SET [Name] = 'ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetailProjections' WHERE [Name] = 'ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2.ParcelDetailV2Projections'"); } /// protected override void Down(MigrationBuilder migrationBuilder) { - migrationBuilder.Sql($@"DROP VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}]"); + migrationBuilder.Sql($@"DROP VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailListCountName}]"); migrationBuilder.CreateTable( name: "ParcelDetailsV2", @@ -260,14 +264,16 @@ protected override void Down(MigrationBuilder migrationBuilder) onDelete: ReferentialAction.Cascade); migrationBuilder.Sql($@" -CREATE VIEW [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] +CREATE VIEW [{Infrastructure.Schema.Legacy}].[vw_ParcelDetailV2ListCount] WITH SCHEMABINDING AS SELECT COUNT_BIG(*) as Count FROM [{Infrastructure.Schema.Legacy}].[{ParcelDetailConfiguration.TableName}] WHERE [Removed] = 0"); - migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailV2ListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailV2ListCountName}] (Count)"); + migrationBuilder.Sql($@"CREATE UNIQUE CLUSTERED INDEX IX_{LegacyContext.ParcelDetailListCountName} ON [{Infrastructure.Schema.Legacy}].[{LegacyContext.ParcelDetailListCountName}] (Count)"); + + migrationBuilder.Sql($"UPDATE [{Infrastructure.Schema.Legacy}].[ProjectionStates] SET [Name] = 'ParcelRegistry.Projections.Legacy.ParcelDetailWithCountV2.ParcelDetailV2Projections' WHERE [Name] = 'ParcelRegistry.Projections.Legacy.ParcelDetail.ParcelDetailProjections'"); } } } diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailExtensions.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailExtensions.cs index f629af3f..733d5def 100644 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailExtensions.cs +++ b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailExtensions.cs @@ -14,7 +14,7 @@ public static async Task FindAndUpdateParcelDetail( CancellationToken ct) { var parcel = await context - .ParcelDetailWithCountV2 + .ParcelDetails .FindAsync(parcelId, cancellationToken: ct); if (parcel == null) diff --git a/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailProjections.cs b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailProjections.cs index a817dd14..8f754dff 100644 --- a/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailProjections.cs +++ b/src/ParcelRegistry.Projections.Legacy/ParcelDetail/ParcelDetailProjections.cs @@ -58,7 +58,7 @@ public ParcelDetailProjections() UpdateHash(item, message); await context - .ParcelDetailWithCountV2 + .ParcelDetails .AddAsync(item, ct); }); @@ -267,7 +267,7 @@ await context.FindAndUpdateParcelDetail( UpdateHash(item, message); await context - .ParcelDetailWithCountV2 + .ParcelDetails .AddAsync(item, ct); }); diff --git a/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests-Readdress.cs b/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests-Readdress.cs index b302c703..34145d36 100644 --- a/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests-Readdress.cs +++ b/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests-Readdress.cs @@ -44,7 +44,7 @@ await Sut new Envelope(new Envelope(@event, eventMetadata))) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(parcelWasImported.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(parcelWasImported.ParcelId); parcelDetailV2.Should().NotBeNull(); var previousRelation = parcelDetailV2!.Addresses @@ -101,7 +101,7 @@ await Sut new Envelope(new Envelope(@event, eventMetadata))) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(parcelWasImported.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(parcelWasImported.ParcelId); parcelDetailV2.Should().NotBeNull(); var previousRelation = parcelDetailV2!.Addresses @@ -157,7 +157,7 @@ await Sut new Envelope(new Envelope(@event, eventMetadata))) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(parcelWasImported.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(parcelWasImported.ParcelId); parcelDetailV2.Should().NotBeNull(); var previousRelation = parcelDetailV2!.Addresses @@ -235,7 +235,7 @@ await Sut new Envelope(new Envelope(@event, eventMetadata))) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(parcelWasImported.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(parcelWasImported.ParcelId); parcelDetailV2.Should().NotBeNull(); foreach (var addressPersistentLocalId in attachedAddressPersistentLocalIds) diff --git a/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests.cs b/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests.cs index 407169df..9169a3bf 100644 --- a/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests.cs +++ b/test/ParcelRegistry.Tests/ProjectionTests/Legacy/ParcelDetailItemV2Tests.cs @@ -50,7 +50,7 @@ await Sut { var geometry = WKBReaderFactory.Create().Read(message.ExtendedWkbGeometry.ToByteArray()); - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(message.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(message.ParcelId); parcelDetailV2.Should().NotBeNull(); parcelDetailV2!.CaPaKey.Should().Be(message.CaPaKey); parcelDetailV2.Status.Should().Be(ParcelStatus.Parse(message.ParcelStatus)); @@ -81,7 +81,7 @@ await Sut { var geometry = WKBReaderFactory.Create().Read(message.ExtendedWkbGeometry.ToByteArray()); - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(message.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(message.ParcelId); parcelDetailV2.Should().NotBeNull(); parcelDetailV2!.CaPaKey.Should().Be(message.CaPaKey); parcelDetailV2.Status.Should().Be(ParcelStatus.Realized); @@ -106,7 +106,7 @@ await Sut CreateEnvelope(parcelWasRetiredV2)) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(parcelWasRetiredV2.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(parcelWasRetiredV2.ParcelId); parcelDetailV2.Should().NotBeNull(); parcelDetailV2!.CaPaKey.Should().Be(parcelWasRetiredV2.CaPaKey); parcelDetailV2.Status.Should().Be(ParcelStatus.Retired); @@ -131,7 +131,7 @@ await Sut CreateEnvelope(parcelGeometryWasChanged)) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync((Guid)_fixture.Create()); + var parcelDetailV2 = await context.ParcelDetails.FindAsync((Guid)_fixture.Create()); parcelDetailV2.Should().NotBeNull(); parcelDetailV2!.Gml.Should().Be(GeometryHelpers.ValidGmlPolygon); parcelDetailV2.GmlType.Should().Be("Polygon"); @@ -157,7 +157,7 @@ await Sut CreateEnvelope(@event)) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync((Guid)_fixture.Create()); + var parcelDetailV2 = await context.ParcelDetails.FindAsync((Guid)_fixture.Create()); parcelDetailV2.Should().NotBeNull(); parcelDetailV2!.Gml.Should().Be(GeometryHelpers.ValidGmlPolygon); parcelDetailV2.GmlType.Should().Be("Polygon"); @@ -188,7 +188,7 @@ await Sut new Envelope(new Envelope(addressWasAttached, metadata2))) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(message.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(message.ParcelId); parcelDetailV2.Should().NotBeNull(); parcelDetailV2!.Addresses.Should().BeEquivalentTo( message.AddressPersistentLocalIds @@ -224,7 +224,7 @@ await Sut new Envelope(new Envelope(addressWasDetached, metadata2))) .Then(async context => { - var parcelDetailV2 = await context.ParcelDetailWithCountV2.FindAsync(parcelWasMigrated.ParcelId); + var parcelDetailV2 = await context.ParcelDetails.FindAsync(parcelWasMigrated.ParcelId); parcelDetailV2.Should().NotBeNull(); parcelDetailV2!.Addresses.Select(x => x.AddressPersistentLocalId).Should() .NotContain(addressWasDetached.AddressPersistentLocalId);