From 3fb555b46374944559f09ead7208306fa478dee1 Mon Sep 17 00:00:00 2001 From: Jan Lesage Date: Mon, 9 Dec 2024 13:08:48 +0100 Subject: [PATCH] test: or-2582 add support for public projection rebuild in projection context --- .../Extensions/ConfigurationExtensions.cs | 6 +-- .../Extensions/ElasticSearchExtensions.cs | 41 ++++++++++--------- .../Detail/BeheerDetailScenarioFixture.cs | 20 ++++----- .../BeheerHistoriekScenarioFixture.cs | 19 ++++----- .../Zoeken/BeheerZoekenScenarioFixture.cs | 17 +++++++- .../Framework/Fixtures/ScenarioFixture.cs | 9 +++- .../Framework/ProjectionContext.cs | 18 +++++--- .../Fixtures/PowerBiScenarioFixture.cs | 25 +++++------ .../Detail/PubliekDetailScenarioFixture.cs | 23 ++++++----- .../Zoeken/PubliekZoekenScenarioFixture.cs | 14 ++++++- 10 files changed, 115 insertions(+), 77 deletions(-) diff --git a/src/AssociationRegistry.Public.Api/Infrastructure/Extensions/ConfigurationExtensions.cs b/src/AssociationRegistry.Public.Api/Infrastructure/Extensions/ConfigurationExtensions.cs index e7ce33552..c4eeb6912 100644 --- a/src/AssociationRegistry.Public.Api/Infrastructure/Extensions/ConfigurationExtensions.cs +++ b/src/AssociationRegistry.Public.Api/Infrastructure/Extensions/ConfigurationExtensions.cs @@ -1,7 +1,7 @@ namespace AssociationRegistry.Public.Api.Infrastructure.Extensions; -using ConfigurationBindings; using Framework; +using Hosts.Configuration.ConfigurationBindings; using Microsoft.Extensions.Configuration; using System; @@ -10,8 +10,8 @@ public static class ConfigurationExtensions public static AssociationRegistry.Hosts.Configuration.ConfigurationBindings.PostgreSqlOptionsSection GetPostgreSqlOptionsSection(this IConfiguration configuration) { var postgreSqlOptionsSection = configuration - .GetSection(PostgreSqlOptionsSection.Name) - .Get(); + .GetSection(PostgreSqlOptionsSection.SectionName) + .Get(); postgreSqlOptionsSection.ThrowIfInvalid(); diff --git a/src/AssociationRegistry.Public.Api/Infrastructure/Extensions/ElasticSearchExtensions.cs b/src/AssociationRegistry.Public.Api/Infrastructure/Extensions/ElasticSearchExtensions.cs index 7d1123ba5..f2f862ff0 100644 --- a/src/AssociationRegistry.Public.Api/Infrastructure/Extensions/ElasticSearchExtensions.cs +++ b/src/AssociationRegistry.Public.Api/Infrastructure/Extensions/ElasticSearchExtensions.cs @@ -1,13 +1,9 @@ namespace AssociationRegistry.Public.Api.Infrastructure.Extensions; -using ConfigurationBindings; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Identity.Client; +using Hosts.Configuration.ConfigurationBindings; using Nest; using Schema; using Schema.Search; -using System; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; @@ -18,8 +14,13 @@ public static IServiceCollection AddElasticSearch( this IServiceCollection services, ElasticSearchOptionsSection elasticSearchOptions) { - services.AddSingleton(serviceProvider => CreateElasticClient(elasticSearchOptions, serviceProvider.GetRequiredService>())); - services.AddSingleton(serviceProvider => CreateElasticClient(elasticSearchOptions, serviceProvider.GetRequiredService>())); + services.AddSingleton(serviceProvider + => CreateElasticClient(elasticSearchOptions, + serviceProvider.GetRequiredService>())); + + services.AddSingleton(serviceProvider + => CreateElasticClient(elasticSearchOptions, + serviceProvider.GetRequiredService>())); services.AddSingleton(serviceProvider => { @@ -32,28 +33,28 @@ public static IServiceCollection AddElasticSearch( return services; } - private static ElasticClient CreateElasticClient(ElasticSearchOptionsSection elasticSearchOptions, ILogger logger) + public static ElasticClient CreateElasticClient(ElasticSearchOptionsSection elasticSearchOptions, ILogger logger) { var settings = new ConnectionSettings( new Uri(elasticSearchOptions.Uri!)) .BasicAuthentication( elasticSearchOptions.Username, elasticSearchOptions.Password) - .ServerCertificateValidationCallback((o, certificate, arg3, arg4) => - { - logger.LogWarning("Policy errors: [{Cert}|{Chain}] {Error}", certificate.Subject, arg3, arg4.ToString()); - logger.LogWarning("Policy object: {@Error}", o); + .ServerCertificateValidationCallback((o, certificate, arg3, arg4) => + { + logger.LogWarning("Policy errors: [{Cert}|{Chain}] {Error}", certificate.Subject, arg3, arg4.ToString()); + logger.LogWarning("Policy object: {@Error}", o); - if (arg4 != SslPolicyErrors.None) - { - logger.LogWarning(Convert.ToBase64String(certificate.Export(X509ContentType.Cert), - Base64FormattingOptions.InsertLineBreaks)); + if (arg4 != SslPolicyErrors.None) + { + logger.LogWarning(Convert.ToBase64String(certificate.Export(X509ContentType.Cert), + Base64FormattingOptions.InsertLineBreaks)); - LogCertificateDetails(certificate, arg3); - } + LogCertificateDetails(certificate, arg3); + } - return true; - }) + return true; + }) .IncludeServerStackTraceOnError() .MapVerenigingDocument(elasticSearchOptions.Indices!.Verenigingen!); diff --git a/test/AssociationRegistry.Test.Projections/Beheer/Detail/BeheerDetailScenarioFixture.cs b/test/AssociationRegistry.Test.Projections/Beheer/Detail/BeheerDetailScenarioFixture.cs index 7c2883684..ef5d1ae03 100644 --- a/test/AssociationRegistry.Test.Projections/Beheer/Detail/BeheerDetailScenarioFixture.cs +++ b/test/AssociationRegistry.Test.Projections/Beheer/Detail/BeheerDetailScenarioFixture.cs @@ -10,19 +10,17 @@ public class BeheerDetailScenarioFixture(ProjectionContext context) : ScenarioFixture(context) where TScenario : IScenario, new() { - protected override async Task GetResultAsync( - TScenario scenario) - { - var store = Context.AdminStore; - await using var session = store.LightweightSession(); - using var daemon = await store.BuildProjectionDaemonAsync(); + protected override IDocumentStore DocumentStore => Context.AdminStore; - await daemon.RebuildProjectionAsync(CancellationToken.None); + protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon) + => await daemon.RebuildProjectionAsync(CancellationToken.None); - return await session - .Query() - .SingleAsync(x => x.VCode == scenario.VCode); - } + protected override async Task GetResultAsync( + IDocumentSession session, + TScenario scenario) + => await session + .Query() + .SingleAsync(x => x.VCode == scenario.VCode); } public class BeheerDetailScenarioClassFixture diff --git a/test/AssociationRegistry.Test.Projections/Beheer/Historiek/BeheerHistoriekScenarioFixture.cs b/test/AssociationRegistry.Test.Projections/Beheer/Historiek/BeheerHistoriekScenarioFixture.cs index e1c67b774..1fb6f25ed 100644 --- a/test/AssociationRegistry.Test.Projections/Beheer/Historiek/BeheerHistoriekScenarioFixture.cs +++ b/test/AssociationRegistry.Test.Projections/Beheer/Historiek/BeheerHistoriekScenarioFixture.cs @@ -10,18 +10,17 @@ public class BeheerHistoriekScenarioFixture(ProjectionContext context : ScenarioFixture(context) where TScenario : IScenario, new() { + protected override IDocumentStore DocumentStore => Context.AdminStore; + + protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon) + => await daemon.RebuildProjectionAsync(CancellationToken.None); + protected override async Task GetResultAsync( + IDocumentSession session, TScenario scenario) - { - var store = Context.AdminStore; - await using var session = store.LightweightSession(); - using var daemon = await store.BuildProjectionDaemonAsync(); - - await daemon.RebuildProjectionAsync(CancellationToken.None); - return await session - .Query() - .SingleAsync(x => x.VCode == scenario.VCode); - } + => await session + .Query() + .SingleAsync(x => x.VCode == scenario.VCode); } public class BeheerHistoriekScenarioClassFixture diff --git a/test/AssociationRegistry.Test.Projections/Beheer/Zoeken/BeheerZoekenScenarioFixture.cs b/test/AssociationRegistry.Test.Projections/Beheer/Zoeken/BeheerZoekenScenarioFixture.cs index 8c52252e7..955e44f76 100644 --- a/test/AssociationRegistry.Test.Projections/Beheer/Zoeken/BeheerZoekenScenarioFixture.cs +++ b/test/AssociationRegistry.Test.Projections/Beheer/Zoeken/BeheerZoekenScenarioFixture.cs @@ -1,17 +1,30 @@ namespace AssociationRegistry.Test.Projections.Beheer.Zoeken; +using Admin.ProjectionHost.Projections; using Admin.Schema.Search; using Framework.Fixtures; +using Marten; +using Marten.Events.Daemon; +using Nest; public class BeheerZoekenScenarioFixture(ProjectionContext context) : ScenarioFixture(context) where TScenario : IScenario, new() { + protected override IDocumentStore DocumentStore => Context.AdminStore; + + protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon) + { + await daemon.RebuildProjectionAsync(ProjectionNames.BeheerZoek, CancellationToken.None); + await Context.AdminElasticClient.Indices.RefreshAsync(Indices.All); + } + protected override async Task GetResultAsync( + IDocumentSession _, TScenario scenario) { - var getResponse = - await Context.ElasticClient + var getResponse = + await Context.AdminElasticClient .GetAsync(scenario.VCode); return getResponse.Source; diff --git a/test/AssociationRegistry.Test.Projections/Framework/Fixtures/ScenarioFixture.cs b/test/AssociationRegistry.Test.Projections/Framework/Fixtures/ScenarioFixture.cs index 82cbf703d..983676e8d 100644 --- a/test/AssociationRegistry.Test.Projections/Framework/Fixtures/ScenarioFixture.cs +++ b/test/AssociationRegistry.Test.Projections/Framework/Fixtures/ScenarioFixture.cs @@ -1,6 +1,7 @@ namespace AssociationRegistry.Test.Projections.Framework.Fixtures; using AssociationRegistry.Framework; +using Marten; using Marten.Events.Daemon; using NodaTime; using NodaTime.Text; @@ -28,10 +29,16 @@ public async Task InitializeAsync() await Context.SaveAsync(Scenario.Events, session); - Result = await GetResultAsync(Scenario); + var currentStoreSession = DocumentStore.LightweightSession(); + using var daemon = await DocumentStore.BuildProjectionDaemonAsync(); + await RefreshProjectionsAsync(daemon); + Result = await GetResultAsync(currentStoreSession, Scenario); } + protected abstract IDocumentStore DocumentStore { get; } + protected abstract Task RefreshProjectionsAsync(IProjectionDaemon daemon); protected abstract Task GetResultAsync( + IDocumentSession session, TScenario scenario); public Task DisposeAsync() => Task.CompletedTask; } diff --git a/test/AssociationRegistry.Test.Projections/Framework/ProjectionContext.cs b/test/AssociationRegistry.Test.Projections/Framework/ProjectionContext.cs index 8e591895e..b5acb00ac 100644 --- a/test/AssociationRegistry.Test.Projections/Framework/ProjectionContext.cs +++ b/test/AssociationRegistry.Test.Projections/Framework/ProjectionContext.cs @@ -1,6 +1,5 @@ namespace AssociationRegistry.Test.Projections.Framework; -using Admin.Api.Infrastructure.Extensions; using Admin.ProjectionHost.Infrastructure.Program.WebApplicationBuilder; using Admin.ProjectionHost.Projections.Locaties; using Admin.ProjectionHost.Projections.Search; @@ -20,7 +19,8 @@ public class ProjectionContext : IProjectionContext, IAsyncLifetime private IConfigurationRoot Configuration { get; } public IDocumentStore AdminStore { get; set; } public IDocumentStore PublicStore { get; set; } - public IElasticClient ElasticClient { get; set; } + public IElasticClient AdminElasticClient { get; set; } + public IElasticClient PublicElasticClient { get; set; } public ProjectionContext() { @@ -29,10 +29,12 @@ public ProjectionContext() public async Task InitializeAsync() { - DropDatabase(Configuration); + // DropDatabase(Configuration); EnsureDbExists(Configuration); - ElasticClient = ElasticSearchExtensions.CreateElasticClient(Configuration.GetElasticSearchOptionsSection(), NullLogger.Instance); + AdminElasticClient = + Admin.Api.Infrastructure.Extensions.ElasticSearchExtensions.CreateElasticClient( + Configuration.GetElasticSearchOptionsSection(), NullLogger.Instance); var adminStore = DocumentStore.For( opts => @@ -40,7 +42,7 @@ public async Task InitializeAsync() ConfigureMartenExtensions.ConfigureStoreOptions(opts, NullLogger.Instance, NullLogger.Instance, - new ElasticRepository(ElasticClient), + new ElasticRepository(AdminElasticClient), true, NullLogger.Instance, new PostgreSqlOptionsSection() @@ -57,12 +59,16 @@ public async Task InitializeAsync() AdminStore = adminStore; + PublicElasticClient = + Public.Api.Infrastructure.Extensions.ElasticSearchExtensions.CreateElasticClient( + Configuration.GetElasticSearchOptionsSection(), NullLogger.Instance); + var publicStore = DocumentStore.For( opts => { Public.ProjectionHost.Infrastructure.Program.WebApplicationBuilder.ConfigureMartenExtensions.ConfigureStoreOptions( opts, - null, + new AssociationRegistry.Public.ProjectionHost.Projections.Search.ElasticRepository(PublicElasticClient), NullLogger.Instance, new PostgreSqlOptionsSection() { diff --git a/test/AssociationRegistry.Test.Projections/PowerBiExport/Fixtures/PowerBiScenarioFixture.cs b/test/AssociationRegistry.Test.Projections/PowerBiExport/Fixtures/PowerBiScenarioFixture.cs index e5dd22ca4..a85a634f8 100644 --- a/test/AssociationRegistry.Test.Projections/PowerBiExport/Fixtures/PowerBiScenarioFixture.cs +++ b/test/AssociationRegistry.Test.Projections/PowerBiExport/Fixtures/PowerBiScenarioFixture.cs @@ -1,6 +1,6 @@ -namespace AssociationRegistry.Test.Projections.Publiek.Detail; +namespace AssociationRegistry.Test.Projections.PowerBiExport; -using Admin.ProjectionHost.Projections.PowerBiExport; +using Admin.ProjectionHost.Projections; using Admin.Schema.PowerBiExport; using Framework.Fixtures; using Marten; @@ -10,18 +10,19 @@ public class PowerBiScenarioFixture(ProjectionContext context) : ScenarioFixture(context) where TScenario : IScenario, new() { - protected override async Task GetResultAsync( - TScenario scenario) - { - var store = Context.AdminStore; - await using var session = store.LightweightSession(); - using var daemon = await store.BuildProjectionDaemonAsync(); + protected override IDocumentStore DocumentStore => Context.AdminStore; - await daemon.RebuildProjectionAsync(CancellationToken.None); - return await session - .Query() - .SingleAsync(x => x.VCode == scenario.VCode); + protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon) + { + await daemon.RebuildProjectionAsync(ProjectionNames.PowerBi, CancellationToken.None); } + + protected override async Task GetResultAsync( + IDocumentSession session, + TScenario scenario) + => await session + .Query() + .SingleAsync(x => x.VCode == scenario.VCode); } public class PowerBiScenarioClassFixture diff --git a/test/AssociationRegistry.Test.Projections/Publiek/Detail/PubliekDetailScenarioFixture.cs b/test/AssociationRegistry.Test.Projections/Publiek/Detail/PubliekDetailScenarioFixture.cs index 305234a3c..b9f734e01 100644 --- a/test/AssociationRegistry.Test.Projections/Publiek/Detail/PubliekDetailScenarioFixture.cs +++ b/test/AssociationRegistry.Test.Projections/Publiek/Detail/PubliekDetailScenarioFixture.cs @@ -3,25 +3,26 @@ using Framework.Fixtures; using Marten; using Marten.Events.Daemon; -using Public.ProjectionHost.Projections.Detail; +using Public.ProjectionHost.Projections; using Public.Schema.Detail; public class PubliekDetailScenarioFixture(ProjectionContext context) : ScenarioFixture(context) where TScenario : IScenario, new() { - protected override async Task GetResultAsync( - TScenario scenario) - { - var store = Context.PublicStore; - await using var session = store.LightweightSession(); - using var daemon = await store.BuildProjectionDaemonAsync(); + protected override IDocumentStore DocumentStore => Context.PublicStore; - await daemon.RebuildProjectionAsync(CancellationToken.None); - return await session - .Query() - .SingleAsync(x => x.VCode == scenario.VCode); + protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon) + { + await daemon.RebuildProjectionAsync(ProjectionNames.PubliekDetail, CancellationToken.None); } + + protected override async Task GetResultAsync( + IDocumentSession session, + TScenario scenario) + => await session + .Query() + .SingleAsync(x => x.VCode == scenario.VCode); } public class PubliekDetailScenarioClassFixture diff --git a/test/AssociationRegistry.Test.Projections/Publiek/Zoeken/PubliekZoekenScenarioFixture.cs b/test/AssociationRegistry.Test.Projections/Publiek/Zoeken/PubliekZoekenScenarioFixture.cs index bd2b09822..73867ebd5 100644 --- a/test/AssociationRegistry.Test.Projections/Publiek/Zoeken/PubliekZoekenScenarioFixture.cs +++ b/test/AssociationRegistry.Test.Projections/Publiek/Zoeken/PubliekZoekenScenarioFixture.cs @@ -1,18 +1,30 @@ namespace AssociationRegistry.Test.Projections.Publiek.Zoeken; using Framework.Fixtures; +using Marten; using Marten.Events.Daemon; +using Nest; +using Public.ProjectionHost.Projections; using Public.Schema.Search; public class PubliekZoekenScenarioFixture(ProjectionContext context) : ScenarioFixture(context) where TScenario : IScenario, new() { + protected override IDocumentStore DocumentStore => Context.PublicStore; + + protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon) + { + await daemon.RebuildProjectionAsync(ProjectionNames.PubliekZoek, CancellationToken.None); + await Context.PublicElasticClient.Indices.RefreshAsync(Indices.All); + } + protected override async Task GetResultAsync( + IDocumentSession _, TScenario scenario) { var getResponse = - await Context.ElasticClient + await Context.PublicElasticClient .GetAsync(scenario.VCode); return getResponse.Source;