From 03d75e0399242f1c4aec9dce34447046a18c9673 Mon Sep 17 00:00:00 2001 From: emalfroy Date: Tue, 30 Jan 2024 16:41:59 +0100 Subject: [PATCH 1/2] chore: update packages --- paket.dependencies | 21 +++-- paket.lock | 85 +++++++++++++++---- .../ProducerContextMigrationFactory.cs | 3 +- .../ProducerModule.cs | 2 +- .../paket.references | 2 +- .../ProducerContextMigrationFactory.cs | 4 +- src/PostalRegistry.Producer/ProducerModule.cs | 1 + src/PostalRegistry.Producer/paket.references | 2 +- .../ExtractContextMigrationFactory.cs | 3 +- .../ExtractModule.cs | 4 +- .../paket.references | 2 +- .../DataMigrationsContext.cs | 3 +- .../PostalLastChangedListModule.cs | 1 + .../LegacyContextMigrationFactory.cs | 4 +- .../LegacyModule.cs | 1 + .../PostalInformationSyndication.cs | 1 + .../paket.references | 2 +- .../MigrationsHelper.cs | 1 + .../SyndicationContext.cs | 1 + .../SyndicationModule.cs | 1 + .../paket.references | 2 +- 21 files changed, 106 insertions(+), 40 deletions(-) diff --git a/paket.dependencies b/paket.dependencies index 77c03cab..69d1fd1d 100755 --- a/paket.dependencies +++ b/paket.dependencies @@ -16,6 +16,11 @@ nuget Dapper 2.0.123 // For more healtchecks, look at https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks nuget AspNetCore.HealthChecks.SqlServer 6.0.2 +nuget AspNetCore.HealthChecks.NpgSql 6.0.2 + +nuget Npgsql 6.0.3 +nuget Npgsql.EntityFrameworkCore.PostgreSQL 6.0.3 +nuget Npgsql.EntityFrameworkCore.PostgreSQL.Design 2.0.0-preview1 nuget Microsoft.EntityFrameworkCore.Design 6.0.3 @@ -42,14 +47,16 @@ nuget Be.Vlaanderen.Basisregisters.CommandHandling.SqlStreamStore 8.0.0 nuget Be.Vlaanderen.Basisregisters.EventHandling 4.2.3 nuget Be.Vlaanderen.Basisregisters.EventHandling.Autofac 4.2.3 -nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.LastChangedList 11.0.1 -nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore 11.0.1 -nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac 11.0.1 -nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner 11.0.1 -nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector.Testing 11.0.1 -nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Syndication 11.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.LastChangedList 12.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore 12.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac 12.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner 12.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer 12.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.Npgsql 12.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector.Testing 12.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Syndication 12.0.1 -nuget Be.Vlaanderen.Basisregisters.Projector 12.0.1 +nuget Be.Vlaanderen.Basisregisters.Projector 13.1.0 nuget Be.Vlaanderen.Basisregisters.DataDog.Tracing.Autofac 5.0.3 nuget Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql 5.0.3 diff --git a/paket.lock b/paket.lock index ee908f24..bcd5b835 100644 --- a/paket.lock +++ b/paket.lock @@ -1,6 +1,9 @@ RESTRICTION: == net6.0 NUGET remote: https://api.nuget.org/v3/index.json + AspNetCore.HealthChecks.NpgSql (6.0.2) + Microsoft.Extensions.Diagnostics.HealthChecks (>= 6.0.2) + Npgsql (>= 6.0) AspNetCore.HealthChecks.SqlServer (6.0.2) Microsoft.Data.SqlClient (>= 3.0.1) Microsoft.Extensions.Diagnostics.HealthChecks (>= 6.0) @@ -292,25 +295,38 @@ NUGET Be.Vlaanderen.Basisregisters.Middleware.AddProblemJsonHeader (2.0) Be.Vlaanderen.Basisregisters.ProblemDetails (8.0.1) System.Reflection.Metadata (>= 6.0.1) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (11.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (12.0.1) Microsoft.EntityFrameworkCore (>= 6.0.3) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector.Testing (11.0.1) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (11.0.1) - Be.Vlaanderen.Basisregisters.ProjectionHandling.LastChangedList (11.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector.Testing (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.LastChangedList (12.0.1) Autofac.Extensions.DependencyInjection (>= 7.2) - Be.Vlaanderen.Basisregisters.AggregateSource.SqlStreamStore.Autofac (>= 6.0) + Be.Vlaanderen.Basisregisters.AggregateSource.SqlStreamStore (>= 7.1.3) Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql (>= 5.0) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner (11.0.1) - Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac (11.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (12.0.1) Microsoft.EntityFrameworkCore.SqlServer (>= 6.0.3) Microsoft.Extensions.DependencyInjection (>= 6.0) Polly (>= 7.2.3) SqlStreamStore.MsSql (>= 1.2) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner (11.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner (12.0.1) Autofac.Extensions.DependencyInjection (>= 7.2) Be.Vlaanderen.Basisregisters.EntityFrameworkCore.EntityTypeConfiguration (>= 3.0) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (11.0.1) - Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (11.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (12.0.1) + Microsoft.EntityFrameworkCore.InMemory (>= 6.0.3) + Microsoft.EntityFrameworkCore.Relational (>= 6.0.3) + Microsoft.Extensions.Configuration (>= 6.0.1) + Microsoft.Extensions.Configuration.CommandLine (>= 6.0) + Microsoft.Extensions.Configuration.EnvironmentVariables (>= 6.0.1) + Microsoft.Extensions.Configuration.FileExtensions (>= 6.0) + Microsoft.Extensions.Configuration.Json (>= 6.0) + SqlStreamStore (>= 1.2) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.Microsoft (12.0.1) + Be.Vlaanderen.Basisregisters.DependencyInjection (>= 1.0.3) + Be.Vlaanderen.Basisregisters.EntityFrameworkCore.EntityTypeConfiguration (>= 3.0) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (12.0.1) Microsoft.EntityFrameworkCore.InMemory (>= 6.0.3) Microsoft.EntityFrameworkCore.SqlServer (>= 6.0.3) Microsoft.Extensions.Configuration (>= 6.0.1) @@ -319,24 +335,38 @@ NUGET Microsoft.Extensions.Configuration.FileExtensions (>= 6.0) Microsoft.Extensions.Configuration.Json (>= 6.0) SqlStreamStore (>= 1.2) - Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (11.0.1) - Be.Vlaanderen.Basisregisters.EventHandling (>= 4.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.Npgsql (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (12.0.1) + Npgsql.EntityFrameworkCore.PostgreSQL (>= 6.0.3) + Polly (>= 7.2.3) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (12.0.1) + Microsoft.EntityFrameworkCore.SqlServer (>= 6.0.3) + Polly (>= 7.2.3) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (12.0.1) + Be.Vlaanderen.Basisregisters.EventHandling (>= 4.2.2) SqlStreamStore (>= 1.2) - Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac (11.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac (12.0.1) Autofac.Extensions.DependencyInjection (>= 7.2) - Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (11.0.1) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Syndication (11.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Syndication (12.0.1) Microsoft.Extensions.Http (>= 6.0) Microsoft.Extensions.Logging (>= 6.0) Microsoft.SyndicationFeed.ReaderWriter (>= 1.0.2) - Be.Vlaanderen.Basisregisters.Projector (12.0.1) + Be.Vlaanderen.Basisregisters.Projector (13.1) Autofac (>= 6.3) Autofac.Extensions.DependencyInjection (>= 7.2) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (>= 11.0.1) - Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner (>= 11.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector (>= 12.0) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner (>= 12.0) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.Microsoft (>= 12.0) Dapper (>= 2.0.123) Microsoft.Data.SqlClient (>= 4.1) Polly (>= 7.2.3) + System.Configuration.ConfigurationManager (>= 6.0) System.Threading.Tasks.Dataflow (>= 6.0) Be.Vlaanderen.Basisregisters.Shaperon (9.0.1) Be.Vlaanderen.Basisregisters.Testing.Infrastructure.Events (3.0) - copy_local: true, copy_content_to_output_dir: always, content: true @@ -595,6 +625,9 @@ NUGET Microsoft.EntityFrameworkCore.Relational (6.0.3) Microsoft.EntityFrameworkCore (>= 6.0.3) Microsoft.Extensions.Configuration.Abstractions (>= 6.0) + Microsoft.EntityFrameworkCore.Relational.Design (2.0.0-preview1-final) + Microsoft.EntityFrameworkCore.Relational (>= 2.0.0-preview1-final) + NETStandard.Library (>= 2.0.0-preview1-25301-01) Microsoft.EntityFrameworkCore.SqlServer (6.0.3) Microsoft.Data.SqlClient (>= 2.1.4) Microsoft.EntityFrameworkCore.Relational (>= 6.0.3) @@ -786,6 +819,22 @@ NUGET NodaTime.Serialization.JsonNet (3.0) Newtonsoft.Json (>= 12.0.1) NodaTime (>= 3.0 < 4.0) + Npgsql (6.0.3) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + Npgsql.EntityFrameworkCore.PostgreSQL (6.0.3) + Microsoft.EntityFrameworkCore (>= 6.0.1) + Microsoft.EntityFrameworkCore.Abstractions (>= 6.0.1) + Microsoft.EntityFrameworkCore.Relational (>= 6.0.1) + Npgsql (>= 6.0.3) + Npgsql.EntityFrameworkCore.PostgreSQL.Design (2.0.0-preview1) + Microsoft.EntityFrameworkCore (>= 2.0.0-preview1-final) + Microsoft.EntityFrameworkCore.Relational (>= 2.0.0-preview1-final) + Microsoft.EntityFrameworkCore.Relational.Design (>= 2.0.0-preview1-final) + Microsoft.Extensions.DependencyInjection (>= 2.0.0-preview1-final) + Microsoft.Extensions.DependencyInjection.Abstractions (>= 2.0.0-preview1-final) + NETStandard.Library (>= 1.6.1) + Npgsql (>= 3.2.2) + Npgsql.EntityFrameworkCore.PostgreSQL (>= 2.0.0-preview1) NSwag.CodeGeneration (13.15.10) Newtonsoft.Json (>= 9.0.1) NJsonSchema (>= 10.6.10) diff --git a/src/PostalRegistry.Producer.Snapshot.Oslo/ProducerContextMigrationFactory.cs b/src/PostalRegistry.Producer.Snapshot.Oslo/ProducerContextMigrationFactory.cs index 0f9db7c3..c1c9c726 100644 --- a/src/PostalRegistry.Producer.Snapshot.Oslo/ProducerContextMigrationFactory.cs +++ b/src/PostalRegistry.Producer.Snapshot.Oslo/ProducerContextMigrationFactory.cs @@ -1,10 +1,11 @@ namespace PostalRegistry.Producer.Snapshot.Oslo { using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer; using Microsoft.EntityFrameworkCore; using PostalRegistry.Infrastructure; - public class ProducerContextMigrationFactory : RunnerDbContextMigrationFactory + public class ProducerContextMigrationFactory : SqlServerRunnerDbContextMigrationFactory { public ProducerContextMigrationFactory() : base("ProducerProjectionsAdmin", HistoryConfiguration) { } diff --git a/src/PostalRegistry.Producer.Snapshot.Oslo/ProducerModule.cs b/src/PostalRegistry.Producer.Snapshot.Oslo/ProducerModule.cs index b93555a6..4002afce 100644 --- a/src/PostalRegistry.Producer.Snapshot.Oslo/ProducerModule.cs +++ b/src/PostalRegistry.Producer.Snapshot.Oslo/ProducerModule.cs @@ -3,7 +3,7 @@ namespace PostalRegistry.Producer.Snapshot.Oslo using System; using Autofac; using Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql.EntityFrameworkCore; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; diff --git a/src/PostalRegistry.Producer.Snapshot.Oslo/paket.references b/src/PostalRegistry.Producer.Snapshot.Oslo/paket.references index b065da96..7efba64d 100644 --- a/src/PostalRegistry.Producer.Snapshot.Oslo/paket.references +++ b/src/PostalRegistry.Producer.Snapshot.Oslo/paket.references @@ -4,7 +4,7 @@ Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql Be.Vlaanderen.Basisregisters.GrAr.Legacy Be.Vlaanderen.Basisregisters.GrAr.Oslo Be.Vlaanderen.BasisRegisters.MessageHandling.Kafka.Producer -Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner +Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac Be.Vlaanderen.Basisregisters.Projector diff --git a/src/PostalRegistry.Producer/ProducerContextMigrationFactory.cs b/src/PostalRegistry.Producer/ProducerContextMigrationFactory.cs index 98ffee87..a2290e2b 100644 --- a/src/PostalRegistry.Producer/ProducerContextMigrationFactory.cs +++ b/src/PostalRegistry.Producer/ProducerContextMigrationFactory.cs @@ -1,10 +1,10 @@ namespace PostalRegistry.Producer { - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer; using Microsoft.EntityFrameworkCore; using PostalRegistry.Infrastructure; - public class ProducerContextMigrationFactory : RunnerDbContextMigrationFactory + public class ProducerContextMigrationFactory : SqlServerRunnerDbContextMigrationFactory { public ProducerContextMigrationFactory() : base("ProducerProjectionsAdmin", HistoryConfiguration) { } diff --git a/src/PostalRegistry.Producer/ProducerModule.cs b/src/PostalRegistry.Producer/ProducerModule.cs index 7c8f6622..cc9e1adc 100644 --- a/src/PostalRegistry.Producer/ProducerModule.cs +++ b/src/PostalRegistry.Producer/ProducerModule.cs @@ -4,6 +4,7 @@ namespace PostalRegistry.Producer using Autofac; using Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql.EntityFrameworkCore; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; diff --git a/src/PostalRegistry.Producer/paket.references b/src/PostalRegistry.Producer/paket.references index 8027ae6b..05131826 100644 --- a/src/PostalRegistry.Producer/paket.references +++ b/src/PostalRegistry.Producer/paket.references @@ -4,7 +4,7 @@ Be.Vlaanderen.Basisregisters.EventHandling.Autofac Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql Be.Vlaanderen.Basisregisters.GrAr.Contracts Be.Vlaanderen.BasisRegisters.MessageHandling.Kafka.Producer -Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner +Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac Be.Vlaanderen.Basisregisters.Projector diff --git a/src/PostalRegistry.Projections.Extract/ExtractContextMigrationFactory.cs b/src/PostalRegistry.Projections.Extract/ExtractContextMigrationFactory.cs index 8820845d..a88516f1 100644 --- a/src/PostalRegistry.Projections.Extract/ExtractContextMigrationFactory.cs +++ b/src/PostalRegistry.Projections.Extract/ExtractContextMigrationFactory.cs @@ -1,10 +1,11 @@ namespace PostalRegistry.Projections.Extract { using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer; using Infrastructure; using Microsoft.EntityFrameworkCore; - public class ExtractContextMigrationFactory : RunnerDbContextMigrationFactory + public class ExtractContextMigrationFactory : SqlServerRunnerDbContextMigrationFactory { public ExtractContextMigrationFactory() : base("ExtractProjectionsAdmin", HistoryConfiguration) diff --git a/src/PostalRegistry.Projections.Extract/ExtractModule.cs b/src/PostalRegistry.Projections.Extract/ExtractModule.cs index d5c6b51f..ac9a2996 100755 --- a/src/PostalRegistry.Projections.Extract/ExtractModule.cs +++ b/src/PostalRegistry.Projections.Extract/ExtractModule.cs @@ -1,11 +1,11 @@ namespace PostalRegistry.Projections.Extract { using System; - using Microsoft.Data.SqlClient; using Autofac; - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; using Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql.EntityFrameworkCore; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Infrastructure; + using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; diff --git a/src/PostalRegistry.Projections.Extract/paket.references b/src/PostalRegistry.Projections.Extract/paket.references index a9ec6c37..3fe9525d 100644 --- a/src/PostalRegistry.Projections.Extract/paket.references +++ b/src/PostalRegistry.Projections.Extract/paket.references @@ -1,7 +1,7 @@ Be.Vlaanderen.Basisregisters.AggregateSource Be.Vlaanderen.Basisregisters.EventHandling.Autofac Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql -Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner +Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac Be.Vlaanderen.Basisregisters.Shaperon diff --git a/src/PostalRegistry.Projections.LastChangedList/DataMigrationsContext.cs b/src/PostalRegistry.Projections.LastChangedList/DataMigrationsContext.cs index d03b9e42..ca308f3e 100644 --- a/src/PostalRegistry.Projections.LastChangedList/DataMigrationsContext.cs +++ b/src/PostalRegistry.Projections.LastChangedList/DataMigrationsContext.cs @@ -5,6 +5,7 @@ namespace PostalRegistry.Projections.LastChangedList using System.Threading.Tasks; using Be.Vlaanderen.Basisregisters.ProjectionHandling.LastChangedList; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer; using Infrastructure; using Microsoft.EntityFrameworkCore; @@ -42,7 +43,7 @@ public override Task SetErrorMessage(string projectionName, string? errorMessage } } - public class DataMigrationContextMigrationFactory : RunnerDbContextMigrationFactory + public class DataMigrationContextMigrationFactory : SqlServerRunnerDbContextMigrationFactory { private static MigrationHistoryConfiguration HistoryConfiguration => new MigrationHistoryConfiguration diff --git a/src/PostalRegistry.Projections.LastChangedList/PostalLastChangedListModule.cs b/src/PostalRegistry.Projections.LastChangedList/PostalLastChangedListModule.cs index f3388ad6..418536e2 100644 --- a/src/PostalRegistry.Projections.LastChangedList/PostalLastChangedListModule.cs +++ b/src/PostalRegistry.Projections.LastChangedList/PostalLastChangedListModule.cs @@ -4,6 +4,7 @@ namespace PostalRegistry.Projections.LastChangedList using Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql.EntityFrameworkCore; using Be.Vlaanderen.Basisregisters.ProjectionHandling.LastChangedList; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Infrastructure; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; diff --git a/src/PostalRegistry.Projections.Legacy/LegacyContextMigrationFactory.cs b/src/PostalRegistry.Projections.Legacy/LegacyContextMigrationFactory.cs index 0243de31..b6f69477 100644 --- a/src/PostalRegistry.Projections.Legacy/LegacyContextMigrationFactory.cs +++ b/src/PostalRegistry.Projections.Legacy/LegacyContextMigrationFactory.cs @@ -1,10 +1,10 @@ namespace PostalRegistry.Projections.Legacy { - using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer; using Infrastructure; using Microsoft.EntityFrameworkCore; - public class LegacyContextMigrationFactory : RunnerDbContextMigrationFactory + public class LegacyContextMigrationFactory : SqlServerRunnerDbContextMigrationFactory { public LegacyContextMigrationFactory() : base("LegacyProjectionsAdmin", HistoryConfiguration) diff --git a/src/PostalRegistry.Projections.Legacy/LegacyModule.cs b/src/PostalRegistry.Projections.Legacy/LegacyModule.cs index 30cdd3d6..dfe3eb52 100755 --- a/src/PostalRegistry.Projections.Legacy/LegacyModule.cs +++ b/src/PostalRegistry.Projections.Legacy/LegacyModule.cs @@ -5,6 +5,7 @@ namespace PostalRegistry.Projections.Legacy using Autofac; using Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql.EntityFrameworkCore; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Infrastructure; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; diff --git a/src/PostalRegistry.Projections.Legacy/PostalInformationSyndication/PostalInformationSyndication.cs b/src/PostalRegistry.Projections.Legacy/PostalInformationSyndication/PostalInformationSyndication.cs index e3874f5f..2e9baac0 100755 --- a/src/PostalRegistry.Projections.Legacy/PostalInformationSyndication/PostalInformationSyndication.cs +++ b/src/PostalRegistry.Projections.Legacy/PostalInformationSyndication/PostalInformationSyndication.cs @@ -4,6 +4,7 @@ namespace PostalRegistry.Projections.Legacy.PostalInformationSyndication using System.Collections.Generic; using Be.Vlaanderen.Basisregisters.GrAr.Provenance; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Infrastructure; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; diff --git a/src/PostalRegistry.Projections.Legacy/paket.references b/src/PostalRegistry.Projections.Legacy/paket.references index 4e009729..500d1d06 100755 --- a/src/PostalRegistry.Projections.Legacy/paket.references +++ b/src/PostalRegistry.Projections.Legacy/paket.references @@ -2,7 +2,7 @@ Be.Vlaanderen.Basisregisters.AggregateSource Be.Vlaanderen.Basisregisters.AggregateSource.SqlStreamStore Be.Vlaanderen.Basisregisters.EventHandling.Autofac Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql -Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner +Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac Be.Vlaanderen.Basisregisters.GrAr.Common diff --git a/src/PostalRegistry.Projections.Syndication/MigrationsHelper.cs b/src/PostalRegistry.Projections.Syndication/MigrationsHelper.cs index 326cd302..c95b8f72 100755 --- a/src/PostalRegistry.Projections.Syndication/MigrationsHelper.cs +++ b/src/PostalRegistry.Projections.Syndication/MigrationsHelper.cs @@ -8,6 +8,7 @@ namespace PostalRegistry.Projections.Syndication using Microsoft.Extensions.Logging; using Polly; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Infrastructure; public class MigrationsLogger { } diff --git a/src/PostalRegistry.Projections.Syndication/SyndicationContext.cs b/src/PostalRegistry.Projections.Syndication/SyndicationContext.cs index 3384ba1f..b12db6ca 100755 --- a/src/PostalRegistry.Projections.Syndication/SyndicationContext.cs +++ b/src/PostalRegistry.Projections.Syndication/SyndicationContext.cs @@ -4,6 +4,7 @@ namespace PostalRegistry.Projections.Syndication using System.IO; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.Configuration; diff --git a/src/PostalRegistry.Projections.Syndication/SyndicationModule.cs b/src/PostalRegistry.Projections.Syndication/SyndicationModule.cs index 1ca713d5..0a968bc4 100755 --- a/src/PostalRegistry.Projections.Syndication/SyndicationModule.cs +++ b/src/PostalRegistry.Projections.Syndication/SyndicationModule.cs @@ -8,6 +8,7 @@ namespace PostalRegistry.Projections.Syndication.Modules using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.MigrationExtensions; using Be.Vlaanderen.Basisregisters.ProjectionHandling.Syndication; using Autofac; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer.MigrationExtensions; using Infrastructure; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; diff --git a/src/PostalRegistry.Projections.Syndication/paket.references b/src/PostalRegistry.Projections.Syndication/paket.references index 1fb38e6f..11024133 100755 --- a/src/PostalRegistry.Projections.Syndication/paket.references +++ b/src/PostalRegistry.Projections.Syndication/paket.references @@ -21,7 +21,7 @@ Microsoft.SyndicationFeed.ReaderWriter Be.Vlaanderen.Basisregisters.AggregateSource Be.Vlaanderen.Basisregisters.EventHandling.Autofac Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql -Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner +Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac Be.Vlaanderen.Basisregisters.ProjectionHandling.Syndication Be.Vlaanderen.Basisregisters.Shaperon From d9e80d0d88bc85166061a878c7bc84a6c673faa5 Mon Sep 17 00:00:00 2001 From: emalfroy Date: Wed, 31 Jan 2024 13:37:47 +0100 Subject: [PATCH 2/2] feat: add integration projections --- PostalRegistry.sln | 7 + paket.dependencies | 3 +- paket.lock | 8 +- .../EF.MigrationsHelper.csproj | 1 + src/EF.MigrationsHelper/appsettings.json | 4 +- src/PostalRegistry.Infrastructure/Schema.cs | 4 + .../Infrastructure/IntegrationModule.cs | 61 +++++++ .../Infrastructure/IntegrationOptions.cs | 8 + .../IntegrationContext.cs | 20 +++ .../IntegrationContextMigrationFactory.cs | 23 +++ .../20240131111518_Initial.Designer.cs | 130 ++++++++++++++ .../Migrations/20240131111518_Initial.cs | 104 +++++++++++ .../IntegrationContextModelSnapshot.cs | 128 ++++++++++++++ .../PostalInformationName.cs | 53 ++++++ .../PostalLatestItem.cs | 66 +++++++ .../PostalLatestItemExtensions.cs | 30 ++++ .../PostalLatestItemProjections.cs | 119 +++++++++++++ ...talRegistry.Projections.Integration.csproj | 13 ++ .../Properties/AssemblyInfo.cs | 7 + .../paket.references | 13 ++ .../Infrastructure/Modules/ApiModule.cs | 22 +++ .../Infrastructure/Startup.cs | 19 +- .../PostalRegistry.Projector.csproj | 1 + src/PostalRegistry.Projector/appsettings.json | 11 +- src/PostalRegistry.Projector/paket.references | 7 + .../InfrastructureCustomization.cs | 13 ++ .../AutoFixture/IntegerNisCode.cs | 39 +++++ .../AutoFixture/NodaTimeCustomization.cs | 78 +++++++++ .../PrivateGreedyConstructorQuery.cs | 46 +++++ ...venanceImplementationsCallSetProvenance.cs | 41 +++++ ...talInformationPostalNameWasAddedBuilder.cs | 34 ++++ ...lInformationPostalNameWasRemovedBuilder.cs | 34 ++++ .../Integration/IntegrationProjectionTest.cs | 30 ++++ .../Integration/PostalLatestItemTest.cs | 164 ++++++++++++++++++ .../PostalRegistry.Tests.csproj | 1 + test/PostalRegistry.Tests/paket.references | 3 + 36 files changed, 1338 insertions(+), 7 deletions(-) create mode 100644 src/PostalRegistry.Projections.Integration/Infrastructure/IntegrationModule.cs create mode 100644 src/PostalRegistry.Projections.Integration/Infrastructure/IntegrationOptions.cs create mode 100644 src/PostalRegistry.Projections.Integration/IntegrationContext.cs create mode 100644 src/PostalRegistry.Projections.Integration/IntegrationContextMigrationFactory.cs create mode 100644 src/PostalRegistry.Projections.Integration/Migrations/20240131111518_Initial.Designer.cs create mode 100644 src/PostalRegistry.Projections.Integration/Migrations/20240131111518_Initial.cs create mode 100644 src/PostalRegistry.Projections.Integration/Migrations/IntegrationContextModelSnapshot.cs create mode 100644 src/PostalRegistry.Projections.Integration/PostalInformationName.cs create mode 100644 src/PostalRegistry.Projections.Integration/PostalLatestItem.cs create mode 100644 src/PostalRegistry.Projections.Integration/PostalLatestItemExtensions.cs create mode 100644 src/PostalRegistry.Projections.Integration/PostalLatestItemProjections.cs create mode 100644 src/PostalRegistry.Projections.Integration/PostalRegistry.Projections.Integration.csproj create mode 100644 src/PostalRegistry.Projections.Integration/Properties/AssemblyInfo.cs create mode 100644 src/PostalRegistry.Projections.Integration/paket.references create mode 100644 test/PostalRegistry.Tests/AutoFixture/InfrastructureCustomization.cs create mode 100644 test/PostalRegistry.Tests/AutoFixture/IntegerNisCode.cs create mode 100644 test/PostalRegistry.Tests/AutoFixture/NodaTimeCustomization.cs create mode 100644 test/PostalRegistry.Tests/AutoFixture/PrivateGreedyConstructorQuery.cs create mode 100644 test/PostalRegistry.Tests/AutoFixture/SetProvenanceImplementationsCallSetProvenance.cs create mode 100644 test/PostalRegistry.Tests/Builders/PostalInformationPostalNameWasAddedBuilder.cs create mode 100644 test/PostalRegistry.Tests/Builders/PostalInformationPostalNameWasRemovedBuilder.cs create mode 100644 test/PostalRegistry.Tests/Integration/IntegrationProjectionTest.cs create mode 100644 test/PostalRegistry.Tests/Integration/PostalLatestItemTest.cs diff --git a/PostalRegistry.sln b/PostalRegistry.sln index bdf70c98..e7049567 100755 --- a/PostalRegistry.sln +++ b/PostalRegistry.sln @@ -63,6 +63,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PostalRegistry.Producer", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PostalRegistry.Producer.Snapshot.Oslo", "src\PostalRegistry.Producer.Snapshot.Oslo\PostalRegistry.Producer.Snapshot.Oslo.csproj", "{B6B9729E-0EF7-48C8-88B1-BB4C437D20E6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PostalRegistry.Projections.Integration", "src\PostalRegistry.Projections.Integration\PostalRegistry.Projections.Integration.csproj", "{8049759B-20E1-4AEE-9086-5422C437D742}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -137,6 +139,10 @@ Global {B6B9729E-0EF7-48C8-88B1-BB4C437D20E6}.Debug|Any CPU.Build.0 = Debug|Any CPU {B6B9729E-0EF7-48C8-88B1-BB4C437D20E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {B6B9729E-0EF7-48C8-88B1-BB4C437D20E6}.Release|Any CPU.Build.0 = Release|Any CPU + {8049759B-20E1-4AEE-9086-5422C437D742}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8049759B-20E1-4AEE-9086-5422C437D742}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8049759B-20E1-4AEE-9086-5422C437D742}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8049759B-20E1-4AEE-9086-5422C437D742}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -159,6 +165,7 @@ Global {D13F985B-F16B-4F38-B170-F86E5D447926} = {81BE6CDF-434E-42AB-9CB1-B5E7A26DC317} {DAC34E64-9C52-495E-9BF6-868E3DFE99EE} = {81BE6CDF-434E-42AB-9CB1-B5E7A26DC317} {B6B9729E-0EF7-48C8-88B1-BB4C437D20E6} = {81BE6CDF-434E-42AB-9CB1-B5E7A26DC317} + {8049759B-20E1-4AEE-9086-5422C437D742} = {81BE6CDF-434E-42AB-9CB1-B5E7A26DC317} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {14E5CC1E-7FCC-4086-A7DD-CEFDAD492801} diff --git a/paket.dependencies b/paket.dependencies index 69d1fd1d..fbae9796 100755 --- a/paket.dependencies +++ b/paket.dependencies @@ -12,7 +12,7 @@ nuget CsvHelper 27.2.1 nuget NetTopologySuite 2.4.0 nuget Dapper 2.0.123 - +nuget NodaTime 3.1.6 // For more healtchecks, look at https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks nuget AspNetCore.HealthChecks.SqlServer 6.0.2 @@ -54,6 +54,7 @@ nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner 12.0.1 nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.SqlServer 12.0.1 nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.Npgsql 12.0.1 nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector.Testing 12.0.1 +nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Testing.Xunit 12.0.1 nuget Be.Vlaanderen.Basisregisters.ProjectionHandling.Syndication 12.0.1 nuget Be.Vlaanderen.Basisregisters.Projector 13.1.0 diff --git a/paket.lock b/paket.lock index bcd5b835..4a84d06b 100644 --- a/paket.lock +++ b/paket.lock @@ -357,6 +357,12 @@ NUGET Microsoft.Extensions.Http (>= 6.0) Microsoft.Extensions.Logging (>= 6.0) Microsoft.SyndicationFeed.ReaderWriter (>= 1.0.2) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Testing.Xunit (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector.Testing (12.0.1) + Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore (12.0.1) + Microsoft.EntityFrameworkCore (>= 6.0.3) + Microsoft.Extensions.Logging (>= 6.0) + xunit (>= 2.4.1) Be.Vlaanderen.Basisregisters.Projector (13.1) Autofac (>= 6.3) Autofac.Extensions.DependencyInjection (>= 7.2) @@ -814,7 +820,7 @@ NUGET Newtonsoft.Json (>= 9.0.1) NJsonSchema (>= 10.6.10) NJsonSchema.CodeGeneration (>= 10.6.10) - NodaTime (3.0.10) + NodaTime (3.1.6) System.Runtime.CompilerServices.Unsafe (>= 4.7.1) NodaTime.Serialization.JsonNet (3.0) Newtonsoft.Json (>= 12.0.1) diff --git a/src/EF.MigrationsHelper/EF.MigrationsHelper.csproj b/src/EF.MigrationsHelper/EF.MigrationsHelper.csproj index e872f51f..59d0b5b6 100644 --- a/src/EF.MigrationsHelper/EF.MigrationsHelper.csproj +++ b/src/EF.MigrationsHelper/EF.MigrationsHelper.csproj @@ -29,6 +29,7 @@ + diff --git a/src/EF.MigrationsHelper/appsettings.json b/src/EF.MigrationsHelper/appsettings.json index 768f9851..0b53402d 100644 --- a/src/EF.MigrationsHelper/appsettings.json +++ b/src/EF.MigrationsHelper/appsettings.json @@ -8,7 +8,9 @@ "SyndicationProjections": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.PostalRegistry;Trusted_Connection=True;", "SyndicationProjectionsAdmin": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.PostalRegistry;Trusted_Connection=True;", "LastChangedListAdmin": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.MunicipalityRegistry;Trusted_Connection=True;", - "ProducerProjectionsAdmin": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.MunicipalityRegistry;Trusted_Connection=True;" + "ProducerProjectionsAdmin": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.MunicipalityRegistry;Trusted_Connection=True;", + "IntegrationProjections": ".", + "IntegrationProjectionsAdmin": "." }, "Serilog": { diff --git a/src/PostalRegistry.Infrastructure/Schema.cs b/src/PostalRegistry.Infrastructure/Schema.cs index 01cb7b27..08c215fb 100755 --- a/src/PostalRegistry.Infrastructure/Schema.cs +++ b/src/PostalRegistry.Infrastructure/Schema.cs @@ -11,6 +11,8 @@ public static class Schema public const string Producer = "PostalRegistryProducer"; public const string ProducerSnapshotOslo = "PostalRegistryProducerSnapshotOslo"; + + public const string Integration = "integration_postal"; } public static class MigrationTables @@ -22,5 +24,7 @@ public static class MigrationTables public const string Producer = "__EFMigrationsHistoryProducer"; public const string ProducerSnapshotOslo = "__EFMigrationsHistoryProducerSnapshotOslo"; + + public const string Integration = "__EFMigrationsHistory"; } } diff --git a/src/PostalRegistry.Projections.Integration/Infrastructure/IntegrationModule.cs b/src/PostalRegistry.Projections.Integration/Infrastructure/IntegrationModule.cs new file mode 100644 index 00000000..52190918 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/Infrastructure/IntegrationModule.cs @@ -0,0 +1,61 @@ +namespace PostalRegistry.Projections.Integration.Infrastructure +{ + using System; + using Autofac; + using Microsoft.EntityFrameworkCore; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Logging; + using PostalRegistry.Infrastructure; + + public class IntegrationModule : Module + { + public IntegrationModule( + IConfiguration configuration, + IServiceCollection services, + ILoggerFactory loggerFactory) + { + var logger = loggerFactory.CreateLogger(); + var connectionString = configuration.GetConnectionString("IntegrationProjections"); + + var hasConnectionString = !string.IsNullOrWhiteSpace(connectionString); + if (hasConnectionString) + RunOnNpgSqlServer(services, connectionString); + else + RunInMemoryDb(services, loggerFactory, logger); + + logger.LogInformation( + "Added {Context} to services:" + + Environment.NewLine + + "\tSchema: {Schema}" + + Environment.NewLine + + "\tTableName: {TableName}", + nameof(IntegrationContext), Schema.Integration, MigrationTables.Integration); + } + + private static void RunOnNpgSqlServer( + IServiceCollection services, + string backofficeProjectionsConnectionString) + { + services + .AddNpgsql(backofficeProjectionsConnectionString, sqlServerOptions => + { + sqlServerOptions.EnableRetryOnFailure(); + sqlServerOptions.MigrationsHistoryTable(MigrationTables.Integration, Schema.Integration); + }); + } + + private static void RunInMemoryDb( + IServiceCollection services, + ILoggerFactory loggerFactory, + ILogger logger) + { + services + .AddDbContext(options => options + .UseLoggerFactory(loggerFactory) + .UseInMemoryDatabase(Guid.NewGuid().ToString(), _ => { })); + + logger.LogWarning("Running InMemory for {Context}!", nameof(IntegrationContext)); + } + } +} diff --git a/src/PostalRegistry.Projections.Integration/Infrastructure/IntegrationOptions.cs b/src/PostalRegistry.Projections.Integration/Infrastructure/IntegrationOptions.cs new file mode 100644 index 00000000..7ff40459 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/Infrastructure/IntegrationOptions.cs @@ -0,0 +1,8 @@ +namespace PostalRegistry.Projections.Integration.Infrastructure +{ + public class IntegrationOptions + { + public string Namespace { get; set; } + public bool Enabled { get; set; } + } +} diff --git a/src/PostalRegistry.Projections.Integration/IntegrationContext.cs b/src/PostalRegistry.Projections.Integration/IntegrationContext.cs new file mode 100644 index 00000000..d2d175bc --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/IntegrationContext.cs @@ -0,0 +1,20 @@ +namespace PostalRegistry.Projections.Integration +{ + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner; + using Microsoft.EntityFrameworkCore; + using PostalRegistry.Infrastructure; + + public class IntegrationContext : RunnerDbContext + { + public override string ProjectionStateSchema => Schema.Integration; + + public DbSet PostalLatestItems => Set(); + + // This needs to be here to please EF + public IntegrationContext() { } + + // This needs to be DbContextOptions for Autofac! + public IntegrationContext(DbContextOptions options) + : base(options) { } + } +} diff --git a/src/PostalRegistry.Projections.Integration/IntegrationContextMigrationFactory.cs b/src/PostalRegistry.Projections.Integration/IntegrationContextMigrationFactory.cs new file mode 100644 index 00000000..cae91996 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/IntegrationContextMigrationFactory.cs @@ -0,0 +1,23 @@ +namespace PostalRegistry.Projections.Integration +{ + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.Npgsql; + using Microsoft.EntityFrameworkCore; + using PostalRegistry.Infrastructure; + + public class IntegrationContextMigrationFactory : NpgsqlRunnerDbContextMigrationFactory + { + public IntegrationContextMigrationFactory() + : base("IntegrationProjectionsAdmin", HistoryConfiguration) { } + + private static MigrationHistoryConfiguration HistoryConfiguration => + new MigrationHistoryConfiguration + { + Schema = Schema.Integration, + Table = MigrationTables.Integration + }; + + protected override IntegrationContext CreateContext( + DbContextOptions migrationContextOptions) => + new IntegrationContext(migrationContextOptions); + } +} diff --git a/src/PostalRegistry.Projections.Integration/Migrations/20240131111518_Initial.Designer.cs b/src/PostalRegistry.Projections.Integration/Migrations/20240131111518_Initial.Designer.cs new file mode 100644 index 00000000..c17ce83a --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/Migrations/20240131111518_Initial.Designer.cs @@ -0,0 +1,130 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using PostalRegistry.Projections.Integration; + +#nullable disable + +namespace PostalRegistry.Projections.Integration.Migrations +{ + [DbContext(typeof(IntegrationContext))] + [Migration("20240131111518_Initial")] + partial class Initial + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.ProjectionStates.ProjectionStateItem", b => + { + b.Property("Name") + .HasColumnType("text"); + + b.Property("DesiredState") + .HasColumnType("text"); + + b.Property("DesiredStateChangedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ErrorMessage") + .HasColumnType("text"); + + b.Property("Position") + .HasColumnType("bigint"); + + b.HasKey("Name"); + + b.ToTable("ProjectionStates", "integration_postal"); + }); + + modelBuilder.Entity("PostalRegistry.Projections.Integration.PostalInformationName", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Language") + .HasColumnType("integer") + .HasColumnName("language"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PostalCode") + .HasColumnType("text") + .HasColumnName("postal_code"); + + b.Property("SearchName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("search_name"); + + b.HasKey("Id"); + + b.HasIndex("PostalCode"); + + b.HasIndex("SearchName"); + + b.ToTable("postal_information_name", "integration_postal"); + }); + + modelBuilder.Entity("PostalRegistry.Projections.Integration.PostalLatestItem", b => + { + b.Property("PostalCode") + .HasColumnType("text") + .HasColumnName("postal_code"); + + b.Property("IsRetired") + .HasColumnType("boolean") + .HasColumnName("is_retired"); + + b.Property("Namespace") + .HasColumnType("text") + .HasColumnName("namespace"); + + b.Property("NisCode") + .HasColumnType("text") + .HasColumnName("nis_code"); + + b.Property("PuriId") + .HasColumnType("text") + .HasColumnName("puri_id"); + + b.Property("VersionTimestampAsDateTimeOffset") + .HasColumnType("timestamp with time zone") + .HasColumnName("version_timestamp"); + + b.HasKey("PostalCode"); + + b.HasIndex("NisCode"); + + b.ToTable("postal_latest_items", "integration_postal"); + }); + + modelBuilder.Entity("PostalRegistry.Projections.Integration.PostalInformationName", b => + { + b.HasOne("PostalRegistry.Projections.Integration.PostalLatestItem", null) + .WithMany("PostalNames") + .HasForeignKey("PostalCode"); + }); + + modelBuilder.Entity("PostalRegistry.Projections.Integration.PostalLatestItem", b => + { + b.Navigation("PostalNames"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/PostalRegistry.Projections.Integration/Migrations/20240131111518_Initial.cs b/src/PostalRegistry.Projections.Integration/Migrations/20240131111518_Initial.cs new file mode 100644 index 00000000..a727ad4b --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/Migrations/20240131111518_Initial.cs @@ -0,0 +1,104 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace PostalRegistry.Projections.Integration.Migrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "integration_postal"); + + migrationBuilder.CreateTable( + name: "postal_latest_items", + schema: "integration_postal", + columns: table => new + { + postal_code = table.Column(type: "text", nullable: false), + nis_code = table.Column(type: "text", nullable: true), + is_retired = table.Column(type: "boolean", nullable: false), + puri_id = table.Column(type: "text", nullable: true), + @namespace = table.Column(name: "namespace", type: "text", nullable: true), + version_timestamp = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_postal_latest_items", x => x.postal_code); + }); + + migrationBuilder.CreateTable( + name: "ProjectionStates", + schema: "integration_postal", + columns: table => new + { + Name = table.Column(type: "text", nullable: false), + Position = table.Column(type: "bigint", nullable: false), + DesiredState = table.Column(type: "text", nullable: true), + DesiredStateChangedAt = table.Column(type: "timestamp with time zone", nullable: true), + ErrorMessage = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ProjectionStates", x => x.Name); + }); + + migrationBuilder.CreateTable( + name: "postal_information_name", + schema: "integration_postal", + columns: table => new + { + id = table.Column(type: "uuid", nullable: false), + name = table.Column(type: "text", nullable: false), + search_name = table.Column(type: "text", nullable: false), + language = table.Column(type: "integer", nullable: false), + postal_code = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_postal_information_name", x => x.id); + table.ForeignKey( + name: "FK_postal_information_name_postal_latest_items_postal_code", + column: x => x.postal_code, + principalSchema: "integration_postal", + principalTable: "postal_latest_items", + principalColumn: "postal_code"); + }); + + migrationBuilder.CreateIndex( + name: "IX_postal_information_name_postal_code", + schema: "integration_postal", + table: "postal_information_name", + column: "postal_code"); + + migrationBuilder.CreateIndex( + name: "IX_postal_information_name_search_name", + schema: "integration_postal", + table: "postal_information_name", + column: "search_name"); + + migrationBuilder.CreateIndex( + name: "IX_postal_latest_items_nis_code", + schema: "integration_postal", + table: "postal_latest_items", + column: "nis_code"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "postal_information_name", + schema: "integration_postal"); + + migrationBuilder.DropTable( + name: "ProjectionStates", + schema: "integration_postal"); + + migrationBuilder.DropTable( + name: "postal_latest_items", + schema: "integration_postal"); + } + } +} diff --git a/src/PostalRegistry.Projections.Integration/Migrations/IntegrationContextModelSnapshot.cs b/src/PostalRegistry.Projections.Integration/Migrations/IntegrationContextModelSnapshot.cs new file mode 100644 index 00000000..b61f94f0 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/Migrations/IntegrationContextModelSnapshot.cs @@ -0,0 +1,128 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using PostalRegistry.Projections.Integration; + +#nullable disable + +namespace PostalRegistry.Projections.Integration.Migrations +{ + [DbContext(typeof(IntegrationContext))] + partial class IntegrationContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.ProjectionStates.ProjectionStateItem", b => + { + b.Property("Name") + .HasColumnType("text"); + + b.Property("DesiredState") + .HasColumnType("text"); + + b.Property("DesiredStateChangedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ErrorMessage") + .HasColumnType("text"); + + b.Property("Position") + .HasColumnType("bigint"); + + b.HasKey("Name"); + + b.ToTable("ProjectionStates", "integration_postal"); + }); + + modelBuilder.Entity("PostalRegistry.Projections.Integration.PostalInformationName", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("id"); + + b.Property("Language") + .HasColumnType("integer") + .HasColumnName("language"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.Property("PostalCode") + .HasColumnType("text") + .HasColumnName("postal_code"); + + b.Property("SearchName") + .IsRequired() + .HasColumnType("text") + .HasColumnName("search_name"); + + b.HasKey("Id"); + + b.HasIndex("PostalCode"); + + b.HasIndex("SearchName"); + + b.ToTable("postal_information_name", "integration_postal"); + }); + + modelBuilder.Entity("PostalRegistry.Projections.Integration.PostalLatestItem", b => + { + b.Property("PostalCode") + .HasColumnType("text") + .HasColumnName("postal_code"); + + b.Property("IsRetired") + .HasColumnType("boolean") + .HasColumnName("is_retired"); + + b.Property("Namespace") + .HasColumnType("text") + .HasColumnName("namespace"); + + b.Property("NisCode") + .HasColumnType("text") + .HasColumnName("nis_code"); + + b.Property("PuriId") + .HasColumnType("text") + .HasColumnName("puri_id"); + + b.Property("VersionTimestampAsDateTimeOffset") + .HasColumnType("timestamp with time zone") + .HasColumnName("version_timestamp"); + + b.HasKey("PostalCode"); + + b.HasIndex("NisCode"); + + b.ToTable("postal_latest_items", "integration_postal"); + }); + + modelBuilder.Entity("PostalRegistry.Projections.Integration.PostalInformationName", b => + { + b.HasOne("PostalRegistry.Projections.Integration.PostalLatestItem", null) + .WithMany("PostalNames") + .HasForeignKey("PostalCode"); + }); + + modelBuilder.Entity("PostalRegistry.Projections.Integration.PostalLatestItem", b => + { + b.Navigation("PostalNames"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/PostalRegistry.Projections.Integration/PostalInformationName.cs b/src/PostalRegistry.Projections.Integration/PostalInformationName.cs new file mode 100644 index 00000000..30aa1fe3 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/PostalInformationName.cs @@ -0,0 +1,53 @@ +namespace PostalRegistry.Projections.Integration +{ + using System; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Metadata.Builders; + using PostalRegistry.Infrastructure; + + public class PostalInformationName + { + public Guid Id { get; set; } + public string Name { get; set; } + public string SearchName { get; set; } + public Language Language { get; set; } + public string? PostalCode { get; set; } + + public PostalInformationName() { } + + public PostalInformationName(string name, string searchName, string postalCode, Language language) + { + Name = name; + SearchName = searchName; + PostalCode = postalCode; + Language = language; + } + } + + public class PostalInformationNameConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("postal_information_name", Schema.Integration) + .HasKey(p => p.Id); + + builder.Property(p => p.Id) + .ValueGeneratedOnAdd() + .HasColumnName("id");; + + builder.Property(p => p.Name) + .IsRequired() + .HasColumnName("name");; + builder.Property(p => p.SearchName) + .IsRequired() + .HasColumnName("search_name");; + builder.Property(p => p.PostalCode) + .HasColumnName("postal_code");; + builder.Property(p => p.Language) + .HasColumnName("language");; + + builder.HasIndex(x => x.PostalCode); + builder.HasIndex(x => x.SearchName); + } + } +} diff --git a/src/PostalRegistry.Projections.Integration/PostalLatestItem.cs b/src/PostalRegistry.Projections.Integration/PostalLatestItem.cs new file mode 100644 index 00000000..34b883f3 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/PostalLatestItem.cs @@ -0,0 +1,66 @@ +namespace PostalRegistry.Projections.Integration +{ + using System; + using System.Collections.Generic; + using Be.Vlaanderen.Basisregisters.GrAr.Common; + using Be.Vlaanderen.Basisregisters.Utilities; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Metadata.Builders; + using NodaTime; + using PostalRegistry.Infrastructure; + + public sealed class PostalLatestItem + { + public const string VersionTimestampBackingPropertyName = nameof(VersionTimestampAsDateTimeOffset); + + public string PostalCode { get; set; } + public string? NisCode { get; set; } + public bool IsRetired { get; set; } + public List PostalNames { get; set; } + public string? PuriId { get; set; } + public string? Namespace { get; set; } + + private DateTimeOffset VersionTimestampAsDateTimeOffset { get; set; } + + public Instant VersionTimestamp + { + get => Instant.FromDateTimeOffset(VersionTimestampAsDateTimeOffset); + set => VersionTimestampAsDateTimeOffset = value.ToDateTimeOffset(); + } + public PostalLatestItem() + { } + } + + public sealed class MunicipalityLatestItemConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder + .ToTable("postal_latest_items", Schema.Integration) + .HasKey(x => x.PostalCode); + + builder.Property(p => p.PostalCode) + .HasColumnName("postal_code"); + + builder.Property(p => p.NisCode) + .HasColumnName("nis_code"); + + builder.Property(p => p.IsRetired) + .HasColumnName("is_retired"); + + builder.HasMany(p => p.PostalNames) + .WithOne() + .HasForeignKey(p => p.PostalCode); + + builder.Property(PostalLatestItem.VersionTimestampBackingPropertyName) + .HasColumnName("version_timestamp"); + + builder.Property(x => x.PuriId).HasColumnName("puri_id"); + builder.Property(x => x.Namespace).HasColumnName("namespace"); + + builder.Ignore(p => p.VersionTimestamp); + + builder.HasIndex(x => x.NisCode); + } + } +} diff --git a/src/PostalRegistry.Projections.Integration/PostalLatestItemExtensions.cs b/src/PostalRegistry.Projections.Integration/PostalLatestItemExtensions.cs new file mode 100644 index 00000000..848fad83 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/PostalLatestItemExtensions.cs @@ -0,0 +1,30 @@ +namespace PostalRegistry.Projections.Integration +{ + using System; + using System.Threading; + using System.Threading.Tasks; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; + + public static class PostalLatestItemExtensions + { + public static async Task FindAndUpdatePostal(this IntegrationContext context, + string postalCode, + Action updateFunc, + CancellationToken ct) + { + var postalItem = await context + .PostalLatestItems + .FindAsync(postalCode, cancellationToken: ct); + + if (postalItem == null) + throw DatabaseItemNotFound(postalCode); + + updateFunc(postalItem); + + return postalItem; + } + + private static ProjectionItemNotFoundException DatabaseItemNotFound(string postalCode) + => new ProjectionItemNotFoundException(postalCode); + } +} diff --git a/src/PostalRegistry.Projections.Integration/PostalLatestItemProjections.cs b/src/PostalRegistry.Projections.Integration/PostalLatestItemProjections.cs new file mode 100644 index 00000000..aa4f6156 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/PostalLatestItemProjections.cs @@ -0,0 +1,119 @@ +namespace PostalRegistry.Projections.Integration +{ + using System; + using System.Collections.Generic; + using System.Linq; + using Be.Vlaanderen.Basisregisters.GrAr.Common; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore; + using Infrastructure; + using Microsoft.Extensions.Options; + using NodaTime; + using PostalInformation.Events; + + [ConnectedProjectionName("Integratie postinfo latest item")] + [ConnectedProjectionDescription("Projectie die de laatste postinfo data voor de integratie database bijhoudt.")] + public sealed class PostalLatestItemProjections : ConnectedProjection + { + public PostalLatestItemProjections(IOptions options) + { + When>(async (context, message, ct) => + { + await context + .PostalLatestItems + .AddAsync( + new PostalLatestItem + { + PostalCode = message.Message.PostalCode, + Namespace = options.Value.Namespace, + PuriId = $"{options.Value.Namespace}/{message.Message.PostalCode}", + VersionTimestamp = message.Message.Provenance.Timestamp + }, ct); + }); + + When>(async (context, message, ct) => + { + await context.FindAndUpdatePostal( + message.Message.PostalCode, + postalInformation => + { + postalInformation.NisCode = message.Message.NisCode; + UpdateVersionTimestamp(postalInformation, message.Message.Provenance.Timestamp); + }, + ct); + }); + + When>(async (context, message, ct) => + { + await context.FindAndUpdatePostal( + message.Message.PostalCode, + postalInformation => + { + postalInformation.IsRetired = false; + UpdateVersionTimestamp(postalInformation, message.Message.Provenance.Timestamp); + }, + ct); + }); + + When>(async (context, message, ct) => + { + await context.FindAndUpdatePostal( + message.Message.PostalCode, + postalInformation => + { + if (postalInformation.PostalNames != null + && postalInformation.PostalNames.Any(p => + p.Name.Equals(message.Message.Name, StringComparison.OrdinalIgnoreCase))) + { + return; + } + + var postalInformationName = new PostalInformationName( + message.Message.Name, + message.Message.Name.RemoveDiacritics(), + postalInformation.PostalCode, + message.Message.Language); + + if (postalInformation.PostalNames == null) + { + postalInformation.PostalNames = new List { postalInformationName }; + } + else + { + postalInformation.PostalNames.Add(postalInformationName); + } + + UpdateVersionTimestamp(postalInformation, message.Message.Provenance.Timestamp); + }, + ct); + }); + + When>(async (context, message, ct) => + { + await context.FindAndUpdatePostal( + message.Message.PostalCode, + postalInformation => + { + postalInformation.PostalNames.RemoveAll(r => r.Name == message.Message.Name); + UpdateVersionTimestamp(postalInformation, message.Message.Provenance.Timestamp); + }, + ct); + }); + + When>(async (context, message, ct) => + { + await context.FindAndUpdatePostal( + message.Message.PostalCode, + postalInformation => + { + postalInformation.IsRetired = true; + UpdateVersionTimestamp(postalInformation, message.Message.Provenance.Timestamp); + }, + ct); + }); + } + + private static void UpdateVersionTimestamp(PostalLatestItem postal, Instant versionTimestamp) + => postal.VersionTimestamp = versionTimestamp; + } +} diff --git a/src/PostalRegistry.Projections.Integration/PostalRegistry.Projections.Integration.csproj b/src/PostalRegistry.Projections.Integration/PostalRegistry.Projections.Integration.csproj new file mode 100644 index 00000000..75b7bca2 --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/PostalRegistry.Projections.Integration.csproj @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/PostalRegistry.Projections.Integration/Properties/AssemblyInfo.cs b/src/PostalRegistry.Projections.Integration/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..91febbca --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyDescription("PostalRegistry Integration Projections")] + +[assembly: ComVisible(false)] +[assembly: Guid("58594a67-dce5-4fcf-be3d-fa00b8ed9f13")] diff --git a/src/PostalRegistry.Projections.Integration/paket.references b/src/PostalRegistry.Projections.Integration/paket.references new file mode 100644 index 00000000..0b4c6c3d --- /dev/null +++ b/src/PostalRegistry.Projections.Integration/paket.references @@ -0,0 +1,13 @@ +Be.Vlaanderen.Basisregisters.AggregateSource +Be.Vlaanderen.Basisregisters.EventHandling.Autofac +Be.Vlaanderen.Basisregisters.DataDog.Tracing.Sql +Be.Vlaanderen.Basisregisters.ProjectionHandling.Runner.Npgsql +Be.Vlaanderen.Basisregisters.ProjectionHandling.SqlStreamStore.Autofac + +Npgsql.EntityFrameworkCore.PostgreSQL.Design + +Be.Vlaanderen.Basisregisters.GrAr.Common +Be.Vlaanderen.Basisregisters.GrAr.Legacy + +SourceLink.Embed.AllSourceFiles +SourceLink.Copy.PdbFiles diff --git a/src/PostalRegistry.Projector/Infrastructure/Modules/ApiModule.cs b/src/PostalRegistry.Projector/Infrastructure/Modules/ApiModule.cs index 33dc29e7..ca1f1975 100755 --- a/src/PostalRegistry.Projector/Infrastructure/Modules/ApiModule.cs +++ b/src/PostalRegistry.Projector/Infrastructure/Modules/ApiModule.cs @@ -20,6 +20,8 @@ namespace PostalRegistry.Projector.Infrastructure.Modules using PostalRegistry.Infrastructure; using PostalRegistry.Projections.Extract; using PostalRegistry.Projections.Extract.PostalInformationExtract; + using PostalRegistry.Projections.Integration; + using PostalRegistry.Projections.Integration.Infrastructure; using PostalRegistry.Projections.LastChangedList; using PostalRegistry.Projections.Legacy; using PostalRegistry.Projections.Legacy.PostalInformation; @@ -68,6 +70,26 @@ private void RegisterProjectionSetup(ContainerBuilder builder) RegisterExtractProjections(builder); RegisterLastChangedProjections(builder); RegisterLegacyProjections(builder); + + if(_configuration.GetSection("Integration").GetValue("Enabled", false)) + RegisterIntegrationProjections(builder); + } + + private void RegisterIntegrationProjections(ContainerBuilder builder) + { + builder + .RegisterModule( + new IntegrationModule( + _configuration, + _services, + _loggerFactory)); + builder + .RegisterProjectionMigrator( + _configuration, + _loggerFactory) + .RegisterProjections( + context => new PostalLatestItemProjections(context.Resolve>()), + ConnectedProjectionSettings.Default); } private void RegisterExtractProjections(ContainerBuilder builder) diff --git a/src/PostalRegistry.Projector/Infrastructure/Startup.cs b/src/PostalRegistry.Projector/Infrastructure/Startup.cs index 1af412b4..4e1aea08 100755 --- a/src/PostalRegistry.Projector/Infrastructure/Startup.cs +++ b/src/PostalRegistry.Projector/Infrastructure/Startup.cs @@ -23,6 +23,7 @@ namespace PostalRegistry.Projector.Infrastructure using PostalRegistry.Projections.Legacy; using Microsoft.OpenApi.Models; using System.Threading; + using PostalRegistry.Projections.Integration.Infrastructure; /// Represents the startup process for the application. public class Startup @@ -92,12 +93,25 @@ public IServiceProvider ConfigureServices(IServiceCollection services) var connectionStrings = _configuration .GetSection("ConnectionStrings") .GetChildren(); + if (!_configuration.GetSection("Integration").GetValue("Enabled", false)) + connectionStrings = connectionStrings + .Where(x => !x.Key.StartsWith("Integration", StringComparison.OrdinalIgnoreCase)) + .ToList(); - foreach (var connectionString in connectionStrings) + + foreach (var connectionString in connectionStrings.Where(x => !x.Value.Contains("host", StringComparison.OrdinalIgnoreCase))) + { health.AddSqlServer( connectionString.Value, name: $"sqlserver-{connectionString.Key.ToLowerInvariant()}", tags: new[] {DatabaseTag, "sql", "sqlserver"}); + } + + foreach (var connectionString in connectionStrings.Where(x => x.Value.Contains("host", StringComparison.OrdinalIgnoreCase))) + health.AddNpgSql( + connectionString.Value, + name: $"npgsql-{connectionString.Key.ToLowerInvariant()}", + tags: new[] {DatabaseTag, "sql", "npgsql"}); health.AddDbContextCheck( $"dbcontext-{nameof(ExtractContext).ToLowerInvariant()}", @@ -113,7 +127,8 @@ public IServiceProvider ConfigureServices(IServiceCollection services) } } }) - .Configure(_configuration.GetSection("Extract")); + .Configure(_configuration.GetSection("Extract")) + .Configure(_configuration.GetSection("Integration")); var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterModule(new LoggingModule(_configuration, services)); diff --git a/src/PostalRegistry.Projector/PostalRegistry.Projector.csproj b/src/PostalRegistry.Projector/PostalRegistry.Projector.csproj index 184901b2..4b398fad 100644 --- a/src/PostalRegistry.Projector/PostalRegistry.Projector.csproj +++ b/src/PostalRegistry.Projector/PostalRegistry.Projector.csproj @@ -26,6 +26,7 @@ + diff --git a/src/PostalRegistry.Projector/appsettings.json b/src/PostalRegistry.Projector/appsettings.json index 32b25cc4..4d7d2284 100755 --- a/src/PostalRegistry.Projector/appsettings.json +++ b/src/PostalRegistry.Projector/appsettings.json @@ -7,7 +7,9 @@ "ExtractProjectionsAdmin": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.PostalRegistry;Trusted_Connection=True;", "LastChangedList": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.PostalRegistry;Trusted_Connection=True;", "LastChangedListAdmin": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.PostalRegistry;Trusted_Connection=True;", - "Syndication": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.PostalRegistry;Trusted_Connection=True;" + "Syndication": "Server=(localdb)\\mssqllocaldb;Database=EFProviders.InMemory.PostalRegistry;Trusted_Connection=True;", + "IntegrationProjections": ".", + "IntegrationProjectionsAdmin": "." }, "DataDog": { @@ -16,6 +18,11 @@ "ServiceName": "postal-registry-projector-dev" }, + "Integration": { + "Namespace": "https://data.vlaanderen.be/id/postinfo", + "Enabled": false + }, + "BaseUrl": "https://api.staging-basisregisters.vlaanderen/", "Extract": { @@ -23,7 +30,7 @@ }, "DistributedLock": { - "Region": "eu-west-1", + "Region": "eu-west-1", "TableName": "__DistributedLocks__", "LeasePeriodInMinutes": 5, "ThrowOnFailedRenew": true, diff --git a/src/PostalRegistry.Projector/paket.references b/src/PostalRegistry.Projector/paket.references index 9b67d2ec..c18e667b 100644 --- a/src/PostalRegistry.Projector/paket.references +++ b/src/PostalRegistry.Projector/paket.references @@ -4,7 +4,14 @@ Be.Vlaanderen.Basisregisters.EventHandling.Autofac Be.Vlaanderen.Basisregisters.DataDog.Tracing.Autofac Be.Vlaanderen.Basisregisters.Projector +Npgsql +Npgsql.EntityFrameworkCore.PostgreSQL + AspNetCore.HealthChecks.SqlServer +AspNetCore.HealthChecks.NpgSql + +NodaTime + Dapper SourceLink.Embed.AllSourceFiles diff --git a/test/PostalRegistry.Tests/AutoFixture/InfrastructureCustomization.cs b/test/PostalRegistry.Tests/AutoFixture/InfrastructureCustomization.cs new file mode 100644 index 00000000..6bbdb222 --- /dev/null +++ b/test/PostalRegistry.Tests/AutoFixture/InfrastructureCustomization.cs @@ -0,0 +1,13 @@ +namespace PostalRegistry.Tests.AutoFixture +{ + using global::AutoFixture; + + public class InfrastructureCustomization : ICustomization + { + public void Customize(IFixture fixture) + { + fixture.Customize(new NodaTimeCustomization()); + fixture.Customize(new SetProvenanceImplementationsCallSetProvenance()); + } + } +} diff --git a/test/PostalRegistry.Tests/AutoFixture/IntegerNisCode.cs b/test/PostalRegistry.Tests/AutoFixture/IntegerNisCode.cs new file mode 100644 index 00000000..39ffe072 --- /dev/null +++ b/test/PostalRegistry.Tests/AutoFixture/IntegerNisCode.cs @@ -0,0 +1,39 @@ +namespace PostalRegistry.Tests.AutoFixture +{ + using global::AutoFixture; + using global::AutoFixture.Kernel; + + public class WithIntegerNisCode : ICustomization + { + public void Customize(IFixture fixture) + { + var nisCode = new NisCode(fixture.Create().ToString()); + fixture.Register(() => nisCode); + + fixture.Customizations.Add( + new FilteringSpecimenBuilder( + new FixedBuilder(nisCode.ToString()), + new ParameterSpecification( + typeof(string), + "nisCode"))); + } + } + + public class WithFixedPostalCode : ICustomization + { + public void Customize(IFixture fixture) + { + + var postalCode = new PostalCode("9000"); + + fixture.Register(() => postalCode); + + fixture.Customizations.Add( + new FilteringSpecimenBuilder( + new FixedBuilder(postalCode), + new ParameterSpecification( + typeof(string), + "postalCode"))); + } + } +} diff --git a/test/PostalRegistry.Tests/AutoFixture/NodaTimeCustomization.cs b/test/PostalRegistry.Tests/AutoFixture/NodaTimeCustomization.cs new file mode 100644 index 00000000..dce9bb50 --- /dev/null +++ b/test/PostalRegistry.Tests/AutoFixture/NodaTimeCustomization.cs @@ -0,0 +1,78 @@ +namespace PostalRegistry.Tests.AutoFixture +{ + using System; + using global::AutoFixture; + using global::AutoFixture.Kernel; + using NodaTime; + + public class NodaTimeCustomization : ICustomization + { + public void Customize(IFixture fixture) + { + fixture.Customizations.Add(new LocalDateGenerator()); + fixture.Customizations.Add(new LocalTimeGenerator()); + fixture.Customizations.Add(new InstantGenerator()); + fixture.Customizations.Add(new LocalDateTimeGenerator()); + } + + public class LocalDateGenerator : ISpecimenBuilder + { + public object Create(object request, ISpecimenContext context) + { + if (context == null) + throw new ArgumentNullException(nameof(context)); + + if (!typeof(LocalDate).Equals(request)) + return new NoSpecimen(); + + return LocalDate.FromDateTime(DateTime.Today); + } + } + + public class LocalTimeGenerator : ISpecimenBuilder + { + public object Create(object request, ISpecimenContext context) + { + if (context == null) + throw new ArgumentNullException(nameof(context)); + + if (!typeof(LocalTime).Equals(request)) + return new NoSpecimen(); + + return LocalTime.FromTicksSinceMidnight(DateTime.Now.TimeOfDay.Ticks); + } + } + + public class InstantGenerator : ISpecimenBuilder + { + public object Create(object request, ISpecimenContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + if (!typeof(Instant).Equals(request)) + { + return new NoSpecimen(); + } + + return Instant.FromDateTimeOffset(DateTimeOffset.Now); + } + } + + public class LocalDateTimeGenerator : ISpecimenBuilder + { + public object Create(object request, ISpecimenContext context) + { + if (context == null) + throw new ArgumentNullException(nameof(context)); + + if (!typeof(LocalDateTime).Equals(request)) + return new NoSpecimen(); + + return LocalDateTime.FromDateTime(DateTime.Now); + } + } + } +} diff --git a/test/PostalRegistry.Tests/AutoFixture/PrivateGreedyConstructorQuery.cs b/test/PostalRegistry.Tests/AutoFixture/PrivateGreedyConstructorQuery.cs new file mode 100644 index 00000000..7c223152 --- /dev/null +++ b/test/PostalRegistry.Tests/AutoFixture/PrivateGreedyConstructorQuery.cs @@ -0,0 +1,46 @@ +namespace PostalRegistry.Tests.AutoFixture +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using global::AutoFixture.Kernel; + + /// + /// Selects public constructors ordered by the most modest constructor first. + /// + public class PrivateGreedyConstructorQuery : IMethodQuery + { + /// + /// Selects the constructors for the supplied type. + /// + /// The type. + /// + /// All public constructors for , ordered by the most modest + /// constructor first. + /// + /// + /// + /// The ordering of the returned constructors is based on the number of parameters of the + /// constructor. Constructors with fewer parameters are returned before constructors with + /// more parameters. This means that if a default constructor exists, it will be the first + /// one returned. + /// + /// + /// In case of two constructors with an equal number of parameters, the ordering is + /// unspecified. + /// + /// + public IEnumerable SelectMethods(Type type) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + + return from ci in type.GetTypeInfo().GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + let parameters = ci.GetParameters() + where parameters.All(p => p.ParameterType != type) + orderby parameters.Length descending + select new ConstructorMethod(ci) as IMethod; + } + } +} diff --git a/test/PostalRegistry.Tests/AutoFixture/SetProvenanceImplementationsCallSetProvenance.cs b/test/PostalRegistry.Tests/AutoFixture/SetProvenanceImplementationsCallSetProvenance.cs new file mode 100644 index 00000000..26c5af4c --- /dev/null +++ b/test/PostalRegistry.Tests/AutoFixture/SetProvenanceImplementationsCallSetProvenance.cs @@ -0,0 +1,41 @@ +namespace PostalRegistry.Tests.AutoFixture +{ + using System; + using System.Linq; + using System.Reflection; + using System.Runtime.CompilerServices; + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using global::AutoFixture; + using global::AutoFixture.Dsl; + using global::AutoFixture.Kernel; + + public class SetProvenanceImplementationsCallSetProvenance : ICustomization + { + public void Customize(IFixture fixture) + { + bool IsEventNamespace(Type t) => t.Namespace.EndsWith("Events"); + bool IsNotCompilerGenerated(MemberInfo t) => Attribute.GetCustomAttribute(t, typeof(CompilerGeneratedAttribute)) == null; + + var provenanceEventTypes = typeof(DomainAssemblyMarker).Assembly + .GetTypes() + .Where(t => t.IsClass && t.Namespace != null && IsEventNamespace(t) && IsNotCompilerGenerated(t) && t.GetInterfaces().Any(i => i == typeof(ISetProvenance))) + .ToList(); + + foreach (var allEventType in provenanceEventTypes) + { + var getSetProvenanceMethod = GetType() + .GetMethod(nameof(GetSetProvenance), BindingFlags.NonPublic | BindingFlags.Instance) + .MakeGenericMethod(allEventType); + var setProvenanceDelegate = getSetProvenanceMethod.Invoke(this, new object[] { fixture.Create() }); + + var customizeMethod = typeof(Fixture).GetMethods().Single(m => m.Name == "Customize" && m.IsGenericMethod); + var genericCustomizeMethod = customizeMethod.MakeGenericMethod(allEventType); + genericCustomizeMethod.Invoke(fixture, new object[] { setProvenanceDelegate }); + } + } + + private Func, ISpecimenBuilder> GetSetProvenance(Provenance provenance) + where T : ISetProvenance => + c => c.Do(@event => (@event as ISetProvenance).SetProvenance(provenance)); + } +} diff --git a/test/PostalRegistry.Tests/Builders/PostalInformationPostalNameWasAddedBuilder.cs b/test/PostalRegistry.Tests/Builders/PostalInformationPostalNameWasAddedBuilder.cs new file mode 100644 index 00000000..9ee5ee94 --- /dev/null +++ b/test/PostalRegistry.Tests/Builders/PostalInformationPostalNameWasAddedBuilder.cs @@ -0,0 +1,34 @@ +namespace PostalRegistry.Tests.Builders +{ + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using global::AutoFixture; + using PostalInformation.Events; + + public class PostalInformationPostalNameWasAddedBuilder + { + private PostalName? _name; + private readonly Fixture _fixture; + + public PostalInformationPostalNameWasAddedBuilder(Fixture fixture) + { + _fixture = fixture; + } + + public PostalInformationPostalNameWasAddedBuilder WithName(string name, Language language) + { + _name = new PostalName(name, language); + + return this; + } + + public PostalInformationPostalNameWasAdded Build() + { + var @event = new PostalInformationPostalNameWasAdded( + _fixture.Create(), + _name ?? _fixture.Create()); + ((ISetProvenance)@event).SetProvenance(_fixture.Create()); + + return @event; + } + } +} diff --git a/test/PostalRegistry.Tests/Builders/PostalInformationPostalNameWasRemovedBuilder.cs b/test/PostalRegistry.Tests/Builders/PostalInformationPostalNameWasRemovedBuilder.cs new file mode 100644 index 00000000..8312c230 --- /dev/null +++ b/test/PostalRegistry.Tests/Builders/PostalInformationPostalNameWasRemovedBuilder.cs @@ -0,0 +1,34 @@ +namespace PostalRegistry.Tests.Builders +{ + using Be.Vlaanderen.Basisregisters.GrAr.Provenance; + using global::AutoFixture; + using PostalInformation.Events; + + public class PostalInformationPostalNameWasRemovedBuilder + { + private PostalName? _name; + private readonly Fixture _fixture; + + public PostalInformationPostalNameWasRemovedBuilder(Fixture fixture) + { + _fixture = fixture; + } + + public PostalInformationPostalNameWasRemovedBuilder WithName(string name, Language language) + { + _name = new PostalName(name, language); + + return this; + } + + public PostalInformationPostalNameWasRemoved Build() + { + var @event = new PostalInformationPostalNameWasRemoved( + _fixture.Create(), + _name ?? _fixture.Create()); + ((ISetProvenance)@event).SetProvenance(_fixture.Create()); + + return @event; + } + } +} diff --git a/test/PostalRegistry.Tests/Integration/IntegrationProjectionTest.cs b/test/PostalRegistry.Tests/Integration/IntegrationProjectionTest.cs new file mode 100644 index 00000000..8f58d668 --- /dev/null +++ b/test/PostalRegistry.Tests/Integration/IntegrationProjectionTest.cs @@ -0,0 +1,30 @@ +namespace PostalRegistry.Tests.Integration +{ + using System; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector; + using Be.Vlaanderen.Basisregisters.ProjectionHandling.Testing; + using Microsoft.EntityFrameworkCore; + using Projections.Integration; + + public abstract class IntegrationProjectionTest + where TProjection : ConnectedProjection + { + protected ConnectedProjectionTest Sut { get; } + + protected IntegrationProjectionTest() + { + Sut = new ConnectedProjectionTest(CreateContext, CreateProjection); + } + + protected virtual IntegrationContext CreateContext() + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .Options; + + return new IntegrationContext(options); + } + + protected abstract TProjection CreateProjection(); + } +} diff --git a/test/PostalRegistry.Tests/Integration/PostalLatestItemTest.cs b/test/PostalRegistry.Tests/Integration/PostalLatestItemTest.cs new file mode 100644 index 00000000..71dc6f5d --- /dev/null +++ b/test/PostalRegistry.Tests/Integration/PostalLatestItemTest.cs @@ -0,0 +1,164 @@ +namespace PostalRegistry.Tests.Integration +{ + using System.Threading.Tasks; + using AutoFixture; + using Builders; + using FluentAssertions; + using global::AutoFixture; + using Microsoft.Extensions.Options; + using PostalInformation.Events; + using Projections.Integration; + using Projections.Integration.Infrastructure; + using Xunit; + + public class PostalLatestItemTest : IntegrationProjectionTest + { + private const string Namespace = "https://data.vlaanderen.be/id/postinfo"; + private readonly Fixture _fixture; + + public PostalLatestItemTest() + { + _fixture = new Fixture(); + _fixture.Customize(new InfrastructureCustomization()); + _fixture.Customize(new WithIntegerNisCode()); + _fixture.Customize(new WithFixedPostalCode()); + } + + [Fact] + public async Task WhenPostalInformationWasRegistered() + { + var postalInformationWasRegistered = _fixture.Create(); + + await Sut + .Given(postalInformationWasRegistered) + .Then(async ct => + { + var expectedLatestItem = + await ct.PostalLatestItems.FindAsync(postalInformationWasRegistered.PostalCode); + expectedLatestItem.Should().NotBeNull(); + expectedLatestItem!.Namespace.Should().Be(Namespace); + expectedLatestItem.PuriId.Should().Be($"{Namespace}/{postalInformationWasRegistered.PostalCode}"); + expectedLatestItem.VersionTimestamp.Should() + .Be(postalInformationWasRegistered.Provenance.Timestamp); + }); + } + + [Fact] + public async Task WhenMunicipalityWasAttached() + { + var municipalityWasAttached = _fixture.Create(); + + await Sut + .Given( + _fixture.Create(), + municipalityWasAttached) + .Then(async ct => + { + var expectedLatestItem = + await ct.PostalLatestItems.FindAsync(municipalityWasAttached.PostalCode); + expectedLatestItem.Should().NotBeNull(); + expectedLatestItem!.NisCode.Should().Be(municipalityWasAttached.NisCode); + }); + } + + [Fact] + public async Task WhenPostalInformationWasRealized() + { + var postalInformationWasRealized = _fixture.Create(); + + await Sut + .Given( + _fixture.Create(), + postalInformationWasRealized) + .Then(async ct => + { + var expectedLatestItem = + await ct.PostalLatestItems.FindAsync(postalInformationWasRealized.PostalCode); + expectedLatestItem.Should().NotBeNull(); + expectedLatestItem!.IsRetired.Should().BeFalse(); + }); + } + + [Fact] + public async Task WhenPostalInformationPostalNameWasAdded() + { + var postalInformationPostalNameWasAdded = new PostalInformationPostalNameWasAddedBuilder(_fixture) + .WithName("dutchPostal", Language.Dutch) + .Build(); + var secondPostalNameWasAdded = new PostalInformationPostalNameWasAddedBuilder(_fixture) + .WithName("dutchFrench", Language.French) + .Build(); + + var thirdPostalNameThatShouldNotBeAdded = new PostalInformationPostalNameWasAddedBuilder(_fixture) + .WithName(secondPostalNameWasAdded.Name, secondPostalNameWasAdded.Language) + .Build(); + + await Sut + .Given( + _fixture.Create(), + postalInformationPostalNameWasAdded, + secondPostalNameWasAdded, + thirdPostalNameThatShouldNotBeAdded) + .Then(async ct => + { + var expectedLatestItem = + await ct.PostalLatestItems.FindAsync(postalInformationPostalNameWasAdded.PostalCode); + expectedLatestItem.Should().NotBeNull(); + expectedLatestItem!.Namespace.Should().Be(Namespace); + + expectedLatestItem.PostalNames.Count.Should().Be(2); + + expectedLatestItem.IsRetired.Should().BeFalse(); + expectedLatestItem.PuriId.Should() + .Be($"{Namespace}/{postalInformationPostalNameWasAdded.PostalCode}"); + }); + } + + [Fact] + public async Task WhenPostalInformationPostalNameWasRemoved() + { + var postalInformationPostalNameWasAdded = new PostalInformationPostalNameWasAddedBuilder(_fixture) + .WithName("dutchPostal", Language.Dutch) + .Build(); + + var postalInformationPostalNameWasRemoved = new PostalInformationPostalNameWasRemovedBuilder(_fixture) + .WithName(postalInformationPostalNameWasAdded.Name, postalInformationPostalNameWasAdded.Language) + .Build(); + + await Sut + .Given( + _fixture.Create(), + postalInformationPostalNameWasAdded, + postalInformationPostalNameWasRemoved) + .Then(async ct => + { + var expectedLatestItem = + await ct.PostalLatestItems.FindAsync(postalInformationPostalNameWasAdded.PostalCode); + expectedLatestItem.Should().NotBeNull(); + expectedLatestItem!.PostalNames.Count.Should().Be(0); + }); + } + + [Fact] + public async Task WhenPostalInformationWasRetired() + { + var postalInformationWasRetired = _fixture.Create(); + + await Sut + .Given( + _fixture.Create(), + postalInformationWasRetired) + .Then(async ct => + { + var expectedLatestItem = + await ct.PostalLatestItems.FindAsync(postalInformationWasRetired.PostalCode); + expectedLatestItem.Should().NotBeNull(); + expectedLatestItem!.IsRetired.Should().BeTrue(); + }); + } + + protected override PostalLatestItemProjections CreateProjection() + => new PostalLatestItemProjections( + new OptionsWrapper(new IntegrationOptions { Namespace = Namespace })); + } +} diff --git a/test/PostalRegistry.Tests/PostalRegistry.Tests.csproj b/test/PostalRegistry.Tests/PostalRegistry.Tests.csproj index 839560a2..30b7279b 100644 --- a/test/PostalRegistry.Tests/PostalRegistry.Tests.csproj +++ b/test/PostalRegistry.Tests/PostalRegistry.Tests.csproj @@ -3,6 +3,7 @@ + diff --git a/test/PostalRegistry.Tests/paket.references b/test/PostalRegistry.Tests/paket.references index b347f920..551aa96d 100755 --- a/test/PostalRegistry.Tests/paket.references +++ b/test/PostalRegistry.Tests/paket.references @@ -9,4 +9,7 @@ Be.Vlaanderen.Basisregisters.AggregateSource.Testing Be.Vlaanderen.Basisregisters.AggregateSource.Testing.SqlStreamStore.Autofac Be.Vlaanderen.Basisregisters.AggregateSource.Testing.Xunit +Be.Vlaanderen.Basisregisters.ProjectionHandling.Connector.Testing +Be.Vlaanderen.Basisregisters.ProjectionHandling.Testing.Xunit + Be.Vlaanderen.Basisregisters.EventHandling.Autofac