Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add package for SurrealDB #2047

Merged
merged 13 commits into from
Dec 12, 2024
Merged
2 changes: 2 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ flags:
carryforward: true
SqlServer:
carryforward: true
SurrealDb:
carryforward: true
System:
carryforward: true
UI:
Expand Down
3 changes: 3 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ sqlserver:
- changed-files:
- any-glob-to-any-file: [src/HealthChecks.SqlServer/**/*]

surrealdb:
- src/HealthChecks.SurrealDb/**/*

system:
- changed-files:
- any-glob-to-any-file: [src/HealthChecks.System/**/*]
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/healthchecks_surrealdb_cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: HealthChecks SurrealDB CD

on:
push:
tags:
- release-surrealdb-*
- release-all-*

jobs:
build:
uses: ./.github/workflows/reusable_cd_workflow.yml
secrets: inherit
with:
BUILD_CONFIG: Release
PROJECT_PATH: ./src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj
PACKAGE_NAME: AspNetCore.HealthChecks.SurrealDb
17 changes: 17 additions & 0 deletions .github/workflows/healthchecks_surrealdb_cd_preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: HealthChecks SurrealDB Preview CD

on:
push:
tags:
- preview-surrealdb-*
- preview-all-*

jobs:
build:
uses: ./.github/workflows/reusable_cd_preview_workflow.yml
secrets: inherit
with:
BUILD_CONFIG: Release
VERSION_SUFFIX_PREFIX: rc1
PROJECT_PATH: ./src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj
PACKAGE_NAME: AspNetCore.HealthChecks.SurrealDb
76 changes: 76 additions & 0 deletions .github/workflows/healthchecks_surrealdb_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: HealthChecks SurrealDB CI

on:
workflow_dispatch:
push:
branches: [master]
paths:
- src/HealthChecks.SurrealDb/**
- test/HealthChecks.SurrealDb.Tests/**
- test/_SHARED/**
- .github/workflows/healthchecks_surrealdb_ci.yml
- Directory.Build.props
- Directory.Build.targets
- Directory.Packages.props
tags-ignore:
- release-*
- preview-*

pull_request:
branches: [master]
paths:
- src/HealthChecks.SurrealDb/**
- test/HealthChecks.SurrealDb.Tests/**
- test/_SHARED/**
- .github/workflows/healthchecks_surrealdb_ci.yml
- Directory.Build.props
- Directory.Build.targets
- Directory.Packages.props

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Start SurrealDB
uses: surrealdb/setup-surreal@v2
with:
surrealdb_version: latest
surrealdb_port: 8000
surrealdb_username: root
surrealdb_password: root
surrealdb_auth: true
surrealdb_strict:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
8.0.x
9.0.x
- name: Restore
run: |
dotnet restore ./src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj &&
dotnet restore ./test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.Tests.csproj
- name: Check formatting
run: |
dotnet format --no-restore --verify-no-changes --severity warn ./src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) &&
dotnet format --no-restore --verify-no-changes --severity warn ./test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.Tests.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1)
- name: Build
run: |
dotnet build --no-restore ./src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj &&
dotnet build --no-restore ./test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.Tests.csproj
- name: Test
run: >
dotnet test
./test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.Tests.csproj
--no-restore
--no-build
--collect "XPlat Code Coverage"
--results-directory .coverage
--
DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
flags: SurrealDb
directory: .coverage
14 changes: 14 additions & 0 deletions AspNetCore.Diagnostics.HealthChecks.sln
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.Rabbitmq.v6",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.RabbitMQ.v6.Tests", "test\HealthChecks.RabbitMQ.v6.Tests\HealthChecks.RabbitMQ.v6.Tests.csproj", "{2787F63E-ABEA-9461-CDF3-97FE7C5C3DCC}"
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
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.ClickHouse", "src\HealthChecks.ClickHouse\HealthChecks.ClickHouse.csproj", "{96E2B0A3-02BD-456B-8888-4D96DABA99EB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.ClickHouse.Tests", "test\HealthChecks.ClickHouse.Tests\HealthChecks.ClickHouse.Tests.csproj", "{2FB5CB9F-F870-48DE-BD1D-306AE86A67CA}"
Expand Down Expand Up @@ -885,6 +889,14 @@ Global
{2787F63E-ABEA-9461-CDF3-97FE7C5C3DCC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2787F63E-ABEA-9461-CDF3-97FE7C5C3DCC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2787F63E-ABEA-9461-CDF3-97FE7C5C3DCC}.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
{96E2B0A3-02BD-456B-8888-4D96DABA99EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96E2B0A3-02BD-456B-8888-4D96DABA99EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96E2B0A3-02BD-456B-8888-4D96DABA99EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -1038,6 +1050,8 @@ Global
{D49CF52C-9D21-4D98-8A15-A2B259E9C003} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE}
{C76D7349-A3D2-7277-93C6-EE92E8E447A5} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4}
{2787F63E-ABEA-9461-CDF3-97FE7C5C3DCC} = {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}
{96E2B0A3-02BD-456B-8888-4D96DABA99EB} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4}
{2FB5CB9F-F870-48DE-BD1D-306AE86A67CA} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE}
EndGlobalSection
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
<PackageVersion Include="SolrNet.Core" Version="1.1.1" />
<PackageVersion Include="SSH.NET" Version="2023.0.0" />
<PackageVersion Include="StackExchange.Redis" Version="2.7.4" />
<PackageVersion Include="SurrealDb.Net" Version="0.6.0" />
<PackageVersion Include="System.Buffers" Version="4.5.1" />
<PackageVersion Include="System.Net.Http.Json" Version="8.0.1" />
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="8.0.0" />
Expand Down
1 change: 1 addition & 0 deletions build/versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
<HealthCheckSignalR>9.0.0</HealthCheckSignalR>
<HealthCheckSolr>9.0.0</HealthCheckSolr>
<HealthCheckSqlite>9.0.0</HealthCheckSqlite>
<HealthCheckSurrealDb>9.0.0</HealthCheckSurrealDb>
<HealthCheckSqlServer>9.0.0</HealthCheckSqlServer>
<HealthChecksUIK8sOperator>9.0.0</HealthChecksUIK8sOperator>
<HealthChecksUIPostgreSQLStorage>9.0.0</HealthChecksUIPostgreSQLStorage>
Expand Down
1 change: 1 addition & 0 deletions src/HealthChecks.ClickHouse/HealthChecks.ClickHouse.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<PackageTags>$(PackageTags);Beat;ClickHouse</PackageTags>
<Description>HealthChecks.ClickHouse is a health check for ClickHouse.</Description>
<VersionPrefix>$(HealthCheckClickHouse)</VersionPrefix>
<SignAssembly>false</SignAssembly>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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="factory">
/// An optional factory to obtain <see cref="ISurrealDbClient" /> instance.
/// When not provided, <see cref="ISurrealDbClient" /> is simply resolved from <see cref="IServiceProvider"/>.
/// </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, ISurrealDbClient>? factory = null,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
return builder.Add(new HealthCheckRegistration(
name ?? NAME,
sp => Factory(sp, factory),
failureStatus,
tags,
timeout));

static SurrealDbHealthCheck Factory(IServiceProvider sp, Func<IServiceProvider, ISurrealDbClient>? factory)
{
// The user might have registered a factory for SurrealDbClient type, but not for the abstraction (ISurrealDbClient).
// That is why we try to resolve ISurrealDbClient first.
ISurrealDbClient client = factory?.Invoke(sp) ?? sp.GetService<ISurrealDbClient>() ?? sp.GetRequiredService<SurrealDbClient>();
return new(client);
}
}
}
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>
<TargetFrameworks>netstandard2.1;$(DefaultNetCoreApp)</TargetFrameworks>
<PackageTags>$(PackageTags);SurrealDb</PackageTags>
<Description>HealthChecks.SurrealDb is the health check package for SurrealDB.</Description>
<VersionPrefix>$(HealthCheckSurrealDb)</VersionPrefix>
<SignAssembly>false</SignAssembly>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="SurrealDb.Net" />
</ItemGroup>

</Project>
15 changes: 15 additions & 0 deletions src/HealthChecks.SurrealDb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## SurrealDB Health Check

This health check verifies the ability to communicate with [SurrealDb](https://surrealdb.com). It uses the provided [ISurrealDbClient](https://surrealdb.com/docs/sdk/dotnet).

### Defaults

By default, the `ISurrealDbClient` instance is resolved from service provider.

```csharp
void Configure(IHealthChecksBuilder builder)
{
builder.Services.AddSurreal("Server=http://localhost:8000;Namespace=test;Database=test");
builder.AddHealthChecks().AddSurreal();
}
```
34 changes: 34 additions & 0 deletions src/HealthChecks.SurrealDb/SurrealDbHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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 ISurrealDbClient _client;

public SurrealDbHealthCheck(ISurrealDbClient client)
{
_client = Guard.ThrowIfNull(client);
}

/// <inheritdoc />
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
await _client.Connect(cancellationToken).ConfigureAwait(false);

return await _client.Health(cancellationToken).ConfigureAwait(false)
? HealthCheckResult.Healthy()
: HealthCheckResult.Unhealthy();
}
catch (Exception ex)
{
return new HealthCheckResult(context.Registration.FailureStatus, exception: ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using SurrealDb.Net;

namespace HealthChecks.SurrealDb.Tests.DependencyInjection;

public class surrealdb_registration_should
{
private const string ConnectionString = "Server=http://localhost:8000;Namespace=test;Database=test;Username=root;Password=root";

[Fact]
public void add_health_check_when_properly_configured()
{
var services = new ServiceCollection();
services.AddSurreal(ConnectionString);
services
.AddHealthChecks()
.AddSurreal();

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 add_named_health_check_when_properly_configured()
{
var services = new ServiceCollection();
services.AddSurreal(ConnectionString);
services
.AddHealthChecks()
.AddSurreal(name: "my-surrealdb-1");

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();
services.AddSurreal(ConnectionString);
bool factoryCalled = false;
services.AddHealthChecks()
.AddSurreal(sp =>
{
factoryCalled = true;
return sp.GetRequiredService<SurrealDbClient>();
});

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
Loading