Skip to content

Commit

Permalink
Add HealthChecks.Dapr (#1947)
Browse files Browse the repository at this point in the history
  • Loading branch information
cieciurm authored Jul 25, 2023
1 parent 1b92fc7 commit cb0871a
Show file tree
Hide file tree
Showing 13 changed files with 340 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ consul:
cosmosdb:
- src/HealthChecks.CosmosDb/**/*

dapr:
- src/HealthChecks.Dapr/**/*

documentdb:
- src/HealthChecks.DocumentDb/**/*

Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/healthchecks_dapr_cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: HealthChecks Dapr CD

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

jobs:
build:
env:
BUILD_CONFIG: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
7.0.x
- name: Restore
run: dotnet restore ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj
- name: Build
run: dotnet build --no-restore ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj -c $BUILD_CONFIG
- name: Pack
run: dotnet pack --no-build ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj -c $BUILD_CONFIG -o ./artifacts
- name: Publish
run: dotnet nuget push ./artifacts/AspNetCore.HealthChecks.Dapr.*.nupkg -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json --skip-duplicate
30 changes: 30 additions & 0 deletions .github/workflows/healthchecks_dapr_cd_preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: HealthChecks Dapr Preview CD

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

jobs:
build:
env:
BUILD_CONFIG: Release
VERSION_SUFFIX: rc2.${{ github.run_number }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
7.0.x
- name: Restore
run: dotnet restore ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj
- name: Build
run: dotnet build --no-restore ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj -c $BUILD_CONFIG
- name: Pack
run: dotnet pack --no-build ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj --version-suffix $VERSION_SUFFIX -c $BUILD_CONFIG -o ./artifacts
- name: Publish
run: dotnet nuget push ./artifacts/AspNetCore.HealthChecks.Dapr.*.nupkg -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json --skip-duplicate
65 changes: 65 additions & 0 deletions .github/workflows/healthchecks_dapr_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: HealthChecks Dapr CI

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

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

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
7.0.x
- name: Restore
run: |
dotnet restore ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj &&
dotnet restore ./test/HealthChecks.Dapr.Tests/HealthChecks.Dapr.Tests.csproj
- name: Check formatting
run: |
dotnet format --no-restore --verify-no-changes --severity warn ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1) &&
dotnet format --no-restore --verify-no-changes --severity warn ./test/HealthChecks.Dapr.Tests/HealthChecks.Dapr.Tests.csproj || (echo "Run 'dotnet format' to fix issues" && exit 1)
- name: Build
run: |
dotnet build --no-restore ./src/HealthChecks.Dapr/HealthChecks.Dapr.csproj &&
dotnet build --no-restore ./test/HealthChecks.Dapr.Tests/HealthChecks.Dapr.Tests.csproj
- name: Test
run: >
dotnet test
./test/HealthChecks.Dapr.Tests/HealthChecks.Dapr.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: Dapr
directory: .coverage
14 changes: 14 additions & 0 deletions AspNetCore.Diagnostics.HealthChecks.sln
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.AzureSearch.Te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.UI.Data.Tests", "test\HealthChecks.UI.Data.Tests\HealthChecks.UI.Data.Tests.csproj", "{93DEEAD7-9A89-48C6-AD42-103AEADBCACE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Dapr", "src\HealthChecks.Dapr\HealthChecks.Dapr.csproj", "{716C2E59-6BB4-49A1-B685-9958B7EF0F3B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.Dapr.Tests", "test\HealthChecks.Dapr.Tests\HealthChecks.Dapr.Tests.csproj", "{1C2085FA-2D33-459B-945E-337323485E16}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -783,6 +787,14 @@ Global
{93DEEAD7-9A89-48C6-AD42-103AEADBCACE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93DEEAD7-9A89-48C6-AD42-103AEADBCACE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93DEEAD7-9A89-48C6-AD42-103AEADBCACE}.Release|Any CPU.Build.0 = Release|Any CPU
{716C2E59-6BB4-49A1-B685-9958B7EF0F3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{716C2E59-6BB4-49A1-B685-9958B7EF0F3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{716C2E59-6BB4-49A1-B685-9958B7EF0F3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{716C2E59-6BB4-49A1-B685-9958B7EF0F3B}.Release|Any CPU.Build.0 = Release|Any CPU
{1C2085FA-2D33-459B-945E-337323485E16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C2085FA-2D33-459B-945E-337323485E16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C2085FA-2D33-459B-945E-337323485E16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C2085FA-2D33-459B-945E-337323485E16}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -912,6 +924,8 @@ Global
{0BE32765-7244-4717-9D48-B4C716DD1769} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4}
{076B7DAE-E92A-4B81-BC1D-D63AF0E9C5B4} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE}
{93DEEAD7-9A89-48C6-AD42-103AEADBCACE} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE}
{716C2E59-6BB4-49A1-B685-9958B7EF0F3B} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4}
{1C2085FA-2D33-459B-945E-337323485E16} = {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 @@ -82,6 +82,7 @@ HealthChecks packages include health checks for:
| Azure Storage | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.AzureStorage)](https://www.nuget.org/packages/AspNetCore.HealthChecks.AzureStorage) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.AzureStorage)](https://www.nuget.org/packages/AspNetCore.HealthChecks.AzureStorage) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/azure)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/azure) | Blob, File, Queue |
| Consul | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Consul)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Consul) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Consul)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Consul) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/consul)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/consul)
| CosmosDb | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.CosmosDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.CosmosDb) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.CosmosDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.CosmosDb) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/cosmosdb)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/cosmosdb) | CosmosDb and Azure Table
| Dapr | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Dapr)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Dapr) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Dapr)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Dapr) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/dapr)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/dapr)
| Azure DocumentDb | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.DocumentDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.DocumentDb) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.DocumentDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.DocumentDb) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/documentdb)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/documentdb)
| Amazon DynamoDb | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.DynamoDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.DynamoDb) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.DynamoDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.DynamoDb) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/dynamodb)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/dynamodb)
| Elasticsearch | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Elasticsearch)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Elasticsearch) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Elasticsearch)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Elasticsearch) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/elasticsearch)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/elasticsearch)
Expand Down Expand Up @@ -131,6 +132,7 @@ Install-Package AspNetCore.HealthChecks.AzureServiceBus
Install-Package AspNetCore.HealthChecks.AzureStorage
Install-Package AspNetCore.HealthChecks.Consul
Install-Package AspNetCore.HealthChecks.CosmosDb
Install-Package AspNetCore.HealthChecks.Dapr
Install-Package AspNetCore.HealthChecks.DocumentDb
Install-Package AspNetCore.HealthChecks.DynamoDB
Install-Package AspNetCore.HealthChecks.Elasticsearch
Expand Down
1 change: 1 addition & 0 deletions build/versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<HealthCheckCloudFirestore>7.0.0</HealthCheckCloudFirestore>
<HealthCheckConsul>7.0.0</HealthCheckConsul>
<HealthCheckCosmosDb>7.0.0</HealthCheckCosmosDb>
<HealthCheckDapr>7.0.0</HealthCheckDapr>
<HealthCheckDocumentDb>7.0.0</HealthCheckDocumentDb>
<HealthCheckDynamoDb>7.0.0</HealthCheckDynamoDb>
<HealthCheckElasticsearch>7.0.0</HealthCheckElasticsearch>
Expand Down
22 changes: 22 additions & 0 deletions src/HealthChecks.Dapr/DaprHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Dapr.Client;
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace HealthChecks.Dapr;

public class DaprHealthCheck : IHealthCheck
{
private readonly DaprClient _daprClient;

public DaprHealthCheck(DaprClient daprClient)
{
_daprClient = daprClient ?? throw new ArgumentNullException(nameof(daprClient));
}

/// <inheritdoc />
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
return await _daprClient.CheckHealthAsync(cancellationToken).ConfigureAwait(false)
? HealthCheckResult.Healthy()
: new HealthCheckResult(context.Registration.FailureStatus);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Dapr.Client;
using HealthChecks.Dapr;
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// Extension methods to configure <see cref="DaprHealthCheck"/>.
/// </summary>
public static class DaprHealthCheckBuilderExtensions
{
private const string DAPR_NAME = "dapr";

/// <summary>
/// Add a health check for Dapr using provided <see cref="DaprClient"/>.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="daprClient">The <see cref="DaprClient"/> to be used.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'dapr' 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 <see cref="TimeSpan"/> representing the timeout of the check. Optional.</param>
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
public static IHealthChecksBuilder AddDapr(
this IHealthChecksBuilder builder,
DaprClient daprClient,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
return builder.Add(new HealthCheckRegistration(
name ?? DAPR_NAME,
new DaprHealthCheck(daprClient),
failureStatus,
tags,
timeout));
}

/// <summary>
/// Add a health check for Dapr using <see cref="DaprClient"/> from service provider.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'dapr' 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 <see cref="TimeSpan"/> representing the timeout of the check. Optional.</param>
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
public static IHealthChecksBuilder AddDapr(
this IHealthChecksBuilder builder,
string? name = default,
HealthStatus? failureStatus = default,
IEnumerable<string>? tags = default,
TimeSpan? timeout = default)
{
return builder.Add(new HealthCheckRegistration(
name ?? DAPR_NAME,
sp => new DaprHealthCheck(sp.GetRequiredService<DaprClient>()),
failureStatus,
tags,
timeout));
}
}
15 changes: 15 additions & 0 deletions src/HealthChecks.Dapr/HealthChecks.Dapr.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<PackageTags>$(PackageTags);Dapr</PackageTags>
<Description>HealthChecks.Dapr is the health check package for Dapr.</Description>
<VersionPrefix>$(HealthCheckDapr)</VersionPrefix>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.9" />
<PackageReference Include="Dapr.Client" Version="1.11.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Dapr.Client;

namespace HealthChecks.Dapr.Tests.DependencyInjection;

public class dapr_registration_should
{
private const string _defaultCheckName = "dapr";

[Fact]
public void add_health_check_when_properly_configured_using_di()
{
var services = new ServiceCollection();
services.AddSingleton(new DaprClientBuilder().Build());
services.AddHealthChecks()
.AddDapr();

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(_defaultCheckName);
check.ShouldBeOfType<DaprHealthCheck>();
}

[Fact]
public void add_health_check_when_properly_configured_using_arguments()
{
var services = new ServiceCollection();
services.AddHealthChecks()
.AddDapr(daprClient: new DaprClientBuilder().Build());

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(_defaultCheckName);
check.ShouldBeOfType<DaprHealthCheck>();
}

[Fact]
public void add_named_health_check_when_properly_configured()
{
var services = new ServiceCollection();
var customCheckName = "my-" + _defaultCheckName;

services.AddSingleton(new DaprClientBuilder().Build());
services.AddHealthChecks()
.AddDapr(name: customCheckName);

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(customCheckName);
check.ShouldBeOfType<DaprHealthCheck>();
}
}
11 changes: 11 additions & 0 deletions test/HealthChecks.Dapr.Tests/HealthChecks.Dapr.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\HealthChecks.Dapr\HealthChecks.Dapr.csproj" />
</ItemGroup>

</Project>
16 changes: 16 additions & 0 deletions test/HealthChecks.Dapr.Tests/HealthChecks.Dapr.approved.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace HealthChecks.Dapr
{
public class DaprHealthCheck : Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck
{
public DaprHealthCheck(Dapr.Client.DaprClient daprClient) { }
public System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult> CheckHealthAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext context, System.Threading.CancellationToken cancellationToken = default) { }
}
}
namespace Microsoft.Extensions.DependencyInjection
{
public static class DaprHealthCheckBuilderExtensions
{
public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddDapr(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, 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 AddDapr(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, Dapr.Client.DaprClient daprClient, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable<string>? tags = null, System.TimeSpan? timeout = default) { }
}
}

0 comments on commit cb0871a

Please sign in to comment.