Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,64 @@ public static IHealthChecksBuilder AddMongoDb(
tags,
timeout));
}

/// <summary>
/// Add a health check for MongoDb that list all databases from specified <paramref name="mongoClientFactory"/>.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="mongoClientFactory">A factory to build MongoClient to be used.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'mongodb' 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 AddMongoDb(
this IHealthChecksBuilder builder,
Func<IServiceProvider, IMongoClient> mongoClientFactory,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
return builder.Add(new HealthCheckRegistration(
name ?? NAME,
sp => new MongoDbHealthCheck(mongoClientFactory(sp)),
failureStatus,
tags,
timeout));
}

/// <summary>
/// Add a health check for MongoDb database that list all collections from specified database on <paramref name="mongoDatabaseName"/>.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="mongoClientFactory">A factory to build MongoClient to be used.</param>
/// <param name="mongoDatabaseName">The name of the database to check.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'mongodb' 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 AddMongoDb(
this IHealthChecksBuilder builder,
Func<IServiceProvider, IMongoClient> mongoClientFactory,
string mongoDatabaseName,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
return builder.Add(new HealthCheckRegistration(
name ?? NAME,
sp => new MongoDbHealthCheck(mongoClientFactory(sp), mongoDatabaseName),
failureStatus,
tags,
timeout));
}
}
8 changes: 7 additions & 1 deletion src/HealthChecks.MongoDb/MongoDbHealthCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace HealthChecks.MongoDb;
public class MongoDbHealthCheck : IHealthCheck
{
private static readonly BsonDocumentCommand<BsonDocument> _command = new(BsonDocument.Parse("{ping:1}"));
private static readonly ConcurrentDictionary<string, MongoClient> _mongoClient = new();
private static readonly ConcurrentDictionary<string, IMongoClient> _mongoClient = new();
private readonly MongoClientSettings _mongoClientSettings;
private readonly string? _specifiedDatabase;

Expand All @@ -21,6 +21,12 @@ public MongoDbHealthCheck(string connectionString, string? databaseName = defaul
}
}

public MongoDbHealthCheck(IMongoClient client, string? databaseName = default)
: this(client.Settings, databaseName)
{
_mongoClient[_mongoClientSettings.ToString()] = client;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove this cache, but this is outside of the scope of this PR. I've created #2148 to track it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @adamsitnik! Since it is not part of the scope of this PR can we close this one?

}

public MongoDbHealthCheck(MongoClientSettings clientSettings, string? databaseName = default)
{
_specifiedDatabase = databaseName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ public void add_health_check_when_properly_configured_mongoClientSettings()
check.ShouldBeOfType<MongoDbHealthCheck>();
}
[Fact]
public void add_health_check_when_properly_configured_mongoClientFactory()
{
var services = new ServiceCollection();

services
.AddSingleton(MongoClientSettings.FromUrl(MongoUrl.Create("mongodb://connectionstring")))
.AddSingleton(sp => new MongoClient(sp.GetRequiredService<MongoClientSettings>()))
.AddHealthChecks()
.AddMongoDb(sp => sp.GetRequiredService<MongoClient>());

using var serviceProvider = services.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>();

var registration = options.Value.Registrations.First();
var check = registration.Factory(serviceProvider);

registration.Name.ShouldBe("mongodb");
check.ShouldBeOfType<MongoDbHealthCheck>();
}
[Fact]
public void add_named_health_check_when_properly_configured_connectionString()
{
var services = new ServiceCollection();
Expand All @@ -56,7 +76,9 @@ public void add_named_health_check_when_properly_configured_connectionString()
public void add_named_health_check_when_properly_configured_mongoClientSettings()
{
var services = new ServiceCollection();
services.AddHealthChecks()

services
.AddHealthChecks()
.AddMongoDb(MongoClientSettings.FromUrl(MongoUrl.Create("mongodb://connectionstring")), name: "my-mongodb-group");

using var serviceProvider = services.BuildServiceProvider();
Expand All @@ -65,6 +87,26 @@ public void add_named_health_check_when_properly_configured_mongoClientSettings(
var registration = options.Value.Registrations.First();
var check = registration.Factory(serviceProvider);

registration.Name.ShouldBe("my-mongodb-group");
check.ShouldBeOfType<MongoDbHealthCheck>();
}
[Fact]
public void add_named_health_check_when_properly_configured_mongoClientFactory()
{
var services = new ServiceCollection();

services
.AddSingleton(MongoClientSettings.FromUrl(MongoUrl.Create("mongodb://connectionstring")))
.AddSingleton(sp => new MongoClient(sp.GetRequiredService<MongoClientSettings>()))
.AddHealthChecks()
.AddMongoDb(sp => sp.GetRequiredService<MongoClient>(), name: "my-mongodb-group");

using var serviceProvider = services.BuildServiceProvider();
var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>();

var registration = options.Value.Registrations.First();
var check = registration.Factory(serviceProvider);

registration.Name.ShouldBe("my-mongodb-group");
check.ShouldBeOfType<MongoDbHealthCheck>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace HealthChecks.MongoDb
{
public class MongoDbHealthCheck : Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck
{
public MongoDbHealthCheck(MongoDB.Driver.IMongoClient client, string? databaseName = null) { }
public MongoDbHealthCheck(MongoDB.Driver.MongoClientSettings clientSettings, string? databaseName = null) { }
public MongoDbHealthCheck(string connectionString, string? databaseName = null) { }
public System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult> CheckHealthAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext context, System.Threading.CancellationToken cancellationToken = default) { }
Expand All @@ -12,9 +13,11 @@ namespace Microsoft.Extensions.DependencyInjection
public static class MongoDbHealthCheckBuilderExtensions
{
public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddMongoDb(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, MongoDB.Driver.MongoClientSettings mongoClientSettings, 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 AddMongoDb(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func<System.IServiceProvider, MongoDB.Driver.IMongoClient> mongoClientFactory, 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 AddMongoDb(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func<System.IServiceProvider, string> mongodbConnectionStringFactory, 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 AddMongoDb(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string mongodbConnectionString, 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 AddMongoDb(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, MongoDB.Driver.MongoClientSettings mongoClientSettings, string mongoDatabaseName, 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 AddMongoDb(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func<System.IServiceProvider, MongoDB.Driver.IMongoClient> mongoClientFactory, string mongoDatabaseName, 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 AddMongoDb(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func<System.IServiceProvider, string> mongodbConnectionStringFactory, string mongoDatabaseName, 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 AddMongoDb(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string mongodbConnectionString, string mongoDatabaseName, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable<string>? tags = null, System.TimeSpan? timeout = default) { }
}
Expand Down