Skip to content

Commit

Permalink
Add package for SurrealDB
Browse files Browse the repository at this point in the history
  • Loading branch information
Odonno committed Oct 1, 2023
1 parent 9832115 commit 154b291
Show file tree
Hide file tree
Showing 11 changed files with 393 additions and 0 deletions.
14 changes: 14 additions & 0 deletions AspNetCore.Diagnostics.HealthChecks.sln
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Azure.Messagin
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.AzureServiceBus.Tests", "test\HealthChecks.AzureServiceBus.Tests\HealthChecks.AzureServiceBus.Tests.csproj", "{3B812989-2C4E-4FCE-B3A0-EF9C00A9B3A5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.SurrealDb", "src\HealthChecks.SurrealDb\HealthChecks.SurrealDb.csproj", "{97DAA09F-E0FA-4D5B-A72B-896161E570DA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.SurrealDb.Tests", "test\HealthChecks.SurrealDb.Tests\HealthChecks.SurrealDb.Tests.csproj", "{44BB97EE-88DB-4C9B-8195-2C6D889AE391}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -855,6 +859,14 @@ Global
{3B812989-2C4E-4FCE-B3A0-EF9C00A9B3A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B812989-2C4E-4FCE-B3A0-EF9C00A9B3A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B812989-2C4E-4FCE-B3A0-EF9C00A9B3A5}.Release|Any CPU.Build.0 = Release|Any CPU
{97DAA09F-E0FA-4D5B-A72B-896161E570DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97DAA09F-E0FA-4D5B-A72B-896161E570DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97DAA09F-E0FA-4D5B-A72B-896161E570DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97DAA09F-E0FA-4D5B-A72B-896161E570DA}.Release|Any CPU.Build.0 = Release|Any CPU
{44BB97EE-88DB-4C9B-8195-2C6D889AE391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44BB97EE-88DB-4C9B-8195-2C6D889AE391}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44BB97EE-88DB-4C9B-8195-2C6D889AE391}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44BB97EE-88DB-4C9B-8195-2C6D889AE391}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -996,6 +1008,8 @@ Global
{2C02BEDF-FFFA-4747-920A-A1ED6CFFC21A} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE}
{09160C0F-BB5E-4DF2-AF44-E859E8EDE6BD} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE}
{3B812989-2C4E-4FCE-B3A0-EF9C00A9B3A5} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE}
{97DAA09F-E0FA-4D5B-A72B-896161E570DA} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4}
{44BB97EE-88DB-4C9B-8195-2C6D889AE391} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2B8C62A1-11B6-469F-874C-A02443256568}
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ HealthChecks packages include health checks for:
| Solr | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Solr)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Solr) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Solr)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Solr) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/solr)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/solr)
| Sqlite | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Sqlite)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Sqlite) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Sqlite)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Sqlite) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/sqlite)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/sqlite)
| Sql Server | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.SqlServer)](https://www.nuget.org/packages/AspNetCore.HealthChecks.SqlServer) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.SqlServer)](https://www.nuget.org/packages/AspNetCore.HealthChecks.SqlServer) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/sqlserver)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/sqlserver)
| SurrealDb | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.SurrealDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.SurrealDb) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.SurrealDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.SurrealDb) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/surrealdb)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/surrealdb)
| System | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.System)](https://www.nuget.org/packages/AspNetCore.HealthChecks.System) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.System)](https://www.nuget.org/packages/AspNetCore.HealthChecks.System) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/system)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/system) | Disk Storage, Folder, Private Memory, Virtual Memory, Process, Windows Service |
| Uris | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Uris)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Uris) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Uris)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Uris) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/uris)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/uris) | Single uri and uri groups |

Expand Down Expand Up @@ -160,6 +161,7 @@ Install-Package AspNetCore.HealthChecks.SignalR
Install-Package AspNetCore.HealthChecks.Solr
Install-Package AspNetCore.HealthChecks.SqLite
Install-Package AspNetCore.HealthChecks.SqlServer
Install-Package AspNetCore.HealthChecks.SurrealDb
Install-Package AspNetCore.HealthChecks.System
Install-Package AspNetCore.HealthChecks.Uris
```
Expand Down
1 change: 1 addition & 0 deletions build/versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<HealthCheckSolr>7.0.0</HealthCheckSolr>
<HealthCheckSqlite>7.0.0</HealthCheckSqlite>
<HealthCheckSqlServer>7.0.0</HealthCheckSqlServer>
<HealthCheckSurrealDb>7.0.0</HealthCheckSurrealDb>
<HealthChecksUIK8sOperator>7.0.0</HealthChecksUIK8sOperator>
<HealthChecksUIPostgreSQLStorage>7.0.0</HealthChecksUIPostgreSQLStorage>
<HealthCheckSystem>7.0.0</HealthCheckSystem>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using HealthChecks.SurrealDb;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using SurrealDb.Net;

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// Extension methods to configure <see cref="SurrealDbHealthCheck"/>.
/// </summary>
public static class SurrealDbHealthCheckBuilderExtensions
{
private const string NAME = "surrealdb";

/// <summary>
/// Add a health check for SurrealDB.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="connectionString">The SurrealDB connection string to be used.</param>
/// <param name="configure">An optional action to allow additional SQL Server specific configuration.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'surrealdb' 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 AddSurreal(
this IHealthChecksBuilder builder,
string connectionString,
Action<ISurrealDbClient>? configure = null,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
return builder.AddSurreal(_ => connectionString, configure, name, failureStatus, tags, timeout);
}

/// <summary>
/// Add a health check for SurrealDB.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="connectionStringFactory">A factory to build the SurrealDB connection string to use.</param>
/// <param name="configure">An optional action to allow additional SQL Server specific configuration.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'surrealdb' 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 AddSurreal(
this IHealthChecksBuilder builder,
Func<IServiceProvider, string> connectionStringFactory,
Action<ISurrealDbClient>? configure = null,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
Guard.ThrowIfNull(connectionStringFactory);

return builder.Add(new HealthCheckRegistration(
name ?? NAME,
sp =>
{
var options = new SurrealDbHealthCheckOptions
{
ConnectionString = connectionStringFactory(sp),
Configure = configure,
};
return new SurrealDbHealthCheck(options);
},
failureStatus,
tags,
timeout));
}

/// <summary>
/// Add a health check for SurrealDB.
/// </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 'surrealdb' 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 AddSurreal(
this IHealthChecksBuilder builder,
SurrealDbHealthCheckOptions 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 SurrealDbHealthCheck(options),
failureStatus,
tags,
timeout));
}
}
15 changes: 15 additions & 0 deletions src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<PackageTags>$(PackageTags);SurrealDb</PackageTags>
<Description>HealthChecks.SurrealDb is the health check package for SurrealDB.</Description>
<VersionPrefix>$(HealthCheckSurrealDb)</VersionPrefix>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.9" />
<PackageReference Include="SurrealDb.Net" Version="0.1.3" />
</ItemGroup>

</Project>
45 changes: 45 additions & 0 deletions src/HealthChecks.SurrealDb/SurrealDbHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using SurrealDb.Net;

namespace HealthChecks.SurrealDb;

/// <summary>
/// A health check for SurrealDb services.
/// </summary>
public class SurrealDbHealthCheck : IHealthCheck
{
private readonly SurrealDbHealthCheckOptions _options;

public SurrealDbHealthCheck(SurrealDbHealthCheckOptions options)
{
Guard.ThrowIfNull(options.ConnectionString, true);
_options = options;
}

/// <inheritdoc />
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
var clientOptions = new SurrealDbOptionsBuilder()
.FromConnectionString(_options.ConnectionString)
.Build();

using var client = new SurrealDbClient(clientOptions);

_options.Configure?.Invoke(client);
await client.Connect(cancellationToken).ConfigureAwait(false);

bool result = await client.Health(cancellationToken).ConfigureAwait(false);

return _options.HealthCheckResultBuilder == null
? HealthCheckResult.Healthy()
: _options.HealthCheckResultBuilder(result);
}
catch (Exception ex)
{
return new HealthCheckResult(context.Registration.FailureStatus, exception: ex);
}
}
}
25 changes: 25 additions & 0 deletions src/HealthChecks.SurrealDb/SurrealDbHealthCheckOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;
using SurrealDb.Net;

namespace HealthChecks.SurrealDb;

/// <summary>
/// Options for <see cref="SurrealDbHealthCheck"/>.
/// </summary>
public class SurrealDbHealthCheckOptions
{
/// <summary>
/// The Sql Server connection string to be used.
/// </summary>
public string ConnectionString { get; set; } = null!;

/// <summary>
/// An optional action executed before the connection is opened in the health check.
/// </summary>
public Action<ISurrealDbClient>? Configure { get; set; }

/// <summary>
/// An optional delegate to build health check result.
/// </summary>
public Func<object?, HealthCheckResult>? HealthCheckResultBuilder { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using SurrealDb.Net;

namespace HealthChecks.SurrealDb.Tests.DependencyInjection;

public class surrealdb_registration_should
{
[Fact]
public void add_health_check_when_properly_configured()
{
var services = new ServiceCollection()
.AddHealthChecks()
.AddSurreal("connectionstring")
.Services;

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("surrealdb");
check.ShouldBeOfType<SurrealDbHealthCheck>();
}

[Fact]
public void invoke_beforeOpen_when_defined()
{
var services = new ServiceCollection();
bool invoked = false;
const string connectionstring = "Server=http://localhost:8000;Namespace=test;Database=test;Username=root;Password=root";
void beforeOpen(ISurrealDbClient client)
{
invoked = true;
client.Uri.AbsoluteUri.ShouldBe("http://localhost:8000");
}
services.AddHealthChecks()
.AddSurreal(connectionstring, configure: beforeOpen);

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

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

Record.ExceptionAsync(() => check.CheckHealthAsync(new HealthCheckContext())).GetAwaiter().GetResult();
invoked.ShouldBeTrue();
}

[Fact]
public void add_named_health_check_when_properly_configured()
{
var services = new ServiceCollection()
.AddHealthChecks()
.AddSurreal("connectionstring", name: "my-surrealdb-1")
.Services;

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-surrealdb-1");
check.ShouldBeOfType<SurrealDbHealthCheck>();
}

[Fact]
public void add_health_check_with_connection_string_factory_when_properly_configured()
{
var services = new ServiceCollection();
bool factoryCalled = false;
services.AddHealthChecks()
.AddSurreal(_ =>
{
factoryCalled = true;
return "connectionstring";
});

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("surrealdb");
check.ShouldBeOfType<SurrealDbHealthCheck>();
factoryCalled.ShouldBeTrue();
}
}
Loading

0 comments on commit 154b291

Please sign in to comment.