Skip to content

Commit

Permalink
test: or-2582 add support for public projection rebuild in projection…
Browse files Browse the repository at this point in the history
… context
  • Loading branch information
Jan Lesage committed Dec 9, 2024
1 parent a54665d commit 3fb555b
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 77 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace AssociationRegistry.Public.Api.Infrastructure.Extensions;

using ConfigurationBindings;
using Framework;
using Hosts.Configuration.ConfigurationBindings;
using Microsoft.Extensions.Configuration;
using System;

Expand All @@ -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<AssociationRegistry.Hosts.Configuration.ConfigurationBindings.PostgreSqlOptionsSection>();
.GetSection(PostgreSqlOptionsSection.SectionName)
.Get<PostgreSqlOptionsSection>();

postgreSqlOptionsSection.ThrowIfInvalid();

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -18,8 +14,13 @@ public static IServiceCollection AddElasticSearch(
this IServiceCollection services,
ElasticSearchOptionsSection elasticSearchOptions)
{
services.AddSingleton<ElasticClient>(serviceProvider => CreateElasticClient(elasticSearchOptions, serviceProvider.GetRequiredService<ILogger<ElasticClient>>()));
services.AddSingleton<IElasticClient>(serviceProvider => CreateElasticClient(elasticSearchOptions, serviceProvider.GetRequiredService<ILogger<ElasticClient>>()));
services.AddSingleton<ElasticClient>(serviceProvider
=> CreateElasticClient(elasticSearchOptions,
serviceProvider.GetRequiredService<ILogger<ElasticClient>>()));

services.AddSingleton<IElasticClient>(serviceProvider
=> CreateElasticClient(elasticSearchOptions,
serviceProvider.GetRequiredService<ILogger<ElasticClient>>()));

services.AddSingleton(serviceProvider =>
{
Expand All @@ -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!);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,17 @@ public class BeheerDetailScenarioFixture<TScenario>(ProjectionContext context)
: ScenarioFixture<TScenario, BeheerVerenigingDetailDocument, ProjectionContext>(context)
where TScenario : IScenario, new()
{
protected override async Task<BeheerVerenigingDetailDocument> 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<BeheerVerenigingDetailProjection>(CancellationToken.None);
protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon)
=> await daemon.RebuildProjectionAsync<BeheerVerenigingDetailProjection>(CancellationToken.None);

return await session
.Query<BeheerVerenigingDetailDocument>()
.SingleAsync(x => x.VCode == scenario.VCode);
}
protected override async Task<BeheerVerenigingDetailDocument> GetResultAsync(
IDocumentSession session,
TScenario scenario)
=> await session
.Query<BeheerVerenigingDetailDocument>()
.SingleAsync(x => x.VCode == scenario.VCode);
}

public class BeheerDetailScenarioClassFixture<TScenario>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ public class BeheerHistoriekScenarioFixture<TScenario>(ProjectionContext context
: ScenarioFixture<TScenario, BeheerVerenigingHistoriekDocument, ProjectionContext>(context)
where TScenario : IScenario, new()
{
protected override IDocumentStore DocumentStore => Context.AdminStore;

protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon)
=> await daemon.RebuildProjectionAsync<BeheerVerenigingHistoriekProjection>(CancellationToken.None);

protected override async Task<BeheerVerenigingHistoriekDocument> GetResultAsync(
IDocumentSession session,
TScenario scenario)
{
var store = Context.AdminStore;
await using var session = store.LightweightSession();
using var daemon = await store.BuildProjectionDaemonAsync();

await daemon.RebuildProjectionAsync<BeheerVerenigingHistoriekProjection>(CancellationToken.None);
return await session
.Query<BeheerVerenigingHistoriekDocument>()
.SingleAsync(x => x.VCode == scenario.VCode);
}
=> await session
.Query<BeheerVerenigingHistoriekDocument>()
.SingleAsync(x => x.VCode == scenario.VCode);
}

public class BeheerHistoriekScenarioClassFixture<TScenario>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<TScenario>(ProjectionContext context)
: ScenarioFixture<TScenario, VerenigingZoekDocument, ProjectionContext>(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<VerenigingZoekDocument> GetResultAsync(
IDocumentSession _,
TScenario scenario)
{
var getResponse =
await Context.ElasticClient
var getResponse =
await Context.AdminElasticClient
.GetAsync<VerenigingZoekDocument>(scenario.VCode);

return getResponse.Source;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace AssociationRegistry.Test.Projections.Framework.Fixtures;

using AssociationRegistry.Framework;
using Marten;
using Marten.Events.Daemon;
using NodaTime;
using NodaTime.Text;
Expand Down Expand Up @@ -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<TResult> GetResultAsync(
IDocumentSession session,
TScenario scenario);
public Task DisposeAsync() => Task.CompletedTask;
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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()
{
Expand All @@ -29,18 +29,20 @@ 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 =>
{
ConfigureMartenExtensions.ConfigureStoreOptions(opts,
NullLogger<LocatieLookupProjection>.Instance,
NullLogger<LocatieZonderAdresMatchProjection>.Instance,
new ElasticRepository(ElasticClient),
new ElasticRepository(AdminElasticClient),
true,
NullLogger<BeheerZoekenEventsConsumer>.Instance,
new PostgreSqlOptionsSection()
Expand All @@ -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<MartenEventsConsumer>.Instance,
new PostgreSqlOptionsSection()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -10,18 +10,19 @@ public class PowerBiScenarioFixture<TScenario>(ProjectionContext context)
: ScenarioFixture<TScenario, PowerBiExportDocument, ProjectionContext>(context)
where TScenario : IScenario, new()
{
protected override async Task<PowerBiExportDocument> 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<PowerBiExportProjection>(CancellationToken.None);
return await session
.Query<PowerBiExportDocument>()
.SingleAsync(x => x.VCode == scenario.VCode);
protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon)
{
await daemon.RebuildProjectionAsync(ProjectionNames.PowerBi, CancellationToken.None);
}

protected override async Task<PowerBiExportDocument> GetResultAsync(
IDocumentSession session,
TScenario scenario)
=> await session
.Query<PowerBiExportDocument>()
.SingleAsync(x => x.VCode == scenario.VCode);
}

public class PowerBiScenarioClassFixture<TScenario>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<TScenario>(ProjectionContext context)
: ScenarioFixture<TScenario, PubliekVerenigingDetailDocument, ProjectionContext>(context)
where TScenario : IScenario, new()
{
protected override async Task<PubliekVerenigingDetailDocument> 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<PubliekVerenigingDetailProjection>(CancellationToken.None);
return await session
.Query<PubliekVerenigingDetailDocument>()
.SingleAsync(x => x.VCode == scenario.VCode);
protected override async Task RefreshProjectionsAsync(IProjectionDaemon daemon)
{
await daemon.RebuildProjectionAsync(ProjectionNames.PubliekDetail, CancellationToken.None);
}

protected override async Task<PubliekVerenigingDetailDocument> GetResultAsync(
IDocumentSession session,
TScenario scenario)
=> await session
.Query<PubliekVerenigingDetailDocument>()
.SingleAsync(x => x.VCode == scenario.VCode);
}

public class PubliekDetailScenarioClassFixture<TScenario>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<TScenario>(ProjectionContext context)
: ScenarioFixture<TScenario, VerenigingZoekDocument, ProjectionContext>(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<VerenigingZoekDocument> GetResultAsync(
IDocumentSession _,
TScenario scenario)
{
var getResponse =
await Context.ElasticClient
await Context.PublicElasticClient
.GetAsync<VerenigingZoekDocument>(scenario.VCode);

return getResponse.Source;
Expand Down

0 comments on commit 3fb555b

Please sign in to comment.