Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions src/HealthChecks.ClickHouse/ClickHouseHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using ClickHouse.Client.ADO;
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace HealthChecks.ClickHouse;
Expand All @@ -7,29 +8,30 @@ namespace HealthChecks.ClickHouse;
/// </summary>
public class ClickHouseHealthCheck : IHealthCheck
{
private readonly ClickHouseHealthCheckOptions _options;
internal const string HEALTH_QUERY = "SELECT 1;";

public ClickHouseHealthCheck(ClickHouseHealthCheckOptions options)
private readonly ClickHouseConnection _connection;
private readonly string _command;

public ClickHouseHealthCheck(ClickHouseConnection connection, string command)
{
Guard.ThrowIfNull(options.CommandText, true);
_options = options;
_connection = connection;
_command = command ?? HEALTH_QUERY;
}

/// <inheritdoc />
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
await using var connection = _options.ConnectionFactory();
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
await _connection.OpenAsync(cancellationToken).ConfigureAwait(false);

using var command = _connection.CreateCommand();
command.CommandText = _command;

using var command = connection.CreateCommand();
command.CommandText = _options.CommandText;
var result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);
await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);

return _options.HealthCheckResultBuilder == null
? HealthCheckResult.Healthy()
: _options.HealthCheckResultBuilder(result);
return HealthCheckResult.Healthy();
}
catch (Exception ex)
{
Expand Down
35 changes: 0 additions & 35 deletions src/HealthChecks.ClickHouse/ClickHouseHealthCheckOptions.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Microsoft.Extensions.DependencyInjection;
public static class ClickHouseHealthCheckBuilderExtensions
{
private const string NAME = "ClickHouse";
internal const string HEALTH_QUERY = "SELECT 1;";

/// <summary>
/// Add a health check for ClickHouse databases.
Expand All @@ -29,54 +28,18 @@ public static class ClickHouseHealthCheckBuilderExtensions
public static IHealthChecksBuilder AddClickHouse(
this IHealthChecksBuilder builder,
Func<IServiceProvider, ClickHouseConnection> connectionFactory,
string healthQuery = HEALTH_QUERY,
string healthQuery = ClickHouseHealthCheck.HEALTH_QUERY,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
if (connectionFactory == null)
{
throw new ArgumentNullException(nameof(connectionFactory));
}
Guard.ThrowIfNull(connectionFactory);
Guard.ThrowIfNull(healthQuery);

return builder.Add(new HealthCheckRegistration(
name ?? NAME,
sp => new ClickHouseHealthCheck(new ClickHouseHealthCheckOptions(() => Guard.ThrowIfNull(connectionFactory.Invoke(sp), paramName: nameof(connectionFactory)))
{
CommandText = healthQuery
}),
failureStatus,
tags,
timeout));
}

/// <summary>
/// Add a health check for ClickHouse databases.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="options">Options for health check.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'ClickHouse' 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 AddClickHouse(
this IHealthChecksBuilder builder,
ClickHouseHealthCheckOptions options,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
Guard.ThrowIfNull(options);

return builder.Add(new HealthCheckRegistration(
name ?? NAME,
_ => new ClickHouseHealthCheck(options),
sp => new ClickHouseHealthCheck(connectionFactory(sp), healthQuery),
failureStatus,
tags,
timeout));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public void add_health_check_when_properly_configured()
var registration = options.Value.Registrations.First();
var check = registration.Factory(serviceProvider);

registration.Name.ShouldBe("clickhouse");
registration.Name.ShouldBe("ClickHouse");
check.ShouldBeOfType<ClickHouseHealthCheck>();
}

Expand Down Expand Up @@ -63,7 +63,7 @@ public void add_health_check_with_connection_string_factory_when_properly_config
}

[Fact]
public void factory_is_called_only_once()
public void factory_is_called_everytime_healthcheck_is_created()
{
ServiceCollection services = new();
int factoryCalls = 0;
Expand All @@ -85,6 +85,7 @@ public void factory_is_called_only_once()
_ = registration.Factory(serviceProvider);
}

factoryCalls.ShouldBe(1);
// ClickHouseConnection is not thread safe, so we assume that that we get a new instance every time
factoryCalls.ShouldBe(10);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,14 @@ namespace HealthChecks.ClickHouse
{
public class ClickHouseHealthCheck : Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck
{
public ClickHouseHealthCheck(HealthChecks.ClickHouse.ClickHouseHealthCheckOptions options) { }
public ClickHouseHealthCheck(ClickHouse.Client.ADO.ClickHouseConnection connection, string command) { }
public System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult> CheckHealthAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext context, System.Threading.CancellationToken cancellationToken = default) { }
}
public class ClickHouseHealthCheckOptions
{
public ClickHouseHealthCheckOptions(string connectionString) { }
public string CommandText { get; set; }
public System.Action<ClickHouse.ClickHouseConnection>? Configure { get; set; }
public string? ConnectionString { get; }
public System.Func<object?, Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>? HealthCheckResultBuilder { get; set; }
}
}
namespace Microsoft.Extensions.DependencyInjection
{
public static class ClickHouseHealthCheckBuilderExtensions
{
public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddClickHouse(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, HealthChecks.ClickHouse.ClickHouseHealthCheckOptions 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 AddClickHouse(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func<System.IServiceProvider, string> connectionStringFactory, string healthQuery = "SELECT 1;", System.Action<ClickHouse.ClickHouseConnection>? 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 AddClickHouse(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string connectionString, string healthQuery = "SELECT 1;", System.Action<ClickHouse.ClickHouseConnection>? 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 AddClickHouse(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func<System.IServiceProvider, ClickHouse.Client.ADO.ClickHouseConnection> connectionFactory, string healthQuery = "SELECT 1;", string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable<string>? tags = null, System.TimeSpan? timeout = default) { }
}
}
Loading