Skip to content

Commit

Permalink
Add DbDataSource for Postgresql (#1832)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelmairegger authored Jun 30, 2023
1 parent 6ba871e commit ad6d0e4
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,43 @@ public static IHealthChecksBuilder AddNpgSql(
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
Guard.ThrowIfNull(connectionStringFactory);
return builder.AddNpgSql(sp => new NpgsqlDataSourceBuilder(connectionStringFactory(sp)).Build(), healthQuery, configure, name, failureStatus, tags, timeout);
}

/// <summary>
/// Add a health check for Postgres databases.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="dbDataSourceFactory">A factory to build the NpgsqlDataSource to use.</param>
/// <param name="healthQuery">The query to be used in check.</param>
/// <param name="configure">An optional action to allow additional Npgsql specific configuration.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'npgsql' will be used for the name.</param>
/// <param name="failureStatus">
/// The <see cref="HealthStatus"/> that should be reported when the health check fails. Optional. If <c>null</c> then
/// the default status of <see cref="HealthStatus.Unhealthy"/> will be reported.
/// </param>
/// <param name="tags">A list of tags that can be used to filter sets of health checks. Optional.</param>
/// <param name="timeout">An optional <see cref="TimeSpan"/> representing the timeout of the check.</param>
/// <returns>The specified <paramref name="builder"/>.</returns>
public static IHealthChecksBuilder AddNpgSql(
this IHealthChecksBuilder builder,
Func<IServiceProvider, NpgsqlDataSource> dbDataSourceFactory,
string healthQuery = HEALTH_QUERY,
Action<NpgsqlConnection>? configure = null,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
Guard.ThrowIfNull(dbDataSourceFactory);

return builder.Add(new HealthCheckRegistration(
name ?? NAME,
sp =>
{
var options = new NpgSqlHealthCheckOptions
{
ConnectionString = connectionStringFactory(sp),
DataSource = dbDataSourceFactory(sp),
CommandText = healthQuery,
Configure = configure,
};
Expand Down
5 changes: 2 additions & 3 deletions src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Npgsql;

namespace HealthChecks.NpgSql;

Expand All @@ -12,7 +11,7 @@ public class NpgSqlHealthCheck : IHealthCheck

public NpgSqlHealthCheck(NpgSqlHealthCheckOptions options)
{
Guard.ThrowIfNull(options.ConnectionString, true);
Guard.ThrowIfNull(options.DataSource);
Guard.ThrowIfNull(options.CommandText, true);
_options = options;
}
Expand All @@ -22,7 +21,7 @@ public async Task<HealthCheckResult> 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);
Expand Down
12 changes: 11 additions & 1 deletion src/HealthChecks.NpgSql/NpgSqlHealthCheckOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,18 @@ public class NpgSqlHealthCheckOptions
{
/// <summary>
/// The Postgres connection string to be used.
/// Use <see cref="DataSource"/> property for advanced configuration.
/// </summary>
public string ConnectionString { get; set; } = null!;
public string? ConnectionString
{
get => DataSource?.ConnectionString;
set => DataSource = value is not null ? NpgsqlDataSource.Create(value) : null;
}

/// <summary>
/// The Postgres data source to be used.
/// </summary>
public NpgsqlDataSource? DataSource { get; set; }

/// <summary>
/// The query to be executed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<IOptions<HealthCheckServiceOptions>>();
Expand All @@ -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<IOptions<HealthCheckServiceOptions>>();
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace HealthChecks.NpgSql
public NpgSqlHealthCheckOptions() { }
public string CommandText { get; set; }
public System.Action<Npgsql.NpgsqlConnection>? Configure { get; set; }
public string ConnectionString { get; set; }
public string? ConnectionString { get; set; }
public Npgsql.NpgsqlDataSource? DataSource { get; set; }
public System.Func<object?, Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>? HealthCheckResultBuilder { get; set; }
}
}
Expand All @@ -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<string>? tags = null, System.TimeSpan? timeout = default) { }
public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddNpgSql(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func<System.IServiceProvider, Npgsql.NpgsqlDataSource> dbDataSourceFactory, string healthQuery = "SELECT 1;", System.Action<Npgsql.NpgsqlConnection>? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable<string>? tags = null, System.TimeSpan? timeout = default) { }
public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddNpgSql(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func<System.IServiceProvider, string> connectionStringFactory, string healthQuery = "SELECT 1;", System.Action<Npgsql.NpgsqlConnection>? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable<string>? 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<Npgsql.NpgsqlConnection>? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable<string>? tags = null, System.TimeSpan? timeout = default) { }
}
Expand Down

0 comments on commit ad6d0e4

Please sign in to comment.