-
Notifications
You must be signed in to change notification settings - Fork 808
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/479' of https://github.com/ahryshchanka/AspNetC…
…ore.Diagnostics.HealthChecks into ahryshchanka-feature/479
- Loading branch information
Showing
13 changed files
with
340 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using Microsoft.Extensions.Diagnostics.HealthChecks; | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ArangoDBNetStandard; | ||
using ArangoDBNetStandard.AuthApi; | ||
using ArangoDBNetStandard.Transport.Http; | ||
|
||
namespace HealthChecks.ArangoDb | ||
{ | ||
public class ArangoDbHealthCheck | ||
: IHealthCheck | ||
{ | ||
private readonly ArangoDbOptions _options; | ||
public ArangoDbHealthCheck(ArangoDbOptions options) | ||
{ | ||
_options = options ?? throw new ArgumentNullException(nameof(options)); | ||
} | ||
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) | ||
{ | ||
try | ||
{ | ||
using (var transport = await GetTransport(_options)) | ||
using (var adb = new ArangoDBClient(transport)) | ||
{ | ||
var databases = await adb.Database.GetCurrentDatabaseInfoAsync(); | ||
return databases.Error | ||
? new HealthCheckResult(context.Registration.FailureStatus, $"HealthCheck failed with status code: {databases.Code}.") | ||
: HealthCheckResult.Healthy(); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
return new HealthCheckResult(context.Registration.FailureStatus, ex.Message, ex); | ||
} | ||
} | ||
private static async Task<HttpApiTransport> GetTransport(ArangoDbOptions options) | ||
{ | ||
if (!string.IsNullOrWhiteSpace(options.JwtToken)) | ||
{ | ||
return HttpApiTransport.UsingJwtAuth(new Uri(options.HostUri), options.Database, options.JwtToken); | ||
} | ||
|
||
if (options.IsGenerateJwtTokenBasedOnUserNameAndPassword) | ||
{ | ||
if (string.IsNullOrWhiteSpace(options.UserName)) | ||
{ | ||
throw new ArgumentNullException(nameof(options.UserName)); | ||
} | ||
if (string.IsNullOrWhiteSpace(options.Password)) | ||
{ | ||
throw new ArgumentNullException(nameof(options.Password)); | ||
} | ||
|
||
var transport = HttpApiTransport.UsingNoAuth(new Uri(options.HostUri), options.Database); | ||
var authClient = new AuthApiClient(transport); | ||
var jwtTokenResponse = await authClient.GetJwtTokenAsync(options.UserName, options.Password); | ||
transport.SetJwtToken(jwtTokenResponse.Jwt); | ||
return transport; | ||
} | ||
|
||
if (!string.IsNullOrWhiteSpace(options.UserName) && !string.IsNullOrWhiteSpace(options.Password)) | ||
{ | ||
return HttpApiTransport.UsingBasicAuth(new Uri(options.HostUri), options.Database, options.UserName, options.Password); | ||
} | ||
|
||
return HttpApiTransport.UsingNoAuth(new Uri(options.HostUri), options.Database); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace HealthChecks.ArangoDb | ||
{ | ||
public class ArangoDbOptions | ||
{ | ||
public string HostUri { get; set; } | ||
public string Database { get; set; } | ||
public bool IsGenerateJwtTokenBasedOnUserNameAndPassword { get; set; } = false; | ||
public string UserName { get; set; } = string.Empty; | ||
public string Password { get; set; } = string.Empty; | ||
public string JwtToken { get; set; } = string.Empty; | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/HealthChecks.ArangoDb/DependencyInjection/ArangoDbHealthCheckBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using Microsoft.Extensions.Diagnostics.HealthChecks; | ||
using System; | ||
using System.Collections.Generic; | ||
using HealthChecks.ArangoDb; | ||
|
||
namespace Microsoft.Extensions.DependencyInjection | ||
{ | ||
public static class ArangoDbHealthCheckBuilderExtensions | ||
{ | ||
private const string NAME = "arangodb"; | ||
|
||
/// <summary> | ||
/// Add a health check for ArangoDB. | ||
/// </summary> | ||
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param> | ||
/// <param name="connectionOptionsFactory">A factory to build the ArangoDB connection data to use.</param> | ||
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'arangodb' 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 System.TimeSpan representing the timeout of the check.</param> | ||
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns> | ||
public static IHealthChecksBuilder AddArangoDb(this IHealthChecksBuilder builder, | ||
Func<IServiceProvider, ArangoDbOptions> connectionOptionsFactory, | ||
string name = default, | ||
HealthStatus? failureStatus = default, | ||
IEnumerable<string> tags = default, | ||
TimeSpan? timeout = default) | ||
{ | ||
if (connectionOptionsFactory == null) | ||
{ | ||
throw new ArgumentNullException(nameof(connectionOptionsFactory)); | ||
} | ||
|
||
return builder.Add(new HealthCheckRegistration( | ||
name ?? NAME, | ||
sp => new ArangoDbHealthCheck(connectionOptionsFactory(sp)), | ||
failureStatus, | ||
tags, | ||
timeout)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>$(NetStandardTargetVersion)</TargetFramework> | ||
<PackageLicenseUrl>$(PackageLicenseUrl)</PackageLicenseUrl> | ||
<PackageProjectUrl>$(PackageProjectUrl)</PackageProjectUrl> | ||
<Description>HealthChecks.ArangoDb is the health check package for ArangoDb.</Description> | ||
<PackageTags>HealthCheck;Health;ArangoDb</PackageTags> | ||
<Version>$(HealthCheckArangoDb)</Version> | ||
<RepositoryUrl>$(RepositoryUrl)</RepositoryUrl> | ||
<Company>$(Company)</Company> | ||
<Authors>$(Authors)</Authors> | ||
<LangVersion>latest</LangVersion> | ||
<PackageId>AspNetCore.HealthChecks.ArangoDb</PackageId> | ||
<PublishRepositoryUrl>$(PublishRepositoryUrl)</PublishRepositoryUrl> | ||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder)</AllowedOutputExtensionsInPackageBuildOutputFolder> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="ArangoDBNetStandard" Version="$(ArangoDBNetStandard)" /> | ||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="$(MicrosoftExtensionsDiagnosticsHealthChecks)" /> | ||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="$(MicrosoftSourceLinkGithub)"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
test/FunctionalTests/HealthChecks.ArangoDb/ArangoDbHealthCheckTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
using FluentAssertions; | ||
using FunctionalTests.Base; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Diagnostics.HealthChecks; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.AspNetCore.TestHost; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using System.Net; | ||
using System.Threading.Tasks; | ||
using HealthChecks.ArangoDb; | ||
using Xunit; | ||
|
||
namespace FunctionalTests.HealthChecks.ArangoDb | ||
{ | ||
[Collection("execution")] | ||
public class arangodb_healthcheck_should | ||
{ | ||
[SkipOnAppVeyor] | ||
public async Task be_healthy_if_arangodb_is_available() | ||
{ | ||
var webHostBuilder = new WebHostBuilder() | ||
.UseStartup<DefaultStartup>() | ||
.ConfigureServices(services => | ||
{ | ||
services.AddHealthChecks() | ||
.AddArangoDb(_ => new ArangoDbOptions | ||
{ | ||
HostUri = "http://localhost:8529/", | ||
Database = "_system", | ||
UserName = "root", | ||
Password = "strongArangoDbPassword" | ||
}, tags: new string[] { "arangodb" }); | ||
}) | ||
.Configure(app => | ||
{ | ||
app.UseHealthChecks("/health", new HealthCheckOptions | ||
{ | ||
Predicate = r => r.Tags.Contains("arangodb") | ||
}); | ||
}); | ||
|
||
var server = new TestServer(webHostBuilder); | ||
|
||
var response = await server.CreateRequest($"/health").GetAsync(); | ||
|
||
response.StatusCode.Should().Be(HttpStatusCode.OK); | ||
} | ||
|
||
[SkipOnAppVeyor] | ||
public async Task be_healthy_if_multiple_arango_are_available() | ||
{ | ||
var webHostBuilder = new WebHostBuilder() | ||
.UseStartup<DefaultStartup>() | ||
.ConfigureServices(services => | ||
{ | ||
services.AddHealthChecks() | ||
.AddArangoDb(_ => new ArangoDbOptions | ||
{ | ||
HostUri = "http://localhost:8529/", | ||
Database = "_system", | ||
UserName = "root", | ||
Password = "strongArangoDbPassword" | ||
}, tags: new string[] { "arango" }, name: "1") | ||
.AddArangoDb(_ =>new ArangoDbOptions | ||
{ | ||
HostUri = "http://localhost:8529/", | ||
Database = "_system", | ||
UserName = "root", | ||
Password = "strongArangoDbPassword", | ||
IsGenerateJwtTokenBasedOnUserNameAndPassword = true | ||
}, tags: new string[] { "arango" }, name: "2"); | ||
}) | ||
.Configure(app => | ||
{ | ||
app.UseHealthChecks("/health", new HealthCheckOptions | ||
{ | ||
Predicate = r => r.Tags.Contains("arango") | ||
}); | ||
}); | ||
|
||
var server = new TestServer(webHostBuilder); | ||
|
||
var response = await server.CreateRequest($"/health").GetAsync(); | ||
|
||
response.StatusCode.Should().Be(HttpStatusCode.OK); | ||
} | ||
|
||
[Fact] | ||
public async Task be_unhealthy_if_arango_is_not_available() | ||
{ | ||
var webHostBuilder = new WebHostBuilder() | ||
.UseStartup<DefaultStartup>() | ||
.ConfigureServices(services => | ||
{ | ||
services.AddHealthChecks() | ||
.AddArangoDb(_ => new ArangoDbOptions | ||
{ | ||
HostUri = "http://localhost:8529/", | ||
Database = "_system", | ||
UserName = "root", | ||
Password = "invalid password" | ||
}, tags: new string[] { "arango" }); | ||
}) | ||
.Configure(app => | ||
{ | ||
app.UseHealthChecks("/health", new HealthCheckOptions | ||
{ | ||
Predicate = r => r.Tags.Contains("arango") | ||
}); | ||
}); | ||
|
||
var server = new TestServer(webHostBuilder); | ||
|
||
var response = await server.CreateRequest($"/health").GetAsync(); | ||
|
||
response.StatusCode.Should().Be(HttpStatusCode.ServiceUnavailable); | ||
} | ||
} | ||
} |
Oops, something went wrong.