diff --git a/src/Akka.Persistence.Hosting.Tests/UnifiedApiSpecs.cs b/src/Akka.Persistence.Hosting.Tests/UnifiedApiSpecs.cs index e540483d..c64bd66a 100644 --- a/src/Akka.Persistence.Hosting.Tests/UnifiedApiSpecs.cs +++ b/src/Akka.Persistence.Hosting.Tests/UnifiedApiSpecs.cs @@ -285,6 +285,56 @@ public async Task WithJournalAndSnapshot_with_builders_should_configure_everythi } } +/// +/// Regression test for https://github.com/akkadotnet/Akka.Hosting/issues/666 +/// Ensures journal health checks are registered even without event adapters +/// +public sealed class JournalHealthCheckWithoutAdaptersSpec : Akka.Hosting.TestKit.TestKit +{ + public JournalHealthCheckWithoutAdaptersSpec(ITestOutputHelper output) : base(output: output) + { + } + + protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) + { + base.ConfigureServices(context, services); + services.AddHealthChecks(); + } + + protected override void ConfigureAkka(AkkaConfigurationBuilder builder, IServiceProvider provider) + { + var journalOptions = new UnifiedApiTestResources.TestJournalOptions { IsDefaultPlugin = true }; + + // Configure journal with health check but WITHOUT any event adapters + // This is the regression case from issue #666 + builder.WithJournal( + journalOptions, + journal => journal.WithHealthCheck()); + } + + [Fact] + public async Task Journal_health_check_should_be_registered_without_event_adapters() + { + // assert - journal plugin configured + var config = Sys.Settings.Config; + config.HasPath("akka.persistence.journal.test-journal") + .Should().BeTrue(); + + // assert - health check is registered even without event adapters + var healthCheckService = Host.Services.GetRequiredService(); + var result = await healthCheckService.CheckHealthAsync(); + + result.Status.Should().Be(HealthStatus.Healthy, + "journal health check should be healthy"); + + // Verify journal health check is present + var journalCheck = result.Entries.FirstOrDefault(e => e.Key.Contains("test-journal")); + journalCheck.Should().NotBeNull("journal health check should be registered even without event adapters"); + journalCheck.Value.Status.Should().Be(HealthStatus.Healthy, + "journal health check should return healthy status"); + } +} + /// /// Test null builder actions work correctly /// diff --git a/src/Akka.Persistence.Hosting/AkkaPersistenceHostingExtensions.cs b/src/Akka.Persistence.Hosting/AkkaPersistenceHostingExtensions.cs index 8713f653..8463b51f 100644 --- a/src/Akka.Persistence.Hosting/AkkaPersistenceHostingExtensions.cs +++ b/src/Akka.Persistence.Hosting/AkkaPersistenceHostingExtensions.cs @@ -112,6 +112,10 @@ private AkkaHealthCheckRegistration AddHealthCheck(string? name, HealthStatus un /// internal void Build() { + // add the health checks if specified - do this FIRST before any early returns + if(HealthCheckRegistration != null) + Builder.WithHealthCheck(HealthCheckRegistration); + // useless configuration - don't bother. if (Adapters.Count == 0 || Bindings.Count == 0) return; @@ -126,10 +130,6 @@ internal void Build() var finalHocon = ConfigurationFactory.ParseString(adapters.ToString()) .WithFallback(Persistence.DefaultConfig()); // add the default config as a fallback Builder.AddHocon(finalHocon, HoconAddMode.Prepend); - - // add the health checks if specified - if(HealthCheckRegistration != null) - Builder.WithHealthCheck(HealthCheckRegistration); } internal void AppendAdapters(StringBuilder sb)