From 60b0b479bd36cd3a8c3a56ea095e6b6f177269d1 Mon Sep 17 00:00:00 2001 From: Michael Mairegger Date: Wed, 31 May 2023 10:38:24 +0200 Subject: [PATCH 01/10] Replace ConnectionString property with DbDataSource to support https://www.npgsql.org/efcore/release-notes/7.0.html#support-for-dbdatasource closes #1813 --- .../NpgSqlHealthCheckBuilderExtensions.cs | 19 +++++++++++++++++-- src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs | 4 ++-- .../NpgSqlHealthCheckOptions.cs | 5 +++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs index 498e53dee5..3ae2f66c31 100644 --- a/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs @@ -1,3 +1,5 @@ +using System.Data.Common; +using System.Runtime.CompilerServices; using HealthChecks.NpgSql; using Microsoft.Extensions.Diagnostics.HealthChecks; using Npgsql; @@ -65,7 +67,20 @@ public static IHealthChecksBuilder AddNpgSql( IEnumerable? tags = default, TimeSpan? timeout = default) { - Guard.ThrowIfNull(connectionStringFactory); + return builder.AddNpgSql(e => new NpgsqlDataSourceBuilder(connectionStringFactory(e)).Build(), healthQuery, configure, name, failureStatus, tags, timeout); + } + + public static IHealthChecksBuilder AddNpgSql( + this IHealthChecksBuilder builder, + Func dbDataSourceFactory, + string healthQuery = HEALTH_QUERY, + Action? configure = null, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(dbDataSourceFactory); return builder.Add(new HealthCheckRegistration( name ?? NAME, @@ -73,7 +88,7 @@ public static IHealthChecksBuilder AddNpgSql( { var options = new NpgSqlHealthCheckOptions { - ConnectionString = connectionStringFactory(sp), + DataSource = dbDataSourceFactory(sp), CommandText = healthQuery, Configure = configure, }; diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs index e33cc96977..65475bbfc8 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs @@ -12,7 +12,7 @@ public class NpgSqlHealthCheck : IHealthCheck public NpgSqlHealthCheck(NpgSqlHealthCheckOptions options) { - Guard.ThrowIfNull(options.ConnectionString, true); + Guard.ThrowIfNull(options.DataSource, true); Guard.ThrowIfNull(options.CommandText, true); _options = options; } @@ -22,7 +22,7 @@ public async Task CheckHealthAsync(HealthCheckContext context { try { - using var connection = new NpgsqlConnection(_options.ConnectionString); + await using var connection = _options.DataSource.CreateConnection(); _options.Configure?.Invoke(connection); await connection.OpenAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs index 910d8053f7..b156d8f1a8 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs @@ -1,3 +1,4 @@ +using System.Data.Common; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Npgsql; @@ -10,9 +11,9 @@ namespace HealthChecks.NpgSql; public class NpgSqlHealthCheckOptions { /// - /// The Postgres connection string to be used. + /// The Postgres data source to be used. /// - public string ConnectionString { get; set; } = null!; + public NpgsqlDataSource DataSource { get; set; } = null!; /// /// The query to be executed. From 5ce2532b9f7f78712fa238bc920394fca1db9cbc Mon Sep 17 00:00:00 2001 From: Michael Mairegger Date: Wed, 31 May 2023 10:45:47 +0200 Subject: [PATCH 02/10] dotnet format --- .../DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs | 4 +--- src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs | 1 - src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs index 3ae2f66c31..0c2d7e523f 100644 --- a/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs @@ -1,5 +1,3 @@ -using System.Data.Common; -using System.Runtime.CompilerServices; using HealthChecks.NpgSql; using Microsoft.Extensions.Diagnostics.HealthChecks; using Npgsql; @@ -69,7 +67,7 @@ public static IHealthChecksBuilder AddNpgSql( { return builder.AddNpgSql(e => new NpgsqlDataSourceBuilder(connectionStringFactory(e)).Build(), healthQuery, configure, name, failureStatus, tags, timeout); } - + public static IHealthChecksBuilder AddNpgSql( this IHealthChecksBuilder builder, Func dbDataSourceFactory, diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs index 65475bbfc8..ea8192d059 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Diagnostics.HealthChecks; -using Npgsql; namespace HealthChecks.NpgSql; diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs index b156d8f1a8..fe99723719 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs @@ -1,4 +1,3 @@ -using System.Data.Common; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Npgsql; From 1bac7490c1f05c528d043fb0482d618cde8768e3 Mon Sep 17 00:00:00 2001 From: Michael Mairegger Date: Wed, 31 May 2023 11:00:33 +0200 Subject: [PATCH 03/10] Re-add ConnectionString to prevent breaking changes. Setting ConnectionString will set the DataSource --- src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs | 4 ++-- src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs index ea8192d059..37a72c681e 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs @@ -11,7 +11,7 @@ public class NpgSqlHealthCheck : IHealthCheck public NpgSqlHealthCheck(NpgSqlHealthCheckOptions options) { - Guard.ThrowIfNull(options.DataSource, true); + Guard.ThrowIfNull(options.DataSource); Guard.ThrowIfNull(options.CommandText, true); _options = options; } @@ -21,7 +21,7 @@ public async Task CheckHealthAsync(HealthCheckContext context { try { - await using var connection = _options.DataSource.CreateConnection(); + await using var connection = _options.DataSource!.CreateConnection(); _options.Configure?.Invoke(connection); await connection.OpenAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs index fe99723719..a6a44523c9 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs @@ -10,9 +10,19 @@ namespace HealthChecks.NpgSql; public class NpgSqlHealthCheckOptions { /// + /// The Postgres connection string to be used. /// The Postgres data source to be used. /// - public NpgsqlDataSource DataSource { get; set; } = null!; + public string? ConnectionString + { + get => DataSource?.ConnectionString; + set => DataSource = NpgsqlDataSource.Create(value); + } + + /// + /// The Postgres data source to be used. + /// + public NpgsqlDataSource? DataSource { get; set; } /// /// The query to be executed. From 989afd717d88536b9d8ce88f30ff9d129160a102 Mon Sep 17 00:00:00 2001 From: Michael Mairegger Date: Wed, 31 May 2023 11:07:08 +0200 Subject: [PATCH 04/10] [Fix] Some null handling issues --- src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs index a6a44523c9..f813181542 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs @@ -16,7 +16,7 @@ public class NpgSqlHealthCheckOptions public string? ConnectionString { get => DataSource?.ConnectionString; - set => DataSource = NpgsqlDataSource.Create(value); + set => DataSource = value is not null ? NpgsqlDataSource.Create(value) : null; } /// From 4517dd8749af1556c6c800219d6f8e40f62717f8 Mon Sep 17 00:00:00 2001 From: Michael Mairegger Date: Wed, 31 May 2023 11:14:34 +0200 Subject: [PATCH 05/10] [Fix] ApiApprovalTests --- .../HealthChecks.NpgSql.approved.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/HealthChecks.Npgsql.Tests/HealthChecks.NpgSql.approved.txt b/test/HealthChecks.Npgsql.Tests/HealthChecks.NpgSql.approved.txt index 3724c042be..d84990c4dd 100644 --- a/test/HealthChecks.Npgsql.Tests/HealthChecks.NpgSql.approved.txt +++ b/test/HealthChecks.Npgsql.Tests/HealthChecks.NpgSql.approved.txt @@ -10,7 +10,8 @@ namespace HealthChecks.NpgSql public NpgSqlHealthCheckOptions() { } public string CommandText { get; set; } public System.Action? Configure { get; set; } - public string ConnectionString { get; set; } + public string? ConnectionString { get; set; } + public Npgsql.NpgsqlDataSource? DataSource { get; set; } public System.Func? HealthCheckResultBuilder { get; set; } } } @@ -19,6 +20,7 @@ namespace Microsoft.Extensions.DependencyInjection public static class NpgSqlHealthCheckBuilderExtensions { public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddNpgSql(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, HealthChecks.NpgSql.NpgSqlHealthCheckOptions options, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } + public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddNpgSql(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func dbDataSourceFactory, string healthQuery = "SELECT 1;", System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddNpgSql(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func connectionStringFactory, string healthQuery = "SELECT 1;", System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddNpgSql(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string connectionString, string healthQuery = "SELECT 1;", System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } } From 0310f67ac61779b6e253a4d0a9391d012a7ff505 Mon Sep 17 00:00:00 2001 From: Michael Mairegger Date: Wed, 31 May 2023 11:25:03 +0200 Subject: [PATCH 06/10] [Fix] Unit test. Previous connection string provided by the tests was not valid --- .../DependencyInjection/RegistrationTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/HealthChecks.Npgsql.Tests/DependencyInjection/RegistrationTests.cs b/test/HealthChecks.Npgsql.Tests/DependencyInjection/RegistrationTests.cs index e45c86b00e..b897f56df3 100644 --- a/test/HealthChecks.Npgsql.Tests/DependencyInjection/RegistrationTests.cs +++ b/test/HealthChecks.Npgsql.Tests/DependencyInjection/RegistrationTests.cs @@ -9,7 +9,7 @@ public void add_health_check_when_properly_configured() { var services = new ServiceCollection(); services.AddHealthChecks() - .AddNpgSql("connectionstring"); + .AddNpgSql("Server=localhost"); using var serviceProvider = services.BuildServiceProvider(); var options = serviceProvider.GetRequiredService>(); @@ -27,7 +27,7 @@ public void add_named_health_check_when_properly_configured() { var services = new ServiceCollection(); services.AddHealthChecks() - .AddNpgSql("connectionstring", name: "my-npg-1"); + .AddNpgSql("Server=localhost", name: "my-npg-1"); using var serviceProvider = services.BuildServiceProvider(); var options = serviceProvider.GetRequiredService>(); @@ -48,7 +48,7 @@ public void add_health_check_with_connection_string_factory_when_properly_config .AddNpgSql(_ => { factoryCalled = true; - return "connectionstring"; + return "Server=localhost"; }, name: "my-npg-1"); using var serviceProvider = services.BuildServiceProvider(); From e5f3c9ea0453e5270c798073cfddfe7de47317e1 Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Fri, 30 Jun 2023 13:25:11 +0300 Subject: [PATCH 07/10] Update src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs --- src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs index f813181542..e898afdb2c 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs @@ -11,7 +11,6 @@ public class NpgSqlHealthCheckOptions { /// /// The Postgres connection string to be used. - /// The Postgres data source to be used. /// public string? ConnectionString { From de5d58cbb40fb5f3504565f9ea06e0c845c47d1e Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Fri, 30 Jun 2023 13:28:06 +0300 Subject: [PATCH 08/10] Update src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs --- .../DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs index 0c2d7e523f..6ce3d7390f 100644 --- a/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs @@ -65,7 +65,7 @@ public static IHealthChecksBuilder AddNpgSql( IEnumerable? tags = default, TimeSpan? timeout = default) { - return builder.AddNpgSql(e => new NpgsqlDataSourceBuilder(connectionStringFactory(e)).Build(), healthQuery, configure, name, failureStatus, tags, timeout); + return builder.AddNpgSql(sp => new NpgsqlDataSourceBuilder(connectionStringFactory(sp)).Build(), healthQuery, configure, name, failureStatus, tags, timeout); } public static IHealthChecksBuilder AddNpgSql( From 75642cd4dad75b0c38d8b1ed4f24464b3754c28c Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Fri, 30 Jun 2023 13:30:00 +0300 Subject: [PATCH 09/10] Update src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs --- .../NpgSqlHealthCheckBuilderExtensions.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs index 6ce3d7390f..fbcecaf63d 100644 --- a/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs @@ -68,6 +68,21 @@ public static IHealthChecksBuilder AddNpgSql( return builder.AddNpgSql(sp => new NpgsqlDataSourceBuilder(connectionStringFactory(sp)).Build(), healthQuery, configure, name, failureStatus, tags, timeout); } + /// + /// Add a health check for Postgres databases. + /// + /// The . + /// A factory to build the NpgsqlDataSource to use. + /// The query to be used in check. + /// An optional action to allow additional Npgsql specific configuration. + /// The health check name. Optional. If null the type name 'npgsql' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . public static IHealthChecksBuilder AddNpgSql( this IHealthChecksBuilder builder, Func dbDataSourceFactory, From c236306bbf3a7fb51a0e3fe2f184daecd5ed7f7f Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Fri, 30 Jun 2023 13:38:53 +0300 Subject: [PATCH 10/10] Update src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs --- src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs index e898afdb2c..0138c30ea8 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs @@ -11,6 +11,7 @@ public class NpgSqlHealthCheckOptions { /// /// The Postgres connection string to be used. + /// Use property for advanced configuration. /// public string? ConnectionString {