diff --git a/README.md b/README.md index a16ea5b034..163a6c6b7c 100644 --- a/README.md +++ b/README.md @@ -261,7 +261,7 @@ Check this [README](./AzureDevOpsTasks/README.md) on how to configure it. AspNetCore.Diagnostics.HealthChecks wouldn't be possible without the time and effort of its contributors. The team is made up of Unai Zorrilla Castro [@unaizorrilla](https://github.com/unaizorrilla), Luis Ruiz Pavón [@lurumad](https://github.com/lurumad), Carlos Landeras [@carloslanderas](https://github.com/carloslanderas) and Eduard Tomás [@eiximenis](https://github.com/eiximenis). -*Our valued committers are*: Hugo Biarge @hbiarge, Matt Channer @mattchanner, Luis Fraile @lfraile, Bradley Grainger @bgrainger, Simon Birrer @SbiCA, Mahamadou Camara @poumup,Jonathan Berube @joncloud, Daniel Edwards @dantheman999301, Mike McFarland @roketworks, Matteo @Franklin89, Miňo Martiniak @Burgyn, Peter Winkler @pajzo, @mikevanoo,Alexandru Rus @AlexandruRus23,Volker Thiel @riker09, Ahmad Magdy @Ahmad-Magdy, Marcel Lambacher @Marcel-Lambacher. +*Our valued committers are*: Hugo Biarge @hbiarge, Matt Channer @mattchanner, Luis Fraile @lfraile, Bradley Grainger @bgrainger, Simon Birrer @SbiCA, Mahamadou Camara @poumup,Jonathan Berube @joncloud, Daniel Edwards @dantheman999301, Mike McFarland @roketworks, Matteo @Franklin89, Miňo Martiniak @Burgyn, Peter Winkler @pajzo, @mikevanoo,Alexandru Rus @AlexandruRus23,Volker Thiel @riker09, Ahmad Magdy @Ahmad-Magdy, Marcel Lambacher @Marcel-Lambacher,Ivan Maximov @sungam3r. If you want to contribute to the project and make it better, your help is very welcome. You can contribute with helpful bug reports, features requests and also submitting new features with pull requests. diff --git a/build.ps1 b/build.ps1 index 428d522e91..06219d6058 100644 --- a/build.ps1 +++ b/build.ps1 @@ -3,7 +3,7 @@ <# .SYNOPSIS This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode - to see if an error occcured. If an error is detected then an exception is thrown. + to see if an error occured. If an error is detected then an exception is thrown. This function allows you to run command-line programs without having to explicitly check the $lastexitcode variable. .EXAMPLE @@ -22,7 +22,7 @@ function Exec } } -if(Test-Path .\artifacts) { Remove-Item .\artifacts -Force -Recurse } +if (Test-Path .\artifacts) { Remove-Item .\artifacts -Force -Recurse } exec { & dotnet restore } @@ -94,6 +94,7 @@ if ($suffix -eq "") { exec { & dotnet pack .\src\HealthChecks.UI.Client\HealthChecks.UI.Client.csproj -c Release -o ..\..\artifacts --include-symbols --no-build } exec { & dotnet pack .\src\HealthChecks.Publisher.ApplicationInsights\HealthChecks.Publisher.ApplicationInsights.csproj -c Release -o ..\..\artifacts --include-symbols --no-build } exec { & dotnet pack .\src\HealthChecks.Publisher.Prometheus\HealthChecks.Publisher.Prometheus.csproj -c Release -o ..\..\artifacts --include-symbols --no-build } + exec { & dotnet pack .\src\HealthChecks.Publisher.Seq\HealthChecks.Publisher.Seq.csproj -c Release -o ..\..\artifacts --include-symbols --no-build } exec { & dotnet pack .\src\HealthChecks.Consul\HealthChecks.Consul.csproj -c Release -o ..\..\artifacts --include-symbols --no-build } exec { & dotnet pack .\src\HealthChecks.RavenDB\HealthChecks.RavenDB.csproj -c Release -o ..\..\artifacts --include-symbols --no-build } exec { & dotnet pack .\src\HealthChecks.Kubernetes\HealthChecks.Kubernetes.csproj -c Release -o ..\..\artifacts --include-symbols --no-build } @@ -128,6 +129,7 @@ else { exec { & dotnet pack .\src\HealthChecks.UI.Client\HealthChecks.UI.Client.csproj -c Release -o ..\..\artifacts --include-symbols --no-build --version-suffix=$suffix } exec { & dotnet pack .\src\HealthChecks.Publisher.ApplicationInsights\HealthChecks.Publisher.ApplicationInsights.csproj -c Release -o ..\..\artifacts --include-symbols --no-build --version-suffix=$suffix } exec { & dotnet pack .\src\HealthChecks.Publisher.Prometheus\HealthChecks.Publisher.Prometheus.csproj -c Release -o ..\..\artifacts --include-symbols --no-build --version-suffix=$suffix } + exec { & dotnet pack .\src\HealthChecks.Publisher.Seq\HealthChecks.Publisher.Seq.csproj -c Release -o ..\..\artifacts --include-symbols --no-build --version-suffix=$suffix } exec { & dotnet pack .\src\HealthChecks.Consul\HealthChecks.Consul.csproj -c Release -o ..\..\artifacts --include-symbols --no-build --version-suffix=$suffix } exec { & dotnet pack .\src\HealthChecks.RavenDB\HealthChecks.RavenDB.csproj -c Release -o ..\..\artifacts --include-symbols --no-build --version-suffix=$suffix } exec { & dotnet pack .\src\HealthChecks.Kubernetes\HealthChecks.Kubernetes.csproj -c Release -o ..\..\artifacts --include-symbols --no-build --version-suffix=$suffix } diff --git a/build/dependencies.props b/build/dependencies.props index b7c4451327..a484e69e52 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -75,7 +75,7 @@ 2.2.0 2.2.0 2.2.3 - 2.2.2 + 2.2.3 2.2.1 2.2.1 2.2.1 @@ -99,7 +99,7 @@ 2.2.0 2.2.0 2.2.2 - 2.2.0 + 2.2.1 2.2.2 2.2.1 2.2.0 diff --git a/dotnet-install.ps1 b/dotnet-install.ps1 index 14ebe11af2..4e0543f8d2 100644 --- a/dotnet-install.ps1 +++ b/dotnet-install.ps1 @@ -48,7 +48,7 @@ .PARAMETER DryRun If set it will not perform installation but instead display what command line to use to consistently install currently requested version of dotnet cli. In example if you specify version 'latest' it will display a link - with specific version so that this command can be used deterministicly in a build script. + with specific version so that this command can be used deterministically in a build script. It also displays binaries location if you prefer to install or download it yourself. .PARAMETER NoPath By default this script will set environment variable PATH for the current process to the binaries folder inside installation folder. @@ -199,11 +199,11 @@ function GetHTTPResponse([Uri] $Uri) # HttpClient is used vs Invoke-WebRequest in order to support Nano Server which doesn't support the Invoke-WebRequest cmdlet. Load-Assembly -Assembly System.Net.Http - if(-not $ProxyAddress) { + if (-not $ProxyAddress) { try { # Despite no proxy being explicitly specified, we may still be behind a default proxy $DefaultProxy = [System.Net.WebRequest]::DefaultWebProxy; - if($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) { + if ($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) { $ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString $ProxyUseDefaultCredentials = $true } @@ -215,7 +215,7 @@ function GetHTTPResponse([Uri] $Uri) } } - if($ProxyAddress) { + if ($ProxyAddress) { $HttpClientHandler = New-Object System.Net.Http.HttpClientHandler $HttpClientHandler.Proxy = New-Object System.Net.WebProxy -Property @{Address=$ProxyAddress;UseDefaultCredentials=$ProxyUseDefaultCredentials} $HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler diff --git a/samples/HealthChecks.Sample/Controllers/ValuesController.cs b/samples/HealthChecks.Sample/Controllers/ValuesController.cs index 8540c5a3bf..3e09e93e8b 100644 --- a/samples/HealthChecks.Sample/Controllers/ValuesController.cs +++ b/samples/HealthChecks.Sample/Controllers/ValuesController.cs @@ -1,8 +1,5 @@ -using System; +using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; namespace HealthChecks.Sample.Controllers { diff --git a/samples/HealthChecks.Sample/Program.cs b/samples/HealthChecks.Sample/Program.cs index 582894f49c..b0d3a57424 100644 --- a/samples/HealthChecks.Sample/Program.cs +++ b/samples/HealthChecks.Sample/Program.cs @@ -1,12 +1,5 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; +using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; namespace HealthChecks.Sample { diff --git a/samples/HealthChecks.Sample/Startup.cs b/samples/HealthChecks.Sample/Startup.cs index e5796629d3..29d6eaa15b 100644 --- a/samples/HealthChecks.Sample/Startup.cs +++ b/samples/HealthChecks.Sample/Startup.cs @@ -45,12 +45,12 @@ public void ConfigureServices(IServiceCollection services) // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { - app.UseHealthChecks("/health", new HealthCheckOptions() + app.UseHealthChecks("/health", new HealthCheckOptions { Predicate = _ => true }); - app.UseHealthChecks("/healthz", new HealthCheckOptions() + app.UseHealthChecks("/healthz", new HealthCheckOptions { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse diff --git a/samples/HealthChecks.UI.Sample/Program.cs b/samples/HealthChecks.UI.Sample/Program.cs index 0834db4e08..73d51b5814 100644 --- a/samples/HealthChecks.UI.Sample/Program.cs +++ b/samples/HealthChecks.UI.Sample/Program.cs @@ -1,12 +1,5 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; +using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; namespace HealthChecks.UI.Sample { diff --git a/samples/HealthChecks.UI.Sample/Startup.cs b/samples/HealthChecks.UI.Sample/Startup.cs index 7cfe2ded7b..78124785a7 100644 --- a/samples/HealthChecks.UI.Sample/Startup.cs +++ b/samples/HealthChecks.UI.Sample/Startup.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; namespace HealthChecks.UI.Sample diff --git a/samples/HealthChecks.UIAndApi/Program.cs b/samples/HealthChecks.UIAndApi/Program.cs index eefc2b4385..efdc6f419c 100644 --- a/samples/HealthChecks.UIAndApi/Program.cs +++ b/samples/HealthChecks.UIAndApi/Program.cs @@ -1,12 +1,5 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; +using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; namespace HealthChecks.UIAndApi { diff --git a/samples/HealthChecks.UIAndApi/Startup.cs b/samples/HealthChecks.UIAndApi/Startup.cs index 65d02b869e..76bd3ca36e 100644 --- a/samples/HealthChecks.UIAndApi/Startup.cs +++ b/samples/HealthChecks.UIAndApi/Startup.cs @@ -64,9 +64,9 @@ public void ConfigureServices(IServiceCollection services) // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { - app.UseHealthChecks("/healthz",new HealthCheckOptions() + app.UseHealthChecks("/healthz",new HealthCheckOptions { - Predicate = _=>true, + Predicate = _=> true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }) .UseHealthChecksUI() diff --git a/samples/HealthChecks.UIAndApiCustomization/Program.cs b/samples/HealthChecks.UIAndApiCustomization/Program.cs index eefc2b4385..efdc6f419c 100644 --- a/samples/HealthChecks.UIAndApiCustomization/Program.cs +++ b/samples/HealthChecks.UIAndApiCustomization/Program.cs @@ -1,12 +1,5 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; +using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; namespace HealthChecks.UIAndApi { diff --git a/samples/HealthChecks.UIAndApiCustomization/Startup.cs b/samples/HealthChecks.UIAndApiCustomization/Startup.cs index 1c2c97a919..4d5ea81a25 100644 --- a/samples/HealthChecks.UIAndApiCustomization/Startup.cs +++ b/samples/HealthChecks.UIAndApiCustomization/Startup.cs @@ -36,7 +36,7 @@ public void ConfigureServices(IServiceCollection services) } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { - app.UseHealthChecks("/healthz", new HealthCheckOptions() + app.UseHealthChecks("/healthz", new HealthCheckOptions { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse diff --git a/src/HealthChecks.Aws.S3/S3HealthCheck.cs b/src/HealthChecks.Aws.S3/S3HealthCheck.cs index 01fa6d8094..3e35aa374c 100644 --- a/src/HealthChecks.Aws.S3/S3HealthCheck.cs +++ b/src/HealthChecks.Aws.S3/S3HealthCheck.cs @@ -12,21 +12,22 @@ public class S3HealthCheck : IHealthCheck private readonly S3BucketOptions _bucketOptions; public S3HealthCheck(S3BucketOptions bucketOptions) { + if (bucketOptions == null) + { + throw new ArgumentNullException(nameof(bucketOptions)); + } if (string.IsNullOrEmpty(bucketOptions.AccessKey)) { throw new ArgumentNullException(nameof(S3BucketOptions.AccessKey)); } - if (string.IsNullOrEmpty(bucketOptions.SecretKey)) { throw new ArgumentNullException(nameof(S3BucketOptions.SecretKey)); } - if (bucketOptions.S3Config == null) { throw new ArgumentNullException(nameof(S3BucketOptions.S3Config)); } - _bucketOptions = bucketOptions; } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) @@ -34,17 +35,17 @@ public async Task CheckHealthAsync(HealthCheckContext context try { var credentials = new BasicAWSCredentials(_bucketOptions.AccessKey, _bucketOptions.SecretKey); - var client = new AmazonS3Client(credentials, _bucketOptions.S3Config); - - var response = await client.ListObjectsAsync(_bucketOptions.BucketName, cancellationToken); - - if (_bucketOptions.CustomResponseCheck != null) - { - return _bucketOptions.CustomResponseCheck.Invoke(response) - ? HealthCheckResult.Healthy() - : new HealthCheckResult(context.Registration.FailureStatus, description:"Custom response check is not satisfied."); + using (var client = new AmazonS3Client(credentials, _bucketOptions.S3Config)) + { + var response = await client.ListObjectsAsync(_bucketOptions.BucketName, cancellationToken); + + if (_bucketOptions.CustomResponseCheck != null) + { + return _bucketOptions.CustomResponseCheck.Invoke(response) + ? HealthCheckResult.Healthy() + : new HealthCheckResult(context.Registration.FailureStatus, description: "Custom response check is not satisfied."); + } } - return HealthCheckResult.Healthy(); } catch (Exception ex) diff --git a/src/HealthChecks.AzureKeyVault/AzureKeyVaultHealthCheck.cs b/src/HealthChecks.AzureKeyVault/AzureKeyVaultHealthCheck.cs index d529b6168f..3c28bbec0b 100644 --- a/src/HealthChecks.AzureKeyVault/AzureKeyVaultHealthCheck.cs +++ b/src/HealthChecks.AzureKeyVault/AzureKeyVaultHealthCheck.cs @@ -11,7 +11,6 @@ namespace HealthChecks.AzureKeyVault public class AzureKeyVaultHealthCheck : IHealthCheck { private readonly AzureKeyVaultOptions _options; - public AzureKeyVaultHealthCheck(AzureKeyVaultOptions options) { _options = options ?? throw new ArgumentNullException(nameof(options)); @@ -19,15 +18,15 @@ public AzureKeyVaultHealthCheck(AzureKeyVaultOptions options) public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { var currentSecret = string.Empty; - try { - var client = CreateClient(); - foreach (var item in _options.Secrets) - { - await client.GetSecretAsync(_options.KeyVaultUrlBase, item, cancellationToken); + using (var client = CreateClient()) + { + foreach (var item in _options.Secrets) + { + await client.GetSecretAsync(_options.KeyVaultUrlBase, item, cancellationToken); + } } - return HealthCheckResult.Healthy(); } catch (Exception ex) @@ -35,7 +34,6 @@ public async Task CheckHealthAsync(HealthCheckContext context return new HealthCheckResult(context.Registration.FailureStatus, exception: ex); } } - private KeyVaultClient CreateClient() { if (_options.UseManagedServiceIdentity) @@ -48,7 +46,6 @@ private KeyVaultClient CreateClient() return new KeyVaultClient(GetToken); } } - private async Task GetToken(string authority, string resource, string scope) { var authContext = new AuthenticationContext(authority); @@ -59,7 +56,6 @@ private async Task GetToken(string authority, string resource, string sc { throw new InvalidOperationException($"[{nameof(AzureKeyVaultHealthCheck)}] - Failed to obtain the JWT token"); } - return result.AccessToken; } } diff --git a/src/HealthChecks.AzureServiceBus/DependencyInjection/AzureServiceBusHealthCheckBuilderExtensions.cs b/src/HealthChecks.AzureServiceBus/DependencyInjection/AzureServiceBusHealthCheckBuilderExtensions.cs index 17ac77f70f..fc5f730f0e 100644 --- a/src/HealthChecks.AzureServiceBus/DependencyInjection/AzureServiceBusHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.AzureServiceBus/DependencyInjection/AzureServiceBusHealthCheckBuilderExtensions.cs @@ -31,7 +31,6 @@ public static IHealthChecksBuilder AddAzureEventHub(this IHealthChecksBuilder bu failureStatus, tags)); } - /// /// Add a health check for specified Azure Service Bus Queue. /// @@ -48,12 +47,11 @@ public static IHealthChecksBuilder AddAzureEventHub(this IHealthChecksBuilder bu public static IHealthChecksBuilder AddAzureServiceBusQueue(this IHealthChecksBuilder builder, string connectionString, string queueName, string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { return builder.Add(new HealthCheckRegistration( - name ?? AZUREQUEUE_NAME, + name ?? AZUREQUEUE_NAME, sp => new AzureServiceBusQueueHealthCheck(connectionString, queueName), failureStatus, tags)); } - /// /// Add a health check for Azure Service Bus Topic. /// @@ -70,7 +68,7 @@ public static IHealthChecksBuilder AddAzureServiceBusQueue(this IHealthChecksBui public static IHealthChecksBuilder AddAzureServiceBusTopic(this IHealthChecksBuilder builder, string connectionString, string topicName, string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { return builder.Add(new HealthCheckRegistration( - name ?? AZURETOPIC_NAME, + name ?? AZURETOPIC_NAME, sp => new AzureServiceBusTopicHealthCheck(connectionString, topicName), failureStatus, tags)); diff --git a/src/HealthChecks.AzureStorage/AzureBlobStorageHealthCheck.cs b/src/HealthChecks.AzureStorage/AzureBlobStorageHealthCheck.cs index 2a1a683461..6b373676fd 100644 --- a/src/HealthChecks.AzureStorage/AzureBlobStorageHealthCheck.cs +++ b/src/HealthChecks.AzureStorage/AzureBlobStorageHealthCheck.cs @@ -7,12 +7,16 @@ namespace HealthChecks.AzureStorage { - public class AzureBlobStorageHealthCheck + public class AzureBlobStorageHealthCheck : IHealthCheck { private readonly string _connectionString; public AzureBlobStorageHealthCheck(string connectionString) { + if (string.IsNullOrEmpty(connectionString)) + { + throw new ArgumentNullException(nameof(connectionString)); + } _connectionString = connectionString; } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) diff --git a/src/HealthChecks.AzureStorage/AzureQueueStorageHealthCheck.cs b/src/HealthChecks.AzureStorage/AzureQueueStorageHealthCheck.cs index b196f93ea3..066fc91e67 100644 --- a/src/HealthChecks.AzureStorage/AzureQueueStorageHealthCheck.cs +++ b/src/HealthChecks.AzureStorage/AzureQueueStorageHealthCheck.cs @@ -7,12 +7,16 @@ namespace HealthChecks.AzureStorage { - public class AzureQueueStorageHealthCheck + public class AzureQueueStorageHealthCheck : IHealthCheck { private readonly string _connectionString; public AzureQueueStorageHealthCheck(string connectionString) { + if (string.IsNullOrEmpty(connectionString)) + { + throw new ArgumentNullException(nameof(connectionString)); + } _connectionString = connectionString; } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) diff --git a/src/HealthChecks.AzureStorage/AzureTableStorageHealthCheck.cs b/src/HealthChecks.AzureStorage/AzureTableStorageHealthCheck.cs index 9810161cc4..90905f866a 100644 --- a/src/HealthChecks.AzureStorage/AzureTableStorageHealthCheck.cs +++ b/src/HealthChecks.AzureStorage/AzureTableStorageHealthCheck.cs @@ -13,6 +13,10 @@ public class AzureTableStorageHealthCheck private readonly string _connectionString; public AzureTableStorageHealthCheck(string connectionString) { + if (string.IsNullOrEmpty(connectionString)) + { + throw new ArgumentNullException(nameof(connectionString)); + } _connectionString = connectionString; } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) diff --git a/src/HealthChecks.Consul/ConsulHealthCheck.cs b/src/HealthChecks.Consul/ConsulHealthCheck.cs index 3c6792629b..7156b29318 100644 --- a/src/HealthChecks.Consul/ConsulHealthCheck.cs +++ b/src/HealthChecks.Consul/ConsulHealthCheck.cs @@ -14,15 +14,14 @@ public class ConsulHealthCheck : IHealthCheck private readonly Func _httpClientFactory; public ConsulHealthCheck(ConsulOptions options, Func httpClientFactory) { - _options = options; - _httpClientFactory = httpClientFactory; + _options = options ?? throw new ArgumentNullException(nameof(options)); + _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { try { var client = _httpClientFactory(); - if (_options.RequireBasicAuthentication) { var credentials = ASCIIEncoding.ASCII.GetBytes($"{_options.Username}:{_options.Password}"); @@ -31,7 +30,6 @@ public async Task CheckHealthAsync(HealthCheckContext context client.DefaultRequestHeaders .Authorization = new AuthenticationHeaderValue("Basic", authHeaderValue); } - var result = await client .GetAsync($"{(_options.RequireHttps ? "https" : "http")}://{_options.HostName}:{_options.Port}/v1/status/leader", cancellationToken); diff --git a/src/HealthChecks.Consul/DependencyInjection/ConsulHealthCheckBuilderExtensions.cs b/src/HealthChecks.Consul/DependencyInjection/ConsulHealthCheckBuilderExtensions.cs index d4e19c6b0b..c888338b28 100644 --- a/src/HealthChecks.Consul/DependencyInjection/ConsulHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Consul/DependencyInjection/ConsulHealthCheckBuilderExtensions.cs @@ -9,7 +9,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class ConsulHealthCheckBuilderExtensions { private const string NAME = "consul"; - /// /// Add a health check for Consul services. /// @@ -31,14 +30,13 @@ public static IHealthChecksBuilder AddConsul(this IHealthChecksBuilder builder, builder.Services.AddHttpClient(); var registrationName = name ?? NAME; - return builder.Add(new HealthCheckRegistration( - name ?? NAME, + registrationName, sp => CreateHealthCheck(sp, options, registrationName), failureStatus, tags)); } - static ConsulHealthCheck CreateHealthCheck(IServiceProvider sp, ConsulOptions options, string name) + private static ConsulHealthCheck CreateHealthCheck(IServiceProvider sp, ConsulOptions options, string name) { var httpClientFactory = sp.GetRequiredService(); return new ConsulHealthCheck(options, () => httpClientFactory.CreateClient(name)); diff --git a/src/HealthChecks.CosmosDb/CosmosDbHealthCheck.cs b/src/HealthChecks.CosmosDb/CosmosDbHealthCheck.cs index 6656364afa..df4634d866 100644 --- a/src/HealthChecks.CosmosDb/CosmosDbHealthCheck.cs +++ b/src/HealthChecks.CosmosDb/CosmosDbHealthCheck.cs @@ -13,7 +13,6 @@ public class CosmosDbHealthCheck public CosmosDbHealthCheck(string connectionString) { _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); - } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { diff --git a/src/HealthChecks.CosmosDb/DependencyInjection/CosmosDbHealthCheckBuilderExtensions.cs b/src/HealthChecks.CosmosDb/DependencyInjection/CosmosDbHealthCheckBuilderExtensions.cs index c7087eeb2d..e13d91c1bc 100644 --- a/src/HealthChecks.CosmosDb/DependencyInjection/CosmosDbHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.CosmosDb/DependencyInjection/CosmosDbHealthCheckBuilderExtensions.cs @@ -7,7 +7,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class CosmosDbHealthCheckBuilderExtensions { const string NAME = "cosmosdb"; - /// /// Add a health check for Azure CosmosDb database. /// diff --git a/src/HealthChecks.DocumentDb/DependencyInjection/DocumentDbHealthCheckBuilderExtensions.cs b/src/HealthChecks.DocumentDb/DependencyInjection/DocumentDbHealthCheckBuilderExtensions.cs index ba4f603c2e..e5c1911568 100644 --- a/src/HealthChecks.DocumentDb/DependencyInjection/DocumentDbHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.DocumentDb/DependencyInjection/DocumentDbHealthCheckBuilderExtensions.cs @@ -8,7 +8,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class DocumentDbHealthCheckBuilderExtensions { const string NAME = "documentdb"; - /// /// Add a health check for Azure DocumentDb database. /// diff --git a/src/HealthChecks.DocumentDb/DocumentDbHealthCheck.cs b/src/HealthChecks.DocumentDb/DocumentDbHealthCheck.cs index f1b678a73f..40f416ab69 100644 --- a/src/HealthChecks.DocumentDb/DocumentDbHealthCheck.cs +++ b/src/HealthChecks.DocumentDb/DocumentDbHealthCheck.cs @@ -23,7 +23,7 @@ public async Task CheckHealthAsync(HealthCheckContext context new Uri(_documentDbOptions.UriEndpoint), _documentDbOptions.PrimaryKey)) { - await documentDbClient.OpenAsync(); + await documentDbClient.OpenAsync(cancellationToken); return HealthCheckResult.Healthy(); } } diff --git a/src/HealthChecks.DynamoDb/DynamoDbHealthCheck.cs b/src/HealthChecks.DynamoDb/DynamoDbHealthCheck.cs index 4dd9f1f2b6..2a98676184 100644 --- a/src/HealthChecks.DynamoDb/DynamoDbHealthCheck.cs +++ b/src/HealthChecks.DynamoDb/DynamoDbHealthCheck.cs @@ -13,11 +13,10 @@ public class DynamoDbHealthCheck private readonly DynamoDBOptions _options; public DynamoDbHealthCheck(DynamoDBOptions options) { + _options = options ?? throw new ArgumentNullException(nameof(options)); if (string.IsNullOrEmpty(options.AccessKey)) throw new ArgumentNullException(nameof(DynamoDBOptions.AccessKey)); if (string.IsNullOrEmpty(options.SecretKey)) throw new ArgumentNullException(nameof(DynamoDBOptions.SecretKey)); if (options.RegionEndpoint == null) throw new ArgumentNullException(nameof(DynamoDBOptions.RegionEndpoint)); - - _options = options; } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { @@ -26,7 +25,7 @@ public async Task CheckHealthAsync(HealthCheckContext context var credentials = new BasicAWSCredentials(_options.AccessKey, _options.SecretKey); var client = new AmazonDynamoDBClient(credentials, _options.RegionEndpoint); - await client.ListTablesAsync(); + await client.ListTablesAsync(cancellationToken); return HealthCheckResult.Healthy(); } catch (Exception ex) diff --git a/src/HealthChecks.Elasticsearch/DependencyInjection/ElasticsearchHealthCheckBuilderExtensions.cs b/src/HealthChecks.Elasticsearch/DependencyInjection/ElasticsearchHealthCheckBuilderExtensions.cs index d5be82ec62..c70fd45e75 100644 --- a/src/HealthChecks.Elasticsearch/DependencyInjection/ElasticsearchHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Elasticsearch/DependencyInjection/ElasticsearchHealthCheckBuilderExtensions.cs @@ -8,13 +8,12 @@ namespace Microsoft.Extensions.DependencyInjection public static class ElasticsearchHealthCheckBuilderExtensions { const string NAME = "elasticsearch"; - /// /// Add a health check for Elasticsearch databases. /// /// The . - /// The Elasticsearchv connection string to be used. - /// The health check name. Optional. If null the type name 'mongodb' will be used for the name. + /// The Elasticsearch connection string to be used. + /// The health check name. Optional. If null the type name 'elasticsearch' will be used for the name. /// /// The that should be reported when the health check fails. Optional. If null then /// the default status of will be reported. @@ -32,13 +31,12 @@ public static IHealthChecksBuilder AddElasticsearch(this IHealthChecksBuilder bu failureStatus, tags)); } - /// /// Add a health check for Elasticsearch databases. /// /// The . /// The Elasticsearch option setup. - /// The health check name. Optional. If null the type name 'mongodb' will be used for the name. + /// The health check name. Optional. If null the type name 'elasticsearch' will be used for the name. /// /// The that should be reported when the health check fails. Optional. If null then /// the default status of will be reported. diff --git a/src/HealthChecks.Elasticsearch/ElasticsearchHealthCheck.cs b/src/HealthChecks.Elasticsearch/ElasticsearchHealthCheck.cs index ae44d7c09a..a4406cc8a3 100644 --- a/src/HealthChecks.Elasticsearch/ElasticsearchHealthCheck.cs +++ b/src/HealthChecks.Elasticsearch/ElasticsearchHealthCheck.cs @@ -30,15 +30,12 @@ public async Task CheckHealthAsync(HealthCheckContext context } var lowlevelClient = new ElasticClient(settings); - var pingResult = await lowlevelClient.PingAsync(cancellationToken: cancellationToken); - var isSuccess = pingResult.ApiCall.HttpStatusCode == 200; return isSuccess ? HealthCheckResult.Healthy() : new HealthCheckResult(context.Registration.FailureStatus); - } catch (Exception ex) { diff --git a/src/HealthChecks.Elasticsearch/ElasticsearchOptions.cs b/src/HealthChecks.Elasticsearch/ElasticsearchOptions.cs index a09bf3786d..c9734c9545 100644 --- a/src/HealthChecks.Elasticsearch/ElasticsearchOptions.cs +++ b/src/HealthChecks.Elasticsearch/ElasticsearchOptions.cs @@ -11,7 +11,6 @@ public class ElasticsearchOptions public X509Certificate Certificate { get; private set; } public bool AuthenticateWithBasicCredentials { get; private set; } = false; public bool AuthenticateWithCertificate { get; private set; } = false; - public ElasticsearchOptions UseBasicAuthentication(string name, string password) { UserName = name ?? throw new ArgumentNullException(nameof(name)); @@ -22,11 +21,10 @@ public ElasticsearchOptions UseBasicAuthentication(string name, string password) AuthenticateWithBasicCredentials = true; return this; } - public ElasticsearchOptions UseCertificate(X509Certificate certificate) { Certificate = certificate ?? throw new ArgumentNullException(nameof(certificate)); - + UserName = string.Empty; Password = string.Empty; AuthenticateWithBasicCredentials = false; diff --git a/src/HealthChecks.EventStore/DependencyInjection/EventStoreHealthCheckBuilderExtensions.cs b/src/HealthChecks.EventStore/DependencyInjection/EventStoreHealthCheckBuilderExtensions.cs index 9cbc86abf5..06f5f6bd62 100644 --- a/src/HealthChecks.EventStore/DependencyInjection/EventStoreHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.EventStore/DependencyInjection/EventStoreHealthCheckBuilderExtensions.cs @@ -7,14 +7,13 @@ namespace Microsoft.Extensions.DependencyInjection public static class EventStoreHealthCheckBuilderExtensions { const string NAME = "eventstore"; - /// /// Add a health check for EventStore services. /// /// The . /// The EventStore connection string to be used. - /// The EventStore user login. Optional. If null the healthcheck will be processed without authentification. - /// The EventStore user password. Optional. If null the healthcheck will be processed without authentification. + /// The EventStore user login. Optional. If null the healthcheck will be processed without authentication. + /// The EventStore user password. Optional. If null the healthcheck will be processed without authentication. /// The health check name. Optional. If null the type name 'eventstore' will be used for the name. /// /// The that should be reported when the health check fails. Optional. If null then diff --git a/src/HealthChecks.EventStore/EventStoreHealthCheck.cs b/src/HealthChecks.EventStore/EventStoreHealthCheck.cs index ddcb0923bb..96e6a1db74 100644 --- a/src/HealthChecks.EventStore/EventStoreHealthCheck.cs +++ b/src/HealthChecks.EventStore/EventStoreHealthCheck.cs @@ -11,11 +11,9 @@ public class EventStoreHealthCheck : IHealthCheck { const string CONNECTION_NAME = "AspNetCore HealthCheck Connection"; - private readonly string _eventStoreConnection; private readonly string _login; private readonly string _password; - public EventStoreHealthCheck(string eventStoreConnection, string login, string password) { _eventStoreConnection = eventStoreConnection ?? throw new ArgumentNullException(nameof(eventStoreConnection)); diff --git a/src/HealthChecks.Hangfire/DependencyInjection/HangfireHealthCheckBuilderExtensions.cs b/src/HealthChecks.Hangfire/DependencyInjection/HangfireHealthCheckBuilderExtensions.cs index 4182369d04..d0a358afda 100644 --- a/src/HealthChecks.Hangfire/DependencyInjection/HangfireHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Hangfire/DependencyInjection/HangfireHealthCheckBuilderExtensions.cs @@ -8,7 +8,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class HangfireHealthCheckBuilderExtensions { const string NAME = "hangfire"; - /// /// Add a health check for Hangfire. /// diff --git a/src/HealthChecks.Hangfire/HangfireHealthCheck.cs b/src/HealthChecks.Hangfire/HangfireHealthCheck.cs index 17f9edd3bd..2a330ae131 100644 --- a/src/HealthChecks.Hangfire/HangfireHealthCheck.cs +++ b/src/HealthChecks.Hangfire/HangfireHealthCheck.cs @@ -10,10 +10,10 @@ namespace HealthChecks.Hangfire public class HangfireHealthCheck : IHealthCheck { - private readonly HangfireOptions _hangfireOptions = new HangfireOptions(); + private readonly HangfireOptions _hangfireOptions; public HangfireHealthCheck(HangfireOptions hangfireOptions) { - _hangfireOptions = hangfireOptions; + _hangfireOptions = hangfireOptions ?? throw new ArgumentNullException(nameof(hangfireOptions)); } public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { @@ -44,7 +44,7 @@ public Task CheckHealthAsync(HealthCheckContext context, Canc { return Task.FromResult(new HealthCheckResult(context.Registration.FailureStatus, description: string.Join(" + ", errorList))); } - + return Task.FromResult(HealthCheckResult.Healthy()); } catch (Exception ex) diff --git a/src/HealthChecks.IdSvr/DependencyInjection/IdSvrHealthCheckBuilderExtensions.cs b/src/HealthChecks.IdSvr/DependencyInjection/IdSvrHealthCheckBuilderExtensions.cs index c6e345adbc..56659596e9 100644 --- a/src/HealthChecks.IdSvr/DependencyInjection/IdSvrHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.IdSvr/DependencyInjection/IdSvrHealthCheckBuilderExtensions.cs @@ -9,7 +9,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class IdSvrHealthCheckBuilderExtensions { const string NAME = "idsvr"; - /// /// Add a health check for Identity Server. /// @@ -24,10 +23,10 @@ public static class IdSvrHealthCheckBuilderExtensions /// The . public static IHealthChecksBuilder AddIdentityServer(this IHealthChecksBuilder builder, Uri idSvrUri, string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { - var registrationName = name ?? NAME; - - builder.Services.AddHttpClient(registrationName, client => client.BaseAddress = idSvrUri); - + var registrationName = name ?? NAME; + + builder.Services.AddHttpClient(registrationName, client => client.BaseAddress = idSvrUri); + return builder.Add(new HealthCheckRegistration( registrationName, sp => new IdSvrHealthCheck(() => sp.GetRequiredService().CreateClient(registrationName)), diff --git a/src/HealthChecks.IdSvr/IdSvrHealthCheck.cs b/src/HealthChecks.IdSvr/IdSvrHealthCheck.cs index db91a86ca0..8f1e4d5d05 100644 --- a/src/HealthChecks.IdSvr/IdSvrHealthCheck.cs +++ b/src/HealthChecks.IdSvr/IdSvrHealthCheck.cs @@ -25,7 +25,7 @@ public async Task CheckHealthAsync(HealthCheckContext context if (!response.IsSuccessStatusCode) { - return new HealthCheckResult(context.Registration.FailureStatus, description: $"Discover endpoint is not responding with 200 OK, the current status is {response.StatusCode} and the content { (await response.Content.ReadAsStringAsync())}"); + return new HealthCheckResult(context.Registration.FailureStatus, description: $"Discover endpoint is not responding with 200 OK, the current status is {response.StatusCode} and the content { await response.Content.ReadAsStringAsync() }"); } return HealthCheckResult.Healthy(); diff --git a/src/HealthChecks.Kafka/DependencyInjection/KafkaHealthCheckBuilderExtensions.cs b/src/HealthChecks.Kafka/DependencyInjection/KafkaHealthCheckBuilderExtensions.cs index 6129161fc9..82d0680be6 100644 --- a/src/HealthChecks.Kafka/DependencyInjection/KafkaHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Kafka/DependencyInjection/KafkaHealthCheckBuilderExtensions.cs @@ -1,5 +1,6 @@ using HealthChecks.Kafka; using Microsoft.Extensions.Diagnostics.HealthChecks; +using System; using System.Collections.Generic; namespace Microsoft.Extensions.DependencyInjection @@ -7,7 +8,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class KafkaHealthCheckBuilderExtensions { const string NAME = "kafka"; - /// /// Add a health check for Kafka cluster. /// @@ -28,5 +28,28 @@ public static IHealthChecksBuilder AddKafka(this IHealthChecksBuilder builder, D failureStatus, tags)); } + /// + /// Add a health check for Kafka cluster. + /// + /// The . + /// The action to configure the kafka connection configuration parameters to be used. + /// The health check name. Optional. If null the type name 'kafka' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// The . + public static IHealthChecksBuilder AddKafka(this IHealthChecksBuilder builder, Action> setup, string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) + { + var config = new Dictionary(); + setup?.Invoke(config); + + return builder.Add(new HealthCheckRegistration( + name ?? NAME, + sp => new KafkaHealthCheck(config), + failureStatus, + tags)); + } } } diff --git a/src/HealthChecks.Kafka/KafkaHealthCheck.cs b/src/HealthChecks.Kafka/KafkaHealthCheck.cs index 2cd757ea23..d9d0c73b26 100644 --- a/src/HealthChecks.Kafka/KafkaHealthCheck.cs +++ b/src/HealthChecks.Kafka/KafkaHealthCheck.cs @@ -23,12 +23,10 @@ public async Task CheckHealthAsync(HealthCheckContext context using (var producer = new Producer(_configuration, new StringSerializer(Encoding.UTF8), new StringSerializer(Encoding.UTF8))) { var result = await producer.ProduceAsync("beatpulse-topic", "beatpulse-key", $"Check Kafka healthy on {DateTime.UtcNow}"); - if (result.Error.Code != ErrorCode.NoError) { return new HealthCheckResult(context.Registration.FailureStatus, description: $"ErrorCode {result.Error.Code} with reason ('{result.Error.Reason}')"); } - return HealthCheckResult.Healthy(); } } diff --git a/src/HealthChecks.Kubernetes/DependencyInjection/KubernetesHealthCheckBuilderExtensions.cs b/src/HealthChecks.Kubernetes/DependencyInjection/KubernetesHealthCheckBuilderExtensions.cs index 74b4da9888..8c0ec5c87c 100644 --- a/src/HealthChecks.Kubernetes/DependencyInjection/KubernetesHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Kubernetes/DependencyInjection/KubernetesHealthCheckBuilderExtensions.cs @@ -3,20 +3,18 @@ using System.Collections.Generic; using HealthChecks.Kubernetes; using k8s; -using Microsoft.Extensions.DependencyInjection.Extensions; namespace Microsoft.Extensions.DependencyInjection { public static class KubernetesHealthCheckBuilderExtensions { const string NAME = "k8s"; - /// /// Add the Kubernetes Health Check /// /// The . /// Action to configure Kubernetes cluster and registrations - /// The health check name. Optional. If null the type name 'kafka' will be used for the name. + /// The health check name. Optional. If null the type name 'k8s' will be used for the name. /// /// The that should be reported when the health check fails. Optional. If null then /// the default status of will be reported. @@ -25,7 +23,6 @@ public static class KubernetesHealthCheckBuilderExtensions /// The . public static IHealthChecksBuilder AddKubernetes(this IHealthChecksBuilder builder, Action setup, string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { - var kubernetesHealthCheckBuilder = new KubernetesHealthCheckBuilder(); setup?.Invoke(kubernetesHealthCheckBuilder); diff --git a/src/HealthChecks.Kubernetes/Extensions/KubernetesChecksTaskExtensions.cs b/src/HealthChecks.Kubernetes/Extensions/KubernetesChecksTaskExtensions.cs index 7993aa307b..7170f99bf5 100644 --- a/src/HealthChecks.Kubernetes/Extensions/KubernetesChecksTaskExtensions.cs +++ b/src/HealthChecks.Kubernetes/Extensions/KubernetesChecksTaskExtensions.cs @@ -1,5 +1,4 @@ - -namespace System.Threading.Tasks +namespace System.Threading.Tasks { public static class KubernetesChecksTaskExtensions { diff --git a/src/HealthChecks.Kubernetes/KubernetesChecksExecutor.cs b/src/HealthChecks.Kubernetes/KubernetesChecksExecutor.cs index 36eae7a676..898752a56e 100644 --- a/src/HealthChecks.Kubernetes/KubernetesChecksExecutor.cs +++ b/src/HealthChecks.Kubernetes/KubernetesChecksExecutor.cs @@ -1,22 +1,18 @@ +using k8s.Models; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using k8s; -using k8s.Models; namespace HealthChecks.Kubernetes { public class KubernetesChecksExecutor { private readonly k8s.Kubernetes _client; - - private Dictionary>> _handlers; - - + private readonly Dictionary>> _handlers; public KubernetesChecksExecutor(k8s.Kubernetes client) { - _client = client; + _client = client ?? throw new ArgumentNullException(nameof(client)); _handlers = new Dictionary>>() { [typeof(V1Deployment)] = CheckDeploymentAsync, @@ -24,7 +20,6 @@ public KubernetesChecksExecutor(k8s.Kubernetes client) [typeof(V1Pod)] = CheckPodAsync }; } - public Task<(bool, string)> CheckAsync(KubernetesResourceCheck resourceCheck, CancellationToken cancellationToken) { var handler = _handlers[resourceCheck.ResourceType]; @@ -32,7 +27,6 @@ public KubernetesChecksExecutor(k8s.Kubernetes client) throw new InvalidOperationException( $"No handler registered for type {resourceCheck.ResourceType.Name}"); } - private async Task<(bool, string)> CheckDeploymentAsync(KubernetesResourceCheck resourceCheck, CancellationToken cancellationToken) { var tsc = new TaskCompletionSource<(bool, string)>(); @@ -52,7 +46,6 @@ public KubernetesChecksExecutor(k8s.Kubernetes client) return await tsc.Task; } - private async Task<(bool, string)> CheckPodAsync(KubernetesResourceCheck resourceCheck, CancellationToken cancellationToken) { var tsc = new TaskCompletionSource<(bool, string)>(); @@ -70,9 +63,7 @@ public KubernetesChecksExecutor(k8s.Kubernetes client) } return await tsc.Task; - } - private async Task<(bool, string)> CheckServiceAsync(KubernetesResourceCheck resourceCheck, CancellationToken cancellationToken) { var tsc = new TaskCompletionSource<(bool, string)>(); @@ -90,7 +81,6 @@ public KubernetesChecksExecutor(k8s.Kubernetes client) } return await tsc.Task; - } } } \ No newline at end of file diff --git a/src/HealthChecks.Kubernetes/KubernetesHealthCheck.cs b/src/HealthChecks.Kubernetes/KubernetesHealthCheck.cs index 0819144f6f..e21a98862a 100644 --- a/src/HealthChecks.Kubernetes/KubernetesHealthCheck.cs +++ b/src/HealthChecks.Kubernetes/KubernetesHealthCheck.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using k8s.Models; using Microsoft.Extensions.Diagnostics.HealthChecks; namespace HealthChecks.Kubernetes @@ -12,7 +11,6 @@ public class KubernetesHealthCheck : IHealthCheck { private readonly KubernetesHealthCheckBuilder _builder; private readonly KubernetesChecksExecutor _kubernetesChecksExecutor; - public KubernetesHealthCheck(KubernetesHealthCheckBuilder builder, KubernetesChecksExecutor kubernetesChecksExecutor) { @@ -20,7 +18,6 @@ public KubernetesHealthCheck(KubernetesHealthCheckBuilder builder, _kubernetesChecksExecutor = kubernetesChecksExecutor ?? throw new ArgumentNullException(nameof(kubernetesChecksExecutor)); } - public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken()) { @@ -44,7 +41,7 @@ public async Task CheckHealthAsync(HealthCheckContext context return HealthCheckResult.Healthy(); } - catch(AggregateException ex) + catch (AggregateException ex) { return new HealthCheckResult(context.Registration.FailureStatus, string.Join(",", ex.InnerExceptions.Select(s=> s.Message))); } @@ -53,7 +50,5 @@ public async Task CheckHealthAsync(HealthCheckContext context return new HealthCheckResult(context.Registration.FailureStatus, ex.Message); } } - - } } \ No newline at end of file diff --git a/src/HealthChecks.Kubernetes/KubernetesHealthCheckBuilder.cs b/src/HealthChecks.Kubernetes/KubernetesHealthCheckBuilder.cs index 9962043b4e..6f426d0182 100644 --- a/src/HealthChecks.Kubernetes/KubernetesHealthCheckBuilder.cs +++ b/src/HealthChecks.Kubernetes/KubernetesHealthCheckBuilder.cs @@ -6,7 +6,6 @@ public class KubernetesHealthCheckBuilder { internal KubernetesClientConfiguration Configuration { get; private set; } internal KubernetesHealthCheckOptions Options { get; private set; } - public KubernetesHealthCheckOptions WithConfiguration(KubernetesClientConfiguration configuration) { Configuration = configuration; diff --git a/src/HealthChecks.Kubernetes/KubernetesHealthCheckOptions.cs b/src/HealthChecks.Kubernetes/KubernetesHealthCheckOptions.cs index a571742f04..60b7fa0746 100644 --- a/src/HealthChecks.Kubernetes/KubernetesHealthCheckOptions.cs +++ b/src/HealthChecks.Kubernetes/KubernetesHealthCheckOptions.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Concurrent; using System.Collections.Generic; -using System.Linq; using k8s; using k8s.Models; @@ -11,14 +9,10 @@ public class KubernetesHealthCheckOptions { private const string DefaultNamespace = "default"; - internal KubernetesHealthCheckOptions(){} - - + internal KubernetesHealthCheckOptions() { } internal List Registrations { get; } = new List(); - public KubernetesHealthCheckOptions CheckDeployment(string name, Func condition, string @namespace = DefaultNamespace) - { Func delegateCheck = (o) => condition(o as V1Deployment); @@ -29,7 +23,6 @@ public KubernetesHealthCheckOptions CheckDeployment(string name, Func condition, string @namespace = DefaultNamespace) { @@ -42,7 +35,6 @@ public KubernetesHealthCheckOptions CheckPod(string name, Func cond return this; } - public KubernetesHealthCheckOptions CheckService(string name, Func condition, string @namespace = DefaultNamespace) { diff --git a/src/HealthChecks.Kubernetes/KubernetesResourceCheck.cs b/src/HealthChecks.Kubernetes/KubernetesResourceCheck.cs index a342a05dc2..d1480c21b9 100644 --- a/src/HealthChecks.Kubernetes/KubernetesResourceCheck.cs +++ b/src/HealthChecks.Kubernetes/KubernetesResourceCheck.cs @@ -1,19 +1,15 @@ -using System; -using System.Diagnostics; -using System.Threading.Tasks; using k8s; +using System; namespace HealthChecks.Kubernetes { public class KubernetesResourceCheck { - private readonly Func _condition; - + private readonly Func _condition; + public Type ResourceType { get; } public string Name { get; } public string Namespace { get; } - - private KubernetesResourceCheck(Type type, string name, string @namespace, Func condition) { _condition = condition; @@ -21,12 +17,11 @@ private KubernetesResourceCheck(Type type, string name, string @namespace, Func< Namespace = @namespace ?? throw new ArgumentNullException(nameof(@namespace)); ResourceType = type ?? throw new ArgumentNullException(nameof(type)); } - public static KubernetesResourceCheck Create(string name, string @namespace, Func condition) - where T: IKubernetesObject => - - new KubernetesResourceCheck(typeof(T),name, @namespace, condition); - + where T: IKubernetesObject + { + return new KubernetesResourceCheck(typeof(T), name, @namespace, condition); + } public bool Check(IKubernetesObject kubernetesObject) { return _condition?.Invoke(kubernetesObject) ?? true; diff --git a/src/HealthChecks.MongoDb/DependencyInjection/MongoDbHealthCheckBuilderExtensions.cs b/src/HealthChecks.MongoDb/DependencyInjection/MongoDbHealthCheckBuilderExtensions.cs index b8c1861a75..012ae31b85 100644 --- a/src/HealthChecks.MongoDb/DependencyInjection/MongoDbHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.MongoDb/DependencyInjection/MongoDbHealthCheckBuilderExtensions.cs @@ -1,14 +1,13 @@ using HealthChecks.MongoDb; using Microsoft.Extensions.Diagnostics.HealthChecks; -using System.Collections.Generic; using MongoDB.Driver; +using System.Collections.Generic; namespace Microsoft.Extensions.DependencyInjection { public static class MongoDbHealthCheckBuilderExtensions { const string NAME = "mongodb"; - /// /// Add a health check for MongoDb database that list all databases on the system. /// @@ -29,7 +28,6 @@ public static IHealthChecksBuilder AddMongoDb(this IHealthChecksBuilder builder, failureStatus, tags)); } - /// /// Add a health check for MongoDb database that list all collections from specified database on . /// @@ -51,7 +49,6 @@ public static IHealthChecksBuilder AddMongoDb(this IHealthChecksBuilder builder, failureStatus, tags)); } - /// /// Add a health check for MongoDb database that list all collections from specified database on . /// @@ -72,7 +69,6 @@ public static IHealthChecksBuilder AddMongoDb(this IHealthChecksBuilder builder, failureStatus, tags)); } - /// /// Add a health check for MongoDb database that list all collections from specified database on . /// diff --git a/src/HealthChecks.MongoDb/HealthChecks.MongoDb.csproj b/src/HealthChecks.MongoDb/HealthChecks.MongoDb.csproj index 1c203637df..ae664cc55a 100644 --- a/src/HealthChecks.MongoDb/HealthChecks.MongoDb.csproj +++ b/src/HealthChecks.MongoDb/HealthChecks.MongoDb.csproj @@ -1,5 +1,4 @@  - $(NetStandardTargetVersion) $(PackageLicenseUrl) @@ -23,6 +22,4 @@ runtime; build; native; contentfiles; analyzers - - diff --git a/src/HealthChecks.MongoDb/MongoDbHealthCheck.cs b/src/HealthChecks.MongoDb/MongoDbHealthCheck.cs index d935246fa1..078b257ed2 100644 --- a/src/HealthChecks.MongoDb/MongoDbHealthCheck.cs +++ b/src/HealthChecks.MongoDb/MongoDbHealthCheck.cs @@ -13,7 +13,6 @@ public class MongoDbHealthCheck private static readonly ConcurrentDictionary _mongoClient = new ConcurrentDictionary(); private readonly MongoClientSettings _mongoClientSettings; private readonly string _specifiedDatabase; - public MongoDbHealthCheck(string connectionString, string databaseName = default) : this(MongoClientSettings.FromUrl(MongoUrl.Create(connectionString)), databaseName) { diff --git a/src/HealthChecks.MySql/DependencyInjection/MySqlHealthCheckBuilderExtensions.cs b/src/HealthChecks.MySql/DependencyInjection/MySqlHealthCheckBuilderExtensions.cs index 142a3a5074..09e537f959 100644 --- a/src/HealthChecks.MySql/DependencyInjection/MySqlHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.MySql/DependencyInjection/MySqlHealthCheckBuilderExtensions.cs @@ -7,13 +7,12 @@ namespace Microsoft.Extensions.DependencyInjection public static class MySqlHealthCheckBuilderExtensions { const string NAME = "mysql"; - /// /// Add a health check for MySql databases. /// /// The . /// The MySql connection string to be used. - /// The health check name. Optional. If null the type name 'mongodb' will be used for the name. + /// The health check name. Optional. If null the type name 'mysql' will be used for the name. /// /// The that should be reported when the health check fails. Optional. If null then /// the default status of will be reported. diff --git a/src/HealthChecks.Network/Core/MailConnection.cs b/src/HealthChecks.Network/Core/MailConnection.cs index 6e54fbb705..04f653d307 100644 --- a/src/HealthChecks.Network/Core/MailConnection.cs +++ b/src/HealthChecks.Network/Core/MailConnection.cs @@ -15,10 +15,10 @@ public class MailConnection : IDisposable public string Host { get; protected set; } protected bool UseSSL { get; set; } = true; - protected TcpClient _tcpClient = null; - protected Stream _stream = null; + protected TcpClient _tcpClient; + protected Stream _stream; protected Func _validateRemoteCertificate = (o, c, ch, e) => true; - private bool _disposed = false; + private bool _disposed; private readonly bool _allowInvalidCertificates; public MailConnection(string host, int port, bool useSSL = true, bool allowInvalidCertificates = false) @@ -29,7 +29,6 @@ public MailConnection(string host, int port, bool useSSL = true, bool allowInval UseSSL = useSSL; _allowInvalidCertificates = allowInvalidCertificates; } - public async Task ConnectAsync() { _tcpClient = new TcpClient(); @@ -55,7 +54,6 @@ protected Stream GetStream() return stream; } } - protected SslStream GetSSLStream(Stream stream) { if (_allowInvalidCertificates) @@ -67,7 +65,6 @@ protected SslStream GetSSLStream(Stream stream) return new SslStream(stream); } } - protected async Task ExecuteCommand(string command) { var buffer = Encoding.ASCII.GetBytes(command); @@ -81,13 +78,11 @@ protected async Task ExecuteCommand(string command) return output; } - public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } - protected virtual void Dispose(bool disposing) { if (_disposed) @@ -100,6 +95,5 @@ protected virtual void Dispose(bool disposing) } _disposed = true; } - } } diff --git a/src/HealthChecks.Network/Core/SmtpConnection.cs b/src/HealthChecks.Network/Core/SmtpConnection.cs index 56ecb8a4f4..77f548a1cb 100644 --- a/src/HealthChecks.Network/Core/SmtpConnection.cs +++ b/src/HealthChecks.Network/Core/SmtpConnection.cs @@ -8,7 +8,6 @@ internal class SmtpConnection : MailConnection { private readonly SmtpConnectionOptions _options; private SmtpConnectionType _connectionType; - public SmtpConnectionType ConnectionType { get @@ -22,9 +21,6 @@ private set UseSSL = ConnectionType == SmtpConnectionType.SSL ? true : false; } } - - private bool ShouldUpgradeConnection => !UseSSL && _connectionType != SmtpConnectionType.PLAIN; - public SmtpConnection(SmtpConnectionOptions options) : base(options.Host, options.Port, false, options.AllowInvalidRemoteCertificates) { @@ -32,35 +28,12 @@ public SmtpConnection(SmtpConnectionOptions options) ConnectionType = _options.ConnectionType; ComputeDefaultValues(); } - - private void ComputeDefaultValues() - { - switch (_options.ConnectionType) - { - case SmtpConnectionType.AUTO when Port == 465: - ConnectionType = SmtpConnectionType.SSL; - break; - case SmtpConnectionType.AUTO when Port == 587: - ConnectionType = SmtpConnectionType.TLS; - break; - case SmtpConnectionType.AUTO when Port == 25: - ConnectionType = SmtpConnectionType.PLAIN; - break; - } - - if (ConnectionType == SmtpConnectionType.AUTO) - { - throw new Exception($"Port {Port} is not a valid smtp port when using automatic configuration"); - } - } - public new async Task ConnectAsync() { await base.ConnectAsync(); var result = await ExecuteCommand(SmtpCommands.EHLO(Host)); return result.Contains(SmtpResponse.ACTION_OK); } - public async Task AuthenticateAsync(string userName, string password) { if (ShouldUpgradeConnection) @@ -76,8 +49,27 @@ public async Task AuthenticateAsync(string userName, string password) var result = await ExecuteCommand($"{password}\r\n"); return result.Contains(SmtpResponse.AUTHENTICATION_SUCCESS); } + private bool ShouldUpgradeConnection => !UseSSL && _connectionType != SmtpConnectionType.PLAIN; + private void ComputeDefaultValues() + { + switch (_options.ConnectionType) + { + case SmtpConnectionType.AUTO when Port == 465: + ConnectionType = SmtpConnectionType.SSL; + break; + case SmtpConnectionType.AUTO when Port == 587: + ConnectionType = SmtpConnectionType.TLS; + break; + case SmtpConnectionType.AUTO when Port == 25: + ConnectionType = SmtpConnectionType.PLAIN; + break; + } - + if (ConnectionType == SmtpConnectionType.AUTO) + { + throw new Exception($"Port {Port} is not a valid smtp port when using automatic configuration"); + } + } private async Task UpgradeToSecureConnection() { var upgradeResult = await ExecuteCommand(SmtpCommands.STARTTLS()); @@ -92,7 +84,6 @@ private async Task UpgradeToSecureConnection() throw new Exception("Could not upgrade SMTP non SSL connection using STARTTLS handshake"); } } - private string ToBase64(string text) { return Convert.ToBase64String(Encoding.UTF8.GetBytes(text)); diff --git a/src/HealthChecks.Network/DependencyInjection/NetworkHealthCheckBuilderExtensions.cs b/src/HealthChecks.Network/DependencyInjection/NetworkHealthCheckBuilderExtensions.cs index 5ade1735db..c8a5dcc47b 100644 --- a/src/HealthChecks.Network/DependencyInjection/NetworkHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Network/DependencyInjection/NetworkHealthCheckBuilderExtensions.cs @@ -85,7 +85,6 @@ public static IHealthChecksBuilder AddFtpHealthCheck(this IHealthChecksBuilder b sp => new FtpHealthCheck(options), failureStatus, tags)); - } /// @@ -161,7 +160,7 @@ public static IHealthChecksBuilder AddSmtpHealthCheck(this IHealthChecksBuilder } /// - /// Add a health check for network SMTP connection. + /// Add a health check for network TCP connection. /// /// The . /// The action to configure TCP connection parameters. diff --git a/src/HealthChecks.Network/DnsResolveHealthCheck.cs b/src/HealthChecks.Network/DnsResolveHealthCheck.cs index 89b5af167b..22d7d92cf2 100644 --- a/src/HealthChecks.Network/DnsResolveHealthCheck.cs +++ b/src/HealthChecks.Network/DnsResolveHealthCheck.cs @@ -13,7 +13,7 @@ public class DnsResolveHealthCheck private readonly DnsResolveOptions _options; public DnsResolveHealthCheck(DnsResolveOptions options) { - _options = options ?? throw new ArgumentNullException(nameof(options)); ; + _options = options ?? throw new ArgumentNullException(nameof(options)); } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { diff --git a/src/HealthChecks.Network/DnsResolveOptions.cs b/src/HealthChecks.Network/DnsResolveOptions.cs index 7a8a9fc502..0fcba66666 100644 --- a/src/HealthChecks.Network/DnsResolveOptions.cs +++ b/src/HealthChecks.Network/DnsResolveOptions.cs @@ -4,9 +4,7 @@ namespace HealthChecks.Network { public class DnsResolveOptions { - internal Dictionary ConfigureHosts = new Dictionary(); - public void AddHost(string host, DnsRegistration registration) { ConfigureHosts.Add(host, registration); diff --git a/src/HealthChecks.Network/FtpHealthCheck.cs b/src/HealthChecks.Network/FtpHealthCheck.cs index 24e1d83d6f..ae1c6c22ab 100644 --- a/src/HealthChecks.Network/FtpHealthCheck.cs +++ b/src/HealthChecks.Network/FtpHealthCheck.cs @@ -18,16 +18,16 @@ public async Task CheckHealthAsync(HealthCheckContext context { try { - foreach (var item in _options.Hosts.Values) + foreach (var (host, createFile, credentials) in _options.Hosts.Values) { - var ftpRequest = CreateFtpWebRequest(item.host, item.createFile, item.credentials); + var ftpRequest = CreateFtpWebRequest(host, createFile, credentials); using (var ftpResponse = (FtpWebResponse)await ftpRequest.GetResponseAsync()) { if (ftpResponse.StatusCode != FtpStatusCode.PathnameCreated && ftpResponse.StatusCode != FtpStatusCode.ClosingData) { - return new HealthCheckResult(context.Registration.FailureStatus, description: $"Error connecting to ftp host {item.host} with exit code {ftpResponse.StatusCode}"); + return new HealthCheckResult(context.Registration.FailureStatus, description: $"Error connecting to ftp host {host} with exit code {ftpResponse.StatusCode}"); } } } @@ -39,7 +39,7 @@ public async Task CheckHealthAsync(HealthCheckContext context return new HealthCheckResult(context.Registration.FailureStatus, exception: ex); } } - WebRequest CreateFtpWebRequest(string host, bool createFile = false, NetworkCredential credentials = null) + private WebRequest CreateFtpWebRequest(string host, bool createFile = false, NetworkCredential credentials = null) { FtpWebRequest ftpRequest; diff --git a/src/HealthChecks.Network/ImapHealthCheck.cs b/src/HealthChecks.Network/ImapHealthCheck.cs index 618077ff36..8a53476488 100644 --- a/src/HealthChecks.Network/ImapHealthCheck.cs +++ b/src/HealthChecks.Network/ImapHealthCheck.cs @@ -10,7 +10,6 @@ public class ImapHealthCheck : IHealthCheck { private readonly ImapHealthCheckOptions _options; - private ImapConnection _imapConnection = null; public ImapHealthCheck(ImapHealthCheckOptions options) { _options = options ?? throw new ArgumentNullException(nameof(options)); @@ -29,18 +28,19 @@ public async Task CheckHealthAsync(HealthCheckContext context { try { - _imapConnection = new ImapConnection(_options); - - if (await _imapConnection.ConnectAsync()) + using (var imapConnection = new ImapConnection(_options)) { - if (_options.AccountOptions.Login) + if (await imapConnection.ConnectAsync()) { - return await ExecuteAuthenticatedUserActions(context); + if (_options.AccountOptions.Login) + { + return await ExecuteAuthenticatedUserActions(context, imapConnection); + } + } + else + { + return new HealthCheckResult(context.Registration.FailureStatus, description: $"Connection to server {_options.Host} has failed - SSL Enabled : {_options.ConnectionType}"); } - } - else - { - return new HealthCheckResult(context.Registration.FailureStatus, description: $"Connection to server {_options.Host} has failed - SSL Enabled : {_options.ConnectionType}"); } return HealthCheckResult.Healthy(); @@ -49,20 +49,15 @@ public async Task CheckHealthAsync(HealthCheckContext context { return new HealthCheckResult(context.Registration.FailureStatus, exception: ex); } - finally - { - _imapConnection.Dispose(); - } } - - private async Task ExecuteAuthenticatedUserActions(HealthCheckContext context) + private async Task ExecuteAuthenticatedUserActions(HealthCheckContext context, ImapConnection imapConnection) { var (User, Password) = _options.AccountOptions.Account; - if (await _imapConnection.AuthenticateAsync(User, Password)) + if (await imapConnection.AuthenticateAsync(User, Password)) { if (_options.FolderOptions.CheckFolder - && !await _imapConnection.SelectFolder(_options.FolderOptions.FolderName)) + && !await imapConnection.SelectFolder(_options.FolderOptions.FolderName)) { return new HealthCheckResult(context.Registration.FailureStatus, description: $"Folder {_options.FolderOptions.FolderName} check failed."); } diff --git a/src/HealthChecks.Network/SftpConfiguration.cs b/src/HealthChecks.Network/SftpConfiguration.cs index d377d799fe..24f1a7aace 100644 --- a/src/HealthChecks.Network/SftpConfiguration.cs +++ b/src/HealthChecks.Network/SftpConfiguration.cs @@ -9,13 +9,12 @@ namespace HealthChecks.Network { public class SftpConfigurationBuilder { - private string _host; - private int _port; - private string _userName; + private readonly string _host; + private readonly int _port; + private readonly string _userName; private (bool createFile, string remotePath) _fileCreationOptions = (false, string.Empty); internal List AuthenticationMethods { get; } = new List(); - public SftpConfigurationBuilder(string host, int port, string userName) { _host = host ?? throw new ArgumentNullException(nameof(host)); @@ -30,7 +29,6 @@ public SftpConfigurationBuilder AddPasswordAuthentication(string password) return this; } - public SftpConfigurationBuilder AddPrivateKeyAuthentication(string privateKey, string passphrase) { if (string.IsNullOrEmpty(privateKey)) throw new ArgumentNullException(nameof(privateKey)); @@ -50,22 +48,20 @@ public SftpConfigurationBuilder AddPrivateKeyAuthentication(string privateKey, s return this; } - public SftpConfigurationBuilder CreateFileOnConnect(string remoteFilePath) { _fileCreationOptions = (true, remoteFilePath); return this; } - public SftpConfiguration Build() { - if(!AuthenticationMethods.Any()) + if (!AuthenticationMethods.Any()) { throw new Exception("No AuthenticationMethods have been configured for Sftp Configuration"); } var sftpConfiguration = new SftpConfiguration(_host, _port, _userName, AuthenticationMethods); - if(_fileCreationOptions.createFile) + if (_fileCreationOptions.createFile) { sftpConfiguration.CreateRemoteFile(_fileCreationOptions.remotePath); } @@ -73,7 +69,6 @@ public SftpConfiguration Build() return sftpConfiguration; } } - public class SftpConfiguration { internal string Host { get; } @@ -89,12 +84,9 @@ internal SftpConfiguration(string host, int port, string userName, List CheckHealthAsync(HealthCheckContext context, Canc return Task.FromResult( HealthCheckResult.Healthy()); - } catch (Exception ex) { diff --git a/src/HealthChecks.Network/SftpHealthCheckOptions.cs b/src/HealthChecks.Network/SftpHealthCheckOptions.cs index af20d152b9..5244f26a12 100644 --- a/src/HealthChecks.Network/SftpHealthCheckOptions.cs +++ b/src/HealthChecks.Network/SftpHealthCheckOptions.cs @@ -5,7 +5,6 @@ namespace HealthChecks.Network public class SftpHealthCheckOptions { internal Dictionary ConfiguredHosts { get; } = new Dictionary(); - public SftpHealthCheckOptions AddHost(SftpConfiguration sftpConfiguration) { ConfiguredHosts.Add(sftpConfiguration.Host, sftpConfiguration); diff --git a/src/HealthChecks.Network/SmtpHealthCheckOptions.cs b/src/HealthChecks.Network/SmtpHealthCheckOptions.cs index 0d68fbaabc..9473d012e8 100644 --- a/src/HealthChecks.Network/SmtpHealthCheckOptions.cs +++ b/src/HealthChecks.Network/SmtpHealthCheckOptions.cs @@ -3,8 +3,8 @@ namespace HealthChecks.Network { - public class SmtpHealthCheckOptions : SmtpConnectionOptions { - + public class SmtpHealthCheckOptions : SmtpConnectionOptions + { internal (bool Login, (string, string) Account) AccountOptions { get; private set; } public void LoginWith(string userName, string password) { diff --git a/src/HealthChecks.Network/TcpHealthCheckOptions.cs b/src/HealthChecks.Network/TcpHealthCheckOptions.cs index 5fbfed3878..0df4a6f723 100644 --- a/src/HealthChecks.Network/TcpHealthCheckOptions.cs +++ b/src/HealthChecks.Network/TcpHealthCheckOptions.cs @@ -5,7 +5,6 @@ namespace HealthChecks.Network public class TcpHealthCheckOptions { internal List<(string host, int port)> ConfiguredHosts = new List<(string host, int port)>(); - public TcpHealthCheckOptions AddHost(string host, int port) { ConfiguredHosts.Add((host, port)); diff --git a/src/HealthChecks.NpgSql/DependencyInjection/NphSqlHealthCheckBuilderExtensions.cs b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs similarity index 96% rename from src/HealthChecks.NpgSql/DependencyInjection/NphSqlHealthCheckBuilderExtensions.cs rename to src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs index aa05b52f2e..8bb6c7c383 100644 --- a/src/HealthChecks.NpgSql/DependencyInjection/NphSqlHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.NpgSql/DependencyInjection/NpgSqlHealthCheckBuilderExtensions.cs @@ -4,10 +4,9 @@ namespace Microsoft.Extensions.DependencyInjection { - public static class NphSqlHealthCheckBuilderExtensions + public static class NpgSqlHealthCheckBuilderExtensions { const string NAME = "npgsql"; - /// /// Add a health check for Postgres databases. /// diff --git a/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs b/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs index 46d8bf0bb8..ba51aaac5d 100644 --- a/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs +++ b/src/HealthChecks.NpgSql/NpgSqlHealthCheck.cs @@ -27,7 +27,7 @@ public async Task CheckHealthAsync(HealthCheckContext context using (var command = connection.CreateCommand()) { command.CommandText = _sql; - await command.ExecuteScalarAsync(); + await command.ExecuteScalarAsync(cancellationToken); } return HealthCheckResult.Healthy(); diff --git a/src/HealthChecks.Oracle/DependencyInjection/OracleHealthCheckBuilderExtensions.cs b/src/HealthChecks.Oracle/DependencyInjection/OracleHealthCheckBuilderExtensions.cs index 9d91f723fe..5beed57bef 100644 --- a/src/HealthChecks.Oracle/DependencyInjection/OracleHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Oracle/DependencyInjection/OracleHealthCheckBuilderExtensions.cs @@ -20,7 +20,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class OracleHealthCheckBuilderExtensions { const string NAME = "oracle"; - public static IHealthChecksBuilder AddOracle(this IHealthChecksBuilder builder, string connectionString, string healthQuery = "select * from v$version", string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { return builder.Add(new HealthCheckRegistration( diff --git a/src/HealthChecks.Oracle/OracleHealthCheck.cs b/src/HealthChecks.Oracle/OracleHealthCheck.cs index 7f3524a5e8..d88f7e9254 100644 --- a/src/HealthChecks.Oracle/OracleHealthCheck.cs +++ b/src/HealthChecks.Oracle/OracleHealthCheck.cs @@ -11,27 +11,23 @@ public class OracleHealthCheck { private readonly string _connectionString; private readonly string _sql; - public OracleHealthCheck(string connectionString, string sql) { _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); _sql = sql ?? throw new ArgumentNullException(nameof(sql)); } - public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { try { using (var connection = new OracleConnection(_connectionString)) { - await connection.OpenAsync(); - + await connection.OpenAsync(cancellationToken); using (var command = connection.CreateCommand()) { command.CommandText = _sql; - await command.ExecuteScalarAsync(); + await command.ExecuteScalarAsync(cancellationToken); } - return HealthCheckResult.Healthy(); } } diff --git a/src/HealthChecks.Publisher.ApplicationInsights/ApplicationInsightsPublisher.cs b/src/HealthChecks.Publisher.ApplicationInsights/ApplicationInsightsPublisher.cs index 8d6f03e0dd..fd4ddff4e7 100644 --- a/src/HealthChecks.Publisher.ApplicationInsights/ApplicationInsightsPublisher.cs +++ b/src/HealthChecks.Publisher.ApplicationInsights/ApplicationInsightsPublisher.cs @@ -20,7 +20,7 @@ class ApplicationInsightsPublisher private readonly string _instrumentationKey; private static TelemetryClient _client; - private static object sync_root = new object(); + private static readonly object sync_root = new object(); private readonly bool _saveDetailedReport; private readonly bool _excludeHealthyReports; @@ -57,32 +57,32 @@ private void SaveDetailedReport(HealthReport report, TelemetryClient client) client.TrackEvent($"{EVENT_NAME}:{reportEntry.Key}", properties: new Dictionary() { - {nameof(Environment.MachineName), Environment.MachineName}, - {nameof(Assembly), Assembly.GetEntryAssembly().GetName().Name }, - {HEALTHCHECK_NAME, reportEntry.Key } + { nameof(Environment.MachineName), Environment.MachineName }, + { nameof(Assembly), Assembly.GetEntryAssembly().GetName().Name }, + { HEALTHCHECK_NAME, reportEntry.Key } }, metrics: new Dictionary() { - { METRIC_STATUS_NAME, reportEntry.Value.Status == HealthStatus.Healthy ? 1 :0}, - { METRIC_DURATION_NAME, reportEntry.Value.Duration.TotalMilliseconds} + { METRIC_STATUS_NAME, reportEntry.Value.Status == HealthStatus.Healthy ? 1 : 0 }, + { METRIC_DURATION_NAME, reportEntry.Value.Duration.TotalMilliseconds } }); } } private static void SaveGeneralizedReport(HealthReport report, TelemetryClient client) { client.TrackEvent(EVENT_NAME, - properties: new Dictionary() + properties: new Dictionary { - {nameof(Environment.MachineName),Environment.MachineName}, - {nameof(Assembly),Assembly.GetEntryAssembly().GetName().Name } + { nameof(Environment.MachineName), Environment.MachineName }, + { nameof(Assembly), Assembly.GetEntryAssembly().GetName().Name } }, - metrics: new Dictionary() + metrics: new Dictionary { - { METRIC_STATUS_NAME ,report.Status == HealthStatus.Healthy ? 1 :0}, - { METRIC_DURATION_NAME,report.TotalDuration.TotalMilliseconds} + { METRIC_STATUS_NAME, report.Status == HealthStatus.Healthy ? 1 : 0 }, + { METRIC_DURATION_NAME, report.TotalDuration.TotalMilliseconds } }); } - TelemetryClient GetOrCreateTelemetryClient() + private TelemetryClient GetOrCreateTelemetryClient() { if (_client == null) { @@ -97,7 +97,6 @@ TelemetryClient GetOrCreateTelemetryClient() ? TelemetryConfiguration.Active : new TelemetryConfiguration(_instrumentationKey); - _client = new TelemetryClient(configuration); } } diff --git a/src/HealthChecks.Publisher.ApplicationInsights/DependencyInjection/ApplicationInsightsHealthCheckBuilderExtensions.cs b/src/HealthChecks.Publisher.ApplicationInsights/DependencyInjection/ApplicationInsightsHealthCheckBuilderExtensions.cs index 4d20551580..e94cab0843 100644 --- a/src/HealthChecks.Publisher.ApplicationInsights/DependencyInjection/ApplicationInsightsHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Publisher.ApplicationInsights/DependencyInjection/ApplicationInsightsHealthCheckBuilderExtensions.cs @@ -3,7 +3,6 @@ namespace Microsoft.Extensions.DependencyInjection { - public static class ApplicationInsightsHealthCheckBuilderExtensions { /// diff --git a/src/HealthChecks.Publisher.Prometheus/DependencyInjection/PrometheusGatewayHealthCheckBuilderExtensions.cs b/src/HealthChecks.Publisher.Prometheus/DependencyInjection/PrometheusGatewayHealthCheckBuilderExtensions.cs index 7a3ae408d5..433ad18e9d 100644 --- a/src/HealthChecks.Publisher.Prometheus/DependencyInjection/PrometheusGatewayHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Publisher.Prometheus/DependencyInjection/PrometheusGatewayHealthCheckBuilderExtensions.cs @@ -1,8 +1,6 @@ -using System.Net.Http; -using HealthChecks.Publisher.Prometheus; +using HealthChecks.Publisher.Prometheus; using Microsoft.Extensions.Diagnostics.HealthChecks; - - +using System.Net.Http; namespace Microsoft.Extensions.DependencyInjection { @@ -12,8 +10,8 @@ public static class PrometheusGatewayHealthCheckBuilderExtensions /// Add a health check publisher for Prometheus Gateway. /// /// - /// For each published a new metric value indicating the health check status ( 2 Healthy, 1 - /// Degraded, 0 Unhealthy) and the total time the health check took to execute on seconds./> + /// For each published a new metric value indicating the health check status (2 Healthy, 1 + /// Degraded, 0 Unhealthy) and the total time the health check took to execute on seconds. /// /// The . /// Endpoint url e.g. http://myendpoint:9091 @@ -28,7 +26,6 @@ public static IHealthChecksBuilder AddPrometheusGatewayPublisher(this IHealthChe return builder; } - internal static IHealthChecksBuilder AddPrometheusGatewayPublisher(this IHealthChecksBuilder builder, HttpClient client, string endpoint, string job, string instance = null) { diff --git a/src/HealthChecks.Publisher.Prometheus/LivenessPrometheusMetrics.cs b/src/HealthChecks.Publisher.Prometheus/LivenessPrometheusMetrics.cs index 5ebe9780e7..798f0a8556 100644 --- a/src/HealthChecks.Publisher.Prometheus/LivenessPrometheusMetrics.cs +++ b/src/HealthChecks.Publisher.Prometheus/LivenessPrometheusMetrics.cs @@ -32,19 +32,17 @@ internal LivenessPrometheusMetrics() Registry = DefaultCollectorRegistry.Instance; } - protected void WriteMetricsFromHealthReport(HealthReport report) { foreach (var reportEntry in report.Entries) { _healthChecksResult.Labels(reportEntry.Key). - Set((double) reportEntry.Value.Status); + Set((double)reportEntry.Value.Status); _healthChecksDuration.Labels(reportEntry.Key) .Set(reportEntry.Value.Duration.TotalSeconds); } } - protected static Stream CollectionToStreamWriter(ICollectorRegistry registry) { var metrics = registry.CollectAll(); diff --git a/src/HealthChecks.Publisher.Prometheus/PrometheusGatewayPublisher.cs b/src/HealthChecks.Publisher.Prometheus/PrometheusGatewayPublisher.cs index 1cebf5317f..5907c680f0 100644 --- a/src/HealthChecks.Publisher.Prometheus/PrometheusGatewayPublisher.cs +++ b/src/HealthChecks.Publisher.Prometheus/PrometheusGatewayPublisher.cs @@ -16,6 +16,8 @@ internal sealed class PrometheusGatewayPublisher : LivenessPrometheusMetrics, IH public PrometheusGatewayPublisher(string endpoint, string job, string instance = null) { + if (endpoint == null) throw new ArgumentNullException(nameof(endpoint)); + var sb = new StringBuilder($"{endpoint.TrimEnd('/')}/job/{job}"); if (!string.IsNullOrEmpty(instance)) @@ -28,26 +30,21 @@ public PrometheusGatewayPublisher(string endpoint, string job, string instance = throw new ArgumentException("Endpoint must be a valid url", nameof(endpoint)); } } - public PrometheusGatewayPublisher(HttpClient httpClient, string endpoint, string job, string instance) : this(endpoint, job, instance) { - _httpClient = httpClient; + _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); } - public void Dispose() { _httpClient?.Dispose(); } - - public async Task PublishAsync(HealthReport report, CancellationToken cancellationToken) { WriteMetricsFromHealthReport(report); await PushMetrics(); } - private async Task PushMetrics() { try diff --git a/src/HealthChecks.Publisher.Prometheus/PrometheusResponseWriter.cs b/src/HealthChecks.Publisher.Prometheus/PrometheusResponseWriter.cs index f70bec49b8..c3215834c6 100644 --- a/src/HealthChecks.Publisher.Prometheus/PrometheusResponseWriter.cs +++ b/src/HealthChecks.Publisher.Prometheus/PrometheusResponseWriter.cs @@ -11,8 +11,8 @@ public sealed class PrometheusResponseWriter : LivenessPrometheusMetrics public static async Task WritePrometheusResultText(HttpContext context, HealthReport report, bool alwaysReturnHttp200Ok = false) { var instance = new PrometheusResponseWriter(); - instance.WriteMetricsFromHealthReport(report); - + instance.WriteMetricsFromHealthReport(report); + using (var resultStream = CollectionToStreamWriter(instance.Registry)) { var content = await new StreamContent(resultStream) diff --git a/src/HealthChecks.Publisher.Seq/DependencyInjection/SeqHealthCheckBuilderExtensions.cs b/src/HealthChecks.Publisher.Seq/DependencyInjection/SeqHealthCheckBuilderExtensions.cs index 99370c0eaf..1ee9c4c84f 100644 --- a/src/HealthChecks.Publisher.Seq/DependencyInjection/SeqHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Publisher.Seq/DependencyInjection/SeqHealthCheckBuilderExtensions.cs @@ -8,13 +8,12 @@ namespace Microsoft.Extensions.DependencyInjection public static class SeqHealthCheckBuilderExtensions { const string NAME = "seq"; - /// /// Add a health check publisher for Seq. /// /// - /// For each published a new metric value indicating the health check status ( 2 Healthy, 1 - /// Degraded, 0 Unhealthy) and the total time the health check took to execute on seconds./> + /// For each published a new metric value indicating the health check status (2 Healthy, 1 + /// Degraded, 0 Unhealthy) and the total time the health check took to execute on seconds. /// /// The . /// The Sql configuration options. diff --git a/src/HealthChecks.Publisher.Seq/SeqPublisher.cs b/src/HealthChecks.Publisher.Seq/SeqPublisher.cs index 9deada3db5..8f73c2c0ab 100644 --- a/src/HealthChecks.Publisher.Seq/SeqPublisher.cs +++ b/src/HealthChecks.Publisher.Seq/SeqPublisher.cs @@ -23,7 +23,7 @@ public class SeqPublisher : IHealthCheckPublisher public SeqPublisher(Func httpClientFactory, SeqOptions options) { - _options = options; + _options = options ?? throw new ArgumentNullException(nameof(options)); _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); } public async Task PublishAsync(HealthReport report, CancellationToken cancellationToken) @@ -46,14 +46,14 @@ public async Task PublishAsync(HealthReport report, CancellationToken cancellati new RawEvent { Timestamp = DateTimeOffset.UtcNow, - MessageTemplate = $"{EVENT_NAME}", + MessageTemplate = EVENT_NAME, Level = level, - Properties = new Dictionary() + Properties = new Dictionary { { nameof(Environment.MachineName), Environment.MachineName }, { nameof(Assembly), Assembly.GetEntryAssembly().GetName().Name }, - { METRIC_STATUS_NAME , (int)report.Status }, - { METRIC_DURATION_NAME,report.TotalDuration.TotalMilliseconds} + { METRIC_STATUS_NAME, (int)report.Status }, + { METRIC_DURATION_NAME, report.TotalDuration.TotalMilliseconds } } } } diff --git a/src/HealthChecks.RabbitMQ/RabbitMQHealthCheck.cs b/src/HealthChecks.RabbitMQ/RabbitMQHealthCheck.cs index d1ebd577e8..d67f0ddd01 100644 --- a/src/HealthChecks.RabbitMQ/RabbitMQHealthCheck.cs +++ b/src/HealthChecks.RabbitMQ/RabbitMQHealthCheck.cs @@ -12,7 +12,6 @@ public class RabbitMQHealthCheck { private readonly string _rabbitMqConnectionString; private readonly SslOption _sslOption; - public RabbitMQHealthCheck(string rabbitMqConnectionString, SslOption sslOption = null) { _rabbitMqConnectionString = rabbitMqConnectionString ?? throw new ArgumentNullException(nameof(rabbitMqConnectionString)); diff --git a/src/HealthChecks.RavenDB/DependencyInjection/RavenDBHealthCheckBuilderExtensions.cs b/src/HealthChecks.RavenDB/DependencyInjection/RavenDBHealthCheckBuilderExtensions.cs index d5f527d925..5a4c5f8a9e 100644 --- a/src/HealthChecks.RavenDB/DependencyInjection/RavenDBHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.RavenDB/DependencyInjection/RavenDBHealthCheckBuilderExtensions.cs @@ -8,7 +8,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class RavenDBHealthCheckBuilderExtensions { const string NAME = "ravendb"; - /// /// /// The . @@ -47,8 +46,6 @@ public static IHealthChecksBuilder AddRavenDB( failureStatus, tags); } - - /// /// Add a health check for RavenDB. /// diff --git a/src/HealthChecks.RavenDB/RavenDBHealthCheck.cs b/src/HealthChecks.RavenDB/RavenDBHealthCheck.cs index 9a8e7fd4d2..987c754374 100644 --- a/src/HealthChecks.RavenDB/RavenDBHealthCheck.cs +++ b/src/HealthChecks.RavenDB/RavenDBHealthCheck.cs @@ -1,63 +1,66 @@ -using Microsoft.Extensions.Diagnostics.HealthChecks; -using Raven.Client.Documents; -using Raven.Client.ServerWide.Operations; -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace HealthChecks.RavenDB -{ - public class RavenDBHealthCheck : IHealthCheck - { - private readonly RavenDBOptions _options; - public RavenDBHealthCheck(RavenDBOptions options) - { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Raven.Client.Documents; +using Raven.Client.ServerWide.Operations; +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace HealthChecks.RavenDB +{ + public class RavenDBHealthCheck : IHealthCheck + { + private readonly RavenDBOptions _options; + public RavenDBHealthCheck(RavenDBOptions options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + if (options.Urls == null) + { + throw new ArgumentNullException(nameof(options.Urls)); } - if (options.Urls == null) - { - throw new ArgumentNullException(nameof(options.Urls)); - } - - _options = options; - } - public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) - { - try - { - using (var store = new DocumentStore - { - Urls = _options.Urls, - }) - { - if (_options.Certificate != null) - { - store.Certificate = _options.Certificate; - } - - store.Initialize(); - - var databases = await store.Maintenance.Server.SendAsync(new GetDatabaseNamesOperation(start: 0, pageSize: 100)); - - if (!string.IsNullOrWhiteSpace(_options.Database) - && !databases.Contains(_options.Database, StringComparer.OrdinalIgnoreCase)) - { - return new HealthCheckResult( - context.Registration.FailureStatus, - $"RavenDB does not contain '{_options.Database}' database."); - } - - return HealthCheckResult.Healthy(); - } - } - catch (Exception ex) - { - return new HealthCheckResult(context.Registration.FailureStatus, exception: ex); - } - } - } -} + _options = options; + } + public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + try + { + using (var store = new DocumentStore + { + Urls = _options.Urls, + }) + { + if (_options.Certificate != null) + { + store.Certificate = _options.Certificate; + } + + store.Initialize(); + + var databases = await store + .Maintenance + .Server + .SendAsync(new GetDatabaseNamesOperation(start: 0, pageSize: 100), cancellationToken); + + if (!string.IsNullOrWhiteSpace(_options.Database) + && !databases.Contains(_options.Database, StringComparer.OrdinalIgnoreCase)) + { + return new HealthCheckResult( + context.Registration.FailureStatus, + $"RavenDB does not contain '{_options.Database}' database."); + } + + return HealthCheckResult.Healthy(); + } + } + catch (Exception ex) + { + return new HealthCheckResult(context.Registration.FailureStatus, exception: ex); + } + } + } +} diff --git a/src/HealthChecks.Redis/RedisHealthCheck.cs b/src/HealthChecks.Redis/RedisHealthCheck.cs index 7d05a3e597..f0a8bef77a 100644 --- a/src/HealthChecks.Redis/RedisHealthCheck.cs +++ b/src/HealthChecks.Redis/RedisHealthCheck.cs @@ -21,16 +21,15 @@ public Task CheckHealthAsync(HealthCheckContext context, Canc { try { - ConnectionMultiplexer connection; - - if (!_connections.TryGetValue(_redisConnectionString, out connection)) + if (!_connections.TryGetValue(_redisConnectionString, out ConnectionMultiplexer connection)) { connection = ConnectionMultiplexer.Connect(_redisConnectionString); if (!_connections.TryAdd(_redisConnectionString, connection)) { - return Task.FromResult( - new HealthCheckResult(context.Registration.FailureStatus, description: "New redis connection can't be added into dictionary.")); + // Dispose new connection which we just created, because we don't need it. + connection.Dispose(); + connection = _connections[_redisConnectionString]; } } diff --git a/src/HealthChecks.SignalR/DependencyInjection/SignalRHealthCheckBuilderExtensions.cs b/src/HealthChecks.SignalR/DependencyInjection/SignalRHealthCheckBuilderExtensions.cs index 7ceeb51c10..27b4c4d4cd 100644 --- a/src/HealthChecks.SignalR/DependencyInjection/SignalRHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.SignalR/DependencyInjection/SignalRHealthCheckBuilderExtensions.cs @@ -9,7 +9,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class SignalRHealthCheckBuilderExtensions { const string NAME = "signalr"; - /// /// Add a health check for SignalR. /// @@ -36,7 +35,6 @@ public static IHealthChecksBuilder AddSignalRHub(this IHealthChecksBuilder build failureStatus, tags)); } - /// /// Add a health check for SignalR. /// diff --git a/src/HealthChecks.SignalR/SignalRHealthCheck.cs b/src/HealthChecks.SignalR/SignalRHealthCheck.cs index abd355b02f..baf8e6929b 100644 --- a/src/HealthChecks.SignalR/SignalRHealthCheck.cs +++ b/src/HealthChecks.SignalR/SignalRHealthCheck.cs @@ -10,10 +10,9 @@ public class SignalRHealthCheck : IHealthCheck { private readonly Func _hubConnectionBuilder; - public SignalRHealthCheck(Func hubConnectionBuilder) { - _hubConnectionBuilder = hubConnectionBuilder; + _hubConnectionBuilder = hubConnectionBuilder ?? throw new ArgumentNullException(nameof(hubConnectionBuilder)); } public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { diff --git a/src/HealthChecks.SqlServer/DependencyInjection/SqlServerHealthCheckBuilderExtensions.cs b/src/HealthChecks.SqlServer/DependencyInjection/SqlServerHealthCheckBuilderExtensions.cs index 93775ee211..c20367f6be 100644 --- a/src/HealthChecks.SqlServer/DependencyInjection/SqlServerHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.SqlServer/DependencyInjection/SqlServerHealthCheckBuilderExtensions.cs @@ -7,7 +7,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class SqlServerHealthCheckBuilderExtensions { const string NAME = "sqlserver"; - /// /// Add a health check for SqlServer services. /// @@ -24,10 +23,10 @@ public static class SqlServerHealthCheckBuilderExtensions public static IHealthChecksBuilder AddSqlServer(this IHealthChecksBuilder builder, string connectionString, string healthQuery = "SELECT 1;", string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { return builder.Add(new HealthCheckRegistration( - name ?? NAME, - sp => new SqlServerHealthCheck(connectionString, healthQuery), - failureStatus, - tags)); + name ?? NAME, + sp => new SqlServerHealthCheck(connectionString, healthQuery), + failureStatus, + tags)); } } } diff --git a/src/HealthChecks.SqlServer/SqlServerHealthCheck.cs b/src/HealthChecks.SqlServer/SqlServerHealthCheck.cs index 2032e1a7c5..b8b962a0a5 100644 --- a/src/HealthChecks.SqlServer/SqlServerHealthCheck.cs +++ b/src/HealthChecks.SqlServer/SqlServerHealthCheck.cs @@ -27,7 +27,7 @@ public async Task CheckHealthAsync(HealthCheckContext context using (var command = connection.CreateCommand()) { command.CommandText = _sql; - await command.ExecuteScalarAsync(); + await command.ExecuteScalarAsync(cancellationToken); } return HealthCheckResult.Healthy(); diff --git a/src/HealthChecks.Sqlite/DependencyInjection/SqliteHealthCheckBuilderExtensions.cs b/src/HealthChecks.Sqlite/DependencyInjection/SqliteHealthCheckBuilderExtensions.cs index 1ac3cabccb..21be45fc16 100644 --- a/src/HealthChecks.Sqlite/DependencyInjection/SqliteHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Sqlite/DependencyInjection/SqliteHealthCheckBuilderExtensions.cs @@ -7,7 +7,6 @@ namespace Microsoft.Extensions.DependencyInjection public static class SqliteHealthCheckBuilderExtensions { const string NAME = "sqlite"; - /// /// Add a health check for Sqlite services. /// diff --git a/src/HealthChecks.Sqlite/SqliteHealthCheck.cs b/src/HealthChecks.Sqlite/SqliteHealthCheck.cs index 9607283c4a..e9cec3b7b0 100644 --- a/src/HealthChecks.Sqlite/SqliteHealthCheck.cs +++ b/src/HealthChecks.Sqlite/SqliteHealthCheck.cs @@ -27,7 +27,7 @@ public async Task CheckHealthAsync(HealthCheckContext context using (var command = connection.CreateCommand()) { command.CommandText = _sql; - await command.ExecuteScalarAsync(); + await command.ExecuteScalarAsync(cancellationToken); } return HealthCheckResult.Healthy(); diff --git a/src/HealthChecks.System/DependencyInjection/SystemHealthCheckBuilderExtensions.cs b/src/HealthChecks.System/DependencyInjection/SystemHealthCheckBuilderExtensions.cs index ab4b07d873..3235f2c31e 100644 --- a/src/HealthChecks.System/DependencyInjection/SystemHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.System/DependencyInjection/SystemHealthCheckBuilderExtensions.cs @@ -12,7 +12,6 @@ public static class SystemHealthCheckBuilderExtensions const string MEMORY_NAME = "privatememory"; const string WORKINGSET_NAME = "workingset"; const string VIRTUALMEMORYSIZE_NAME = "virtualmemory"; - /// /// Add a health check for disk storage. /// @@ -31,12 +30,11 @@ public static IHealthChecksBuilder AddDiskStorageHealthCheck(this IHealthChecksB setup?.Invoke(options); return builder.Add(new HealthCheckRegistration( - name ?? DISK_NAME, - sp => new DiskStorageHealthCheck(options), - failureStatus, - tags)); + name ?? DISK_NAME, + sp => new DiskStorageHealthCheck(options), + failureStatus, + tags)); } - /// /// Add a health check for process private memory. /// @@ -52,12 +50,11 @@ public static IHealthChecksBuilder AddDiskStorageHealthCheck(this IHealthChecksB public static IHealthChecksBuilder AddPrivateMemoryHealthCheck(this IHealthChecksBuilder builder, long maximumMemoryBytes, string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { return builder.Add(new HealthCheckRegistration( - name ?? MEMORY_NAME, - sp => new MaximumValueHealthCheck(maximumMemoryBytes, () => Process.GetCurrentProcess().PrivateMemorySize64), - failureStatus, - tags)); + name ?? MEMORY_NAME, + sp => new MaximumValueHealthCheck(maximumMemoryBytes, () => Process.GetCurrentProcess().PrivateMemorySize64), + failureStatus, + tags)); } - /// /// Add a health check for process working set. /// @@ -73,12 +70,11 @@ public static IHealthChecksBuilder AddPrivateMemoryHealthCheck(this IHealthCheck public static IHealthChecksBuilder AddWorkingSetHealthCheck(this IHealthChecksBuilder builder, long maximumMemoryBytes, string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { return builder.Add(new HealthCheckRegistration( - name ?? WORKINGSET_NAME, - sp => new MaximumValueHealthCheck(maximumMemoryBytes, () => Process.GetCurrentProcess().WorkingSet64), - failureStatus, - tags)); + name ?? WORKINGSET_NAME, + sp => new MaximumValueHealthCheck(maximumMemoryBytes, () => Process.GetCurrentProcess().WorkingSet64), + failureStatus, + tags)); } - /// /// Add a health check for process virtual memory. /// @@ -94,10 +90,10 @@ public static IHealthChecksBuilder AddWorkingSetHealthCheck(this IHealthChecksBu public static IHealthChecksBuilder AddVirtualMemorySizeHealthCheck(this IHealthChecksBuilder builder, long maximumMemoryBytes, string name = default, HealthStatus? failureStatus = default, IEnumerable tags = default) { return builder.Add(new HealthCheckRegistration( - name ?? VIRTUALMEMORYSIZE_NAME, - sp => new MaximumValueHealthCheck(maximumMemoryBytes, () => Process.GetCurrentProcess().VirtualMemorySize64), - failureStatus, - tags)); + name ?? VIRTUALMEMORYSIZE_NAME, + sp => new MaximumValueHealthCheck(maximumMemoryBytes, () => Process.GetCurrentProcess().VirtualMemorySize64), + failureStatus, + tags)); } } } diff --git a/src/HealthChecks.System/DiskStorageHealthCheck.cs b/src/HealthChecks.System/DiskStorageHealthCheck.cs index 63f925c4b6..f89bea88e9 100644 --- a/src/HealthChecks.System/DiskStorageHealthCheck.cs +++ b/src/HealthChecks.System/DiskStorageHealthCheck.cs @@ -21,25 +21,24 @@ public Task CheckHealthAsync(HealthCheckContext context, Canc { var configuredDrives = _options.ConfiguredDrives.Values; - foreach (var item in configuredDrives) + foreach (var (DriveName, MinimumFreeMegabytes) in configuredDrives) { - var systemDriveInfo = GetSystemDriveInfo(item.DriveName); + var (Exists, ActualFreeMegabytes) = GetSystemDriveInfo(DriveName); - if (systemDriveInfo.Exists) + if (Exists) { - if (systemDriveInfo.ActualFreeMegabytes < item.MinimumFreeMegabytes) + if (ActualFreeMegabytes < MinimumFreeMegabytes) { return Task.FromResult( - new HealthCheckResult(context.Registration.FailureStatus, description: $"Minimum configured megabytes for disk {item.DriveName} is {item.MinimumFreeMegabytes} but actual free space are {systemDriveInfo.ActualFreeMegabytes} megabytes")); + new HealthCheckResult(context.Registration.FailureStatus, description: $"Minimum configured megabytes for disk {DriveName} is {MinimumFreeMegabytes} but actual free space are {ActualFreeMegabytes} megabytes")); } } else { return Task.FromResult( - new HealthCheckResult(context.Registration.FailureStatus, description: $"Configured drive {item.DriveName} is not present on system")); + new HealthCheckResult(context.Registration.FailureStatus, description: $"Configured drive {DriveName} is not present on system")); } } - return Task.FromResult( HealthCheckResult.Healthy()); } @@ -49,11 +48,10 @@ public Task CheckHealthAsync(HealthCheckContext context, Canc new HealthCheckResult(context.Registration.FailureStatus, exception: ex)); } } - - private (bool Exists, long ActualFreeMegabytes) GetSystemDriveInfo(string driveName) + private static (bool Exists, long ActualFreeMegabytes) GetSystemDriveInfo(string driveName) { var driveInfo = DriveInfo.GetDrives() - .FirstOrDefault(drive => String.Equals(drive.Name, driveName, StringComparison.InvariantCultureIgnoreCase)); + .FirstOrDefault(drive => string.Equals(drive.Name, driveName, StringComparison.InvariantCultureIgnoreCase)); if (driveInfo != null) { diff --git a/src/HealthChecks.System/DiskStorageLivenessOptions.cs b/src/HealthChecks.System/DiskStorageLivenessOptions.cs index 4dd5be5685..9d7496af23 100644 --- a/src/HealthChecks.System/DiskStorageLivenessOptions.cs +++ b/src/HealthChecks.System/DiskStorageLivenessOptions.cs @@ -5,7 +5,6 @@ namespace HealthChecks.System public class DiskStorageOptions { internal Dictionary ConfiguredDrives { get; } = new Dictionary(); - public DiskStorageOptions AddDrive(string driveName, long minimumFreeMegabytes = 1) { ConfiguredDrives.Add(driveName, (driveName, minimumFreeMegabytes)); diff --git a/src/HealthChecks.System/MaximumValueHealthCheck.cs b/src/HealthChecks.System/MaximumValueHealthCheck.cs index 9c12260a79..2526e391fd 100644 --- a/src/HealthChecks.System/MaximumValueHealthCheck.cs +++ b/src/HealthChecks.System/MaximumValueHealthCheck.cs @@ -9,24 +9,24 @@ public class MaximumValueHealthCheck : IHealthCheck where T : IComparable { - private readonly T maximumValue; - private readonly Func currentValueFunc; + private readonly T _maximumValue; + private readonly Func _currentValueFunc; public MaximumValueHealthCheck(T maximumValue, Func currentValueFunc) { - this.maximumValue = maximumValue; - this.currentValueFunc = currentValueFunc; + _maximumValue = maximumValue; + _currentValueFunc = currentValueFunc ?? throw new ArgumentNullException(nameof(currentValueFunc)); } public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { - var currentValue = currentValueFunc(); + var currentValue = _currentValueFunc(); - if (currentValue.CompareTo(maximumValue) <= 0) + if (currentValue.CompareTo(_maximumValue) <= 0) { return Task.FromResult(HealthCheckResult.Healthy()); } return Task.FromResult( - new HealthCheckResult(context.Registration.FailureStatus, description: $"Maximum={maximumValue}, Current={currentValue}")); + new HealthCheckResult(context.Registration.FailureStatus, description: $"Maximum={_maximumValue}, Current={currentValue}")); } } } diff --git a/src/HealthChecks.UI.Client/HealthChecks.UI.Client.csproj b/src/HealthChecks.UI.Client/HealthChecks.UI.Client.csproj index e91c94cd81..cc2535e4af 100644 --- a/src/HealthChecks.UI.Client/HealthChecks.UI.Client.csproj +++ b/src/HealthChecks.UI.Client/HealthChecks.UI.Client.csproj @@ -5,7 +5,7 @@ $(PackageLicenseUrl) $(PackageProjectUrl) HealthCheck;UI;Client - HealthChecks.UI:Client contains some mandatory abstractions to work with HealthChecks.UI. + HealthChecks.UI.Client contains some mandatory abstractions to work with HealthChecks.UI. $(HealthCheckUIClient) $(RepositoryUrl) $(Company) diff --git a/src/HealthChecks.UI.Client/UIHealthReport.cs b/src/HealthChecks.UI.Client/UIHealthReport.cs index b4f66e2131..a4be361c0a 100644 --- a/src/HealthChecks.UI.Client/UIHealthReport.cs +++ b/src/HealthChecks.UI.Client/UIHealthReport.cs @@ -6,7 +6,7 @@ namespace HealthChecks.UI.Client { /* * Models for UI Client. This models represent a indirection between HealthChecks API and - * UI Client in order to implement some features not present on HealthChecks of substiture + * UI Client in order to implement some features not present on HealthChecks of substitute * some properties etc. */ public class UIHealthReport @@ -29,7 +29,7 @@ public static UIHealthReport CreateFrom(HealthReport report) foreach (var item in report.Entries) { - var entry = new UIHealthReportEntry() + var entry = new UIHealthReportEntry { Data = item.Value.Data, Description = item.Value.Description, @@ -59,7 +59,7 @@ public static UIHealthReport CreateFrom(Exception exception, string entryName = Status = UIHealthStatus.Unhealthy, }; - uiReport.Entries.Add(entryName, new UIHealthReportEntry() + uiReport.Entries.Add(entryName, new UIHealthReportEntry { Exception = exception.Message, Description = exception.Message, diff --git a/src/HealthChecks.UI.Client/UIResponseWriter.cs b/src/HealthChecks.UI.Client/UIResponseWriter.cs index 262d8ed1ca..2d4d9e9fb6 100644 --- a/src/HealthChecks.UI.Client/UIResponseWriter.cs +++ b/src/HealthChecks.UI.Client/UIResponseWriter.cs @@ -10,7 +10,6 @@ namespace HealthChecks.UI.Client public static class UIResponseWriter { const string DEFAULT_CONTENT_TYPE = "application/json"; - public static Task WriteHealthCheckUIResponse(HttpContext httpContext, HealthReport report) { var response = "{}"; diff --git a/src/HealthChecks.UI/ApplicationBuilderExtensions.cs b/src/HealthChecks.UI/ApplicationBuilderExtensions.cs index ff9abcd109..eb4697576b 100644 --- a/src/HealthChecks.UI/ApplicationBuilderExtensions.cs +++ b/src/HealthChecks.UI/ApplicationBuilderExtensions.cs @@ -36,12 +36,12 @@ private static IApplicationBuilder ConfigurePipeline(IApplicationBuilder app, Op private static void EnsureValidApiOptions(Options options) { Action ensureValidPath = (string path, string argument) => - { - if (string.IsNullOrEmpty(path) || !path.StartsWith("/")) - { - throw new ArgumentException("The value for customized path can't be null and need to start with / characater."); - } - }; + { + if (string.IsNullOrEmpty(path) || !path.StartsWith("/")) + { + throw new ArgumentException("The value for customized path can't be null and need to start with / character.", argument); + } + }; ensureValidPath(options.ApiPath, nameof(Options.ApiPath)); ensureValidPath(options.UIPath, nameof(Options.UIPath)); diff --git a/src/HealthChecks.UI/Core/ContentType.cs b/src/HealthChecks.UI/Core/ContentType.cs index e33ac563f4..986aa8d935 100644 --- a/src/HealthChecks.UI/Core/ContentType.cs +++ b/src/HealthChecks.UI/Core/ContentType.cs @@ -13,18 +13,12 @@ internal class ContentType public static Dictionary supportedContent = new Dictionary(StringComparer.InvariantCultureIgnoreCase) { - {"js", JAVASCRIPT }, - {"html", HTML }, - {"css", CSS } + { "js", JAVASCRIPT }, + { "html", HTML }, + { "css", CSS } }; public static string FromExtension(string fileExtension) - { - if (!supportedContent.ContainsKey(fileExtension)) - { - return PLAIN; - } - return supportedContent[fileExtension]; - } + => supportedContent.TryGetValue(fileExtension, out var result) ? result : PLAIN; } } diff --git a/src/HealthChecks.UI/Core/Data/Configuration/HealthCheckConfigurationMap.cs b/src/HealthChecks.UI/Core/Data/Configuration/HealthCheckConfigurationMap.cs index 4a8c61a655..e7c1503b2f 100644 --- a/src/HealthChecks.UI/Core/Data/Configuration/HealthCheckConfigurationMap.cs +++ b/src/HealthChecks.UI/Core/Data/Configuration/HealthCheckConfigurationMap.cs @@ -4,7 +4,7 @@ namespace HealthChecks.UI.Core.Data.Configuration { class HealthCheckConfigurationMap - : IEntityTypeConfiguration< HealthCheckConfiguration> + : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { diff --git a/src/HealthChecks.UI/Core/Data/HealthCheckDbDesignTimeContextFactory.cs b/src/HealthChecks.UI/Core/Data/HealthCheckDbDesignTimeContextFactory.cs index cce264f5a8..d781fc548e 100644 --- a/src/HealthChecks.UI/Core/Data/HealthCheckDbDesignTimeContextFactory.cs +++ b/src/HealthChecks.UI/Core/Data/HealthCheckDbDesignTimeContextFactory.cs @@ -1,8 +1,5 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; -using System; -using System.Collections.Generic; -using System.Text; namespace HealthChecks.UI.Core.Data { diff --git a/src/HealthChecks.UI/Core/Data/HealthCheckStatusHistory.cs b/src/HealthChecks.UI/Core/Data/HealthCheckStatusHistory.cs index 053ff6b639..27d14aa130 100644 --- a/src/HealthChecks.UI/Core/Data/HealthCheckStatusHistory.cs +++ b/src/HealthChecks.UI/Core/Data/HealthCheckStatusHistory.cs @@ -1,5 +1,4 @@ using HealthChecks.UI.Client; -using Microsoft.Extensions.Diagnostics.HealthChecks; using System; namespace HealthChecks.UI.Core.Data diff --git a/src/HealthChecks.UI/Core/Discovery/K8S/Extensions/KubernetesHttpClientExtensions.cs b/src/HealthChecks.UI/Core/Discovery/K8S/Extensions/KubernetesHttpClientExtensions.cs index 448e77b4ea..77d4fd4fd4 100644 --- a/src/HealthChecks.UI/Core/Discovery/K8S/Extensions/KubernetesHttpClientExtensions.cs +++ b/src/HealthChecks.UI/Core/Discovery/K8S/Extensions/KubernetesHttpClientExtensions.cs @@ -28,7 +28,6 @@ internal static void ConfigureKubernetesClient(this HttpClient client, IServiceP client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", options.Token); } } - internal static async Task GetServices(this HttpClient client, string label = "") { var response = await client.GetAsync($"{client.BaseAddress.AbsoluteUri}{KubernetesApiEndpoints.ServicesV1}?labelSelector={label}"); diff --git a/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesAddressFactory.cs b/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesAddressFactory.cs index 8826c88f21..a777c01cc2 100644 --- a/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesAddressFactory.cs +++ b/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesAddressFactory.cs @@ -1,14 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; namespace HealthChecks.UI.Core.Discovery.K8S { internal class KubernetesAddressFactory { private readonly string _healthPath; - public KubernetesAddressFactory(string healthPath) { _healthPath = healthPath; @@ -32,7 +28,6 @@ public string CreateAddress(Service service) return $"http://{address}{port}/{_healthPath}"; } - private string GetLoadBalancerAddress(Service service) { var ingress = service.Status?.LoadBalancer?.Ingress?.FirstOrDefault(); @@ -43,7 +38,6 @@ private string GetLoadBalancerAddress(Service service) return service.Spec.ClusterIP; } - private string GetServicePort(Service service) { string port = string.Empty; diff --git a/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesDiscoveryHostedService.cs b/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesDiscoveryHostedService.cs index ae704f3a51..b7c9347953 100644 --- a/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesDiscoveryHostedService.cs +++ b/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesDiscoveryHostedService.cs @@ -49,22 +49,18 @@ public Task StartAsync(CancellationToken cancellationToken) return Task.CompletedTask; } - public async Task StopAsync(CancellationToken cancellationToken) { await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken)); } - private async Task ExecuteAsync(CancellationToken cancellationToken) { - while (!cancellationToken.IsCancellationRequested) { _logger.LogInformation($"Starting kubernetes service discovery on cluster {_discoveryOptions.ClusterHost}"); using (var scope = _serviceProvider.CreateScope()) { - var livenessDbContext = scope.ServiceProvider.GetRequiredService(); try @@ -90,37 +86,31 @@ private async Task ExecuteAsync(CancellationToken cancellationToken) { _logger.LogError($"Error discovering service {item.Metadata.Name}. It might not be visible"); } - } } catch (Exception ex) { - _logger.LogError(ex, "An error ocurred on kubernetes service discovery"); + _logger.LogError(ex, "An error occurred on kubernetes service discovery"); } } await Task.Delay(_discoveryOptions.RefreshTimeOnSeconds * 1000); } } - bool IsLivenessRegistered(HealthChecksDb livenessDb, string host) { return livenessDb.Configurations .Any(lc => lc.Uri == host); } - bool IsValidHealthChecksStatusCode(HttpStatusCode statusCode) { return statusCode == HttpStatusCode.OK || statusCode == HttpStatusCode.ServiceUnavailable; } - - async Task CallClusterService(string host) { var response = await _clusterServiceClient.GetAsync(host); return response.StatusCode; } - Task RegisterDiscoveredLiveness(HealthChecksDb livenessDb, string host, string name) { livenessDb.Configurations.Add(new HealthCheckConfiguration() @@ -132,6 +122,5 @@ Task RegisterDiscoveredLiveness(HealthChecksDb livenessDb, string host, str return livenessDb.SaveChangesAsync(); } - } } diff --git a/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesResponses.cs b/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesResponses.cs index cf30edce10..49d5bd479f 100644 --- a/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesResponses.cs +++ b/src/HealthChecks.UI/Core/Discovery/K8S/KubernetesResponses.cs @@ -8,38 +8,31 @@ internal class ServiceList [JsonProperty("items")] public Service[] Items { get; set; } = new Service[] { }; } - internal class Service { public Metadata Metadata { get; set; } public Status Status { get; set; } public Spec Spec { get; set; } } - internal class Metadata { - public string Name { get; set; } public string Namespace { get; set; } public string Uid { get; set; } } - internal class LoadBalancer { public Ingress[] Ingress { get; set; } } - internal class Status { public LoadBalancer LoadBalancer { get; set; } } - internal class Ingress { public string Ip { get; set; } public string HostName { get; set; } } - internal class Spec { public List Ports { get; set; } @@ -47,7 +40,6 @@ internal class Spec public PortType PortType { get; set; } public string ClusterIP { get; set; } } - internal class Port { public string Protocol { get; set; } @@ -55,6 +47,5 @@ internal class Port public int PortNumber { get; set; } public int NodePort { get; set; } public int TargetPort { get; set; } - } } diff --git a/src/HealthChecks.UI/Core/Discovery/K8S/PortType.cs b/src/HealthChecks.UI/Core/Discovery/K8S/PortType.cs index b459d489ee..d5ebd1c79f 100644 --- a/src/HealthChecks.UI/Core/Discovery/K8S/PortType.cs +++ b/src/HealthChecks.UI/Core/Discovery/K8S/PortType.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace HealthChecks.UI.Core.Discovery.K8S -{ +namespace HealthChecks.UI.Core.Discovery.K8S +{ internal enum PortType { LoadBalancer, diff --git a/src/HealthChecks.UI/Core/Extensions/UIResourceExtensions.cs b/src/HealthChecks.UI/Core/Extensions/UIResourceExtensions.cs index f0d9a14b12..448bebfdfd 100644 --- a/src/HealthChecks.UI/Core/Extensions/UIResourceExtensions.cs +++ b/src/HealthChecks.UI/Core/Extensions/UIResourceExtensions.cs @@ -1,28 +1,28 @@ -using HealthChecks.UI.Configuration; +using HealthChecks.UI.Configuration; using System; -using System.Collections.Generic; -using System.Linq; - -namespace HealthChecks.UI.Core -{ - internal static class UIResourceExtensions - { - public static UIResource GetMainUI(this IEnumerable resources, Options options) - { - var resource = resources - .Where(r => r.ContentType == ContentType.HTML && r.FileName == Keys.HEALTHCHECKSUI_MAIN_UI_RESOURCE) - .FirstOrDefault(); - - resource.Content = resource.Content - .Replace(Keys.HEALTHCHECKSUI_MAIN_UI_API_TARGET, options.ApiPath.AsRelativeResource()); - - resource.Content = resource.Content - .Replace(Keys.HEALTHCHECKSUI_WEBHOOKS_API_TARGET, options.WebhookPath); - - resource.Content = resource.Content - .Replace(Keys.HEALTHCHECKSUI_RESOURCES_TARGET,options.ResourcesPath.AsRelativeResource()); - - return resource; - } - } -} +using System.Collections.Generic; +using System.Linq; + +namespace HealthChecks.UI.Core +{ + internal static class UIResourceExtensions + { + public static UIResource GetMainUI(this IEnumerable resources, Options options) + { + var resource = resources + .Where(r => r.ContentType == ContentType.HTML && r.FileName == Keys.HEALTHCHECKSUI_MAIN_UI_RESOURCE) + .FirstOrDefault(); + + resource.Content = resource.Content + .Replace(Keys.HEALTHCHECKSUI_MAIN_UI_API_TARGET, options.ApiPath.AsRelativeResource()); + + resource.Content = resource.Content + .Replace(Keys.HEALTHCHECKSUI_WEBHOOKS_API_TARGET, options.WebhookPath); + + resource.Content = resource.Content + .Replace(Keys.HEALTHCHECKSUI_RESOURCES_TARGET,options.ResourcesPath.AsRelativeResource()); + + return resource; + } + } +} diff --git a/src/HealthChecks.UI/Core/HostedService/HealthCheckReportCollector.cs b/src/HealthChecks.UI/Core/HostedService/HealthCheckReportCollector.cs index 78fc5c489d..09c9e9d804 100644 --- a/src/HealthChecks.UI/Core/HostedService/HealthCheckReportCollector.cs +++ b/src/HealthChecks.UI/Core/HostedService/HealthCheckReportCollector.cs @@ -23,6 +23,7 @@ internal class HealthCheckReportCollector private readonly Settings _settings; private readonly HttpClient _httpClient; private readonly ILogger _logger; + public HealthCheckReportCollector( HealthChecksDb db, IHealthCheckFailureNotifier healthCheckFailureNotifier, @@ -192,7 +193,6 @@ private async Task SaveExecutionHistory(HealthCheckConfiguration configuration, DiscoveryService = configuration.DiscoveryService }; - await _db.Executions .AddAsync(execution); } diff --git a/src/HealthChecks.UI/Core/HostedService/HealthCheckReportCollectorHostedService.cs b/src/HealthChecks.UI/Core/HostedService/HealthCheckReportCollectorHostedService.cs index 89ecf4bbff..52531d6c47 100644 --- a/src/HealthChecks.UI/Core/HostedService/HealthCheckReportCollectorHostedService.cs +++ b/src/HealthChecks.UI/Core/HostedService/HealthCheckReportCollectorHostedService.cs @@ -58,7 +58,7 @@ private async Task ExecuteAsync(CancellationToken cancellationToken) var runner = scope.ServiceProvider.GetRequiredService(); await runner.Collect(cancellationToken); - _logger.LogDebug("HealthCheck collector HostedService executed succesfully."); + _logger.LogDebug("HealthCheck collector HostedService executed successfully."); } catch (Exception ex) { diff --git a/src/HealthChecks.UI/Core/Notifications/IHealthCheckFailureNotifier.cs b/src/HealthChecks.UI/Core/Notifications/IHealthCheckFailureNotifier.cs index 42227eccd8..a50e63239a 100644 --- a/src/HealthChecks.UI/Core/Notifications/IHealthCheckFailureNotifier.cs +++ b/src/HealthChecks.UI/Core/Notifications/IHealthCheckFailureNotifier.cs @@ -1,5 +1,4 @@ using HealthChecks.UI.Client; -using System; using System.Threading.Tasks; namespace HealthChecks.UI.Core.Notifications diff --git a/src/HealthChecks.UI/Core/Notifications/WebHookFailureNotifier.cs b/src/HealthChecks.UI/Core/Notifications/WebHookFailureNotifier.cs index e8004bfd20..fdb2bbb4ec 100644 --- a/src/HealthChecks.UI/Core/Notifications/WebHookFailureNotifier.cs +++ b/src/HealthChecks.UI/Core/Notifications/WebHookFailureNotifier.cs @@ -18,6 +18,7 @@ internal class WebHookFailureNotifier private readonly ILogger _logger; private readonly Settings _settings; private readonly HealthChecksDb _db; + public WebHookFailureNotifier(HealthChecksDb db, IOptions settings, ILogger logger) { _db = db ?? throw new ArgumentNullException(nameof(db)); @@ -72,7 +73,6 @@ private async Task IsNotifiedOnWindowTime(string livenessName, bool restor && (DateTime.UtcNow - lastNotification.LastNotified).TotalSeconds < _settings.MinimumSecondsBetweenFailureNotifications; } - private async Task SaveNotification(HealthCheckFailureNotification notification) { if (notification != null) @@ -83,12 +83,11 @@ await _db.Failures await _db.SaveChangesAsync(); } } - private async Task SendRequest(string uri, string name, string payloadContent) { if (uri == null || !Uri.TryCreate(uri, UriKind.Absolute, out Uri webHookUri)) { - _logger.LogWarning($"The web hook notification uri is not stablished or is not an absolute Uri ({name}). Set the webhook uri value on BeatPulse setttings."); + _logger.LogWarning($"The web hook notification uri is not established or is not an absolute Uri ({name}). Set the webhook uri value on BeatPulse settings."); return; } @@ -109,7 +108,6 @@ private async Task SendRequest(string uri, string name, string payloadContent) _logger.LogError($"The failure notification for {name} has not executed successfully.", exception); } } - private string GetFailedMessageFromContent(UIHealthReport healthReport) { var failedChecks = healthReport.Entries.Values @@ -117,7 +115,6 @@ private string GetFailedMessageFromContent(UIHealthReport healthReport) return $"There are at least {failedChecks} HealthChecks failing."; } - private string GetFailedDescriptionsFromContent(UIHealthReport healthReport) { const string JOIN_SYMBOL = "|"; @@ -129,7 +126,6 @@ private string GetFailedDescriptionsFromContent(UIHealthReport healthReport) return failedChecksDescription; } - public void Dispose() { if (_db != null) diff --git a/src/HealthChecks.UI/Core/UIEmbeddedResourcesReader.cs b/src/HealthChecks.UI/Core/UIEmbeddedResourcesReader.cs index 7501f7d8c7..462aa2523b 100644 --- a/src/HealthChecks.UI/Core/UIEmbeddedResourcesReader.cs +++ b/src/HealthChecks.UI/Core/UIEmbeddedResourcesReader.cs @@ -9,10 +9,12 @@ internal class UIEmbeddedResourcesReader : IUIResourcesReader { private readonly Assembly _assembly; + public UIEmbeddedResourcesReader(Assembly assembly) { _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); } + public IEnumerable UIResources { get @@ -21,6 +23,7 @@ public IEnumerable UIResources return ParseEmbeddedResources(embeddedResources); } } + private IEnumerable ParseEmbeddedResources(string[] embeddedFiles) { const char SPLIT_SEPARATOR = '.'; diff --git a/src/HealthChecks.UI/Core/UIResource.cs b/src/HealthChecks.UI/Core/UIResource.cs index 8e72d3fba5..382efd7b47 100644 --- a/src/HealthChecks.UI/Core/UIResource.cs +++ b/src/HealthChecks.UI/Core/UIResource.cs @@ -7,12 +7,14 @@ internal class UIResource public string Content { get; internal set; } public string ContentType { get; } public string FileName { get;} + private UIResource(string fileName, string content, string contentType) { Content = content ?? throw new ArgumentNullException(nameof(content)); ContentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); } + public static UIResource Create(string fileName, string content, string contentType) { return new UIResource(fileName, content, contentType); diff --git a/src/HealthChecks.UI/Core/UIResourceMapper.cs b/src/HealthChecks.UI/Core/UIResourceMapper.cs index 75c8149dae..5432b1773b 100644 --- a/src/HealthChecks.UI/Core/UIResourceMapper.cs +++ b/src/HealthChecks.UI/Core/UIResourceMapper.cs @@ -9,10 +9,12 @@ namespace HealthChecks.UI.Core internal class UIResourcesMapper { private readonly IUIResourcesReader _reader; + public UIResourcesMapper(IUIResourcesReader reader) { _reader = reader ?? throw new ArgumentNullException(nameof(reader)); } + public void Map(IApplicationBuilder app, Options options) { var resources = _reader.UIResources; diff --git a/src/HealthChecks.UI/Middleware/UIWebHooksApiMiddleware.cs b/src/HealthChecks.UI/Middleware/UIWebHooksApiMiddleware.cs index a27d343edc..dbaec0c3ff 100644 --- a/src/HealthChecks.UI/Middleware/UIWebHooksApiMiddleware.cs +++ b/src/HealthChecks.UI/Middleware/UIWebHooksApiMiddleware.cs @@ -15,6 +15,7 @@ public class UIWebHooksApiMiddleware { private readonly JsonSerializerSettings _jsonSerializationSettings; private readonly IServiceScopeFactory _serviceScopeFactory; + public UIWebHooksApiMiddleware(RequestDelegate next, IServiceScopeFactory serviceScopeFactory) { _jsonSerializationSettings = new JsonSerializerSettings() diff --git a/src/HealthChecks.UI/ServiceCollectionExtensions.cs b/src/HealthChecks.UI/ServiceCollectionExtensions.cs index fb108d3bc7..9eeca550f7 100644 --- a/src/HealthChecks.UI/ServiceCollectionExtensions.cs +++ b/src/HealthChecks.UI/ServiceCollectionExtensions.cs @@ -81,6 +81,7 @@ public static IServiceCollection AddHealthChecksUI(this IServiceCollection servi return services; } + static async Task CreateDatabase(IServiceProvider serviceProvider) { var scopeFactory = serviceProvider.GetRequiredService(); @@ -101,7 +102,7 @@ static async Task CreateDatabase(IServiceProvider serviceProvider) var healthCheckConfigurations = settings.Value? .HealthChecks? - .Select(s => new HealthCheckConfiguration() + .Select(s => new HealthCheckConfiguration { Name = s.Name, Uri = s.Uri diff --git a/src/HealthChecks.Uris/DependencyInjection/UrisHealthCheckBuilderExtensions.cs b/src/HealthChecks.Uris/DependencyInjection/UrisHealthCheckBuilderExtensions.cs index 0d31fa0bba..5714140260 100755 --- a/src/HealthChecks.Uris/DependencyInjection/UrisHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.Uris/DependencyInjection/UrisHealthCheckBuilderExtensions.cs @@ -38,6 +38,7 @@ public static IHealthChecksBuilder AddUrlGroup(this IHealthChecksBuilder builder failureStatus, tags)); } + /// /// Add a health check for single uri. /// @@ -68,6 +69,7 @@ public static IHealthChecksBuilder AddUrlGroup(this IHealthChecksBuilder builder failureStatus, tags)); } + /// /// Add a health check for multiple uri's. /// @@ -90,6 +92,7 @@ public static IHealthChecksBuilder AddUrlGroup(this IHealthChecksBuilder builder failureStatus, tags)); } + /// /// Add a health check for multiple uri's. /// @@ -119,6 +122,7 @@ public static IHealthChecksBuilder AddUrlGroup(this IHealthChecksBuilder builder failureStatus, tags)); } + /// /// Add a health check for multiple uri's. /// diff --git a/src/HealthChecks.Uris/UriHealthCheck.cs b/src/HealthChecks.Uris/UriHealthCheck.cs index 170e28460e..220d47b5d3 100644 --- a/src/HealthChecks.Uris/UriHealthCheck.cs +++ b/src/HealthChecks.Uris/UriHealthCheck.cs @@ -11,7 +11,6 @@ public class UriHealthCheck { private readonly UriHealthCheckOptions _options; private readonly Func _httpClientFactory; - public UriHealthCheck(UriHealthCheckOptions options, Func httpClientFactory) { _options = options ?? throw new ArgumentNullException(nameof(options)); @@ -41,9 +40,9 @@ public async Task CheckHealthAsync(HealthCheckContext context var requestMessage = new HttpRequestMessage(method, item.Uri); - foreach (var header in item.Headers) + foreach (var (Name, Value) in item.Headers) { - requestMessage.Headers.Add(header.Name, header.Value); + requestMessage.Headers.Add(Name, Value); } using (var timeoutSource = new CancellationTokenSource(timeout)) diff --git a/src/HealthChecks.Uris/UriHealthCheckOptions.cs b/src/HealthChecks.Uris/UriHealthCheckOptions.cs index 96a624daa1..d9516ace45 100644 --- a/src/HealthChecks.Uris/UriHealthCheckOptions.cs +++ b/src/HealthChecks.Uris/UriHealthCheckOptions.cs @@ -14,7 +14,6 @@ public interface IUriOptions IUriOptions ExpectHttpCodes(int minCodeToExpect, int maxCodeToExpect); IUriOptions AddCustomHeader(string name, string value); } - public class UriOptions : IUriOptions { public HttpMethod HttpMethod { get; private set; } @@ -32,47 +31,37 @@ public class UriOptions : IUriOptions public UriOptions(Uri uri) { Uri = uri; - ExpectedHttpCodes = null; - HttpMethod = null; - Timeout = TimeSpan.Zero; } - public IUriOptions AddCustomHeader(string name, string value) { _headers.Add((name, value)); return this; } - IUriOptions IUriOptions.UseGet() { HttpMethod = HttpMethod.Get; return this; } - IUriOptions IUriOptions.UsePost() { HttpMethod = HttpMethod.Post; return this; } - IUriOptions IUriOptions.ExpectHttpCode(int codeToExpect) { ExpectedHttpCodes = (codeToExpect, codeToExpect); return this; } - IUriOptions IUriOptions.ExpectHttpCodes(int minCodeToExpect, int maxCodeToExpect) { ExpectedHttpCodes = (minCodeToExpect, maxCodeToExpect); return this; } - IUriOptions IUriOptions.UseHttpMethod(HttpMethod methodToUse) { HttpMethod = methodToUse; return this; } - IUriOptions IUriOptions.UseTimeout(TimeSpan timeout) { Timeout = timeout; @@ -83,28 +72,22 @@ IUriOptions IUriOptions.UseTimeout(TimeSpan timeout) public class UriHealthCheckOptions { private readonly List _urisOptions = new List(); - internal IEnumerable UrisOptions => _urisOptions; - internal HttpMethod HttpMethod { get; private set; } - internal TimeSpan Timeout { get; private set; } - internal (int Min, int Max) ExpectedHttpCodes { get; private set; } public UriHealthCheckOptions() { - ExpectedHttpCodes = (200, 299); // DEFAULT = HTTP Succesful status codes + ExpectedHttpCodes = (200, 299); // DEFAULT = HTTP Successful status codes HttpMethod = HttpMethod.Get; Timeout = TimeSpan.FromSeconds(10); } - public UriHealthCheckOptions UseGet() { HttpMethod = HttpMethod.Get; return this; } - public UriHealthCheckOptions UsePost() { HttpMethod = HttpMethod.Post; @@ -116,13 +99,11 @@ public UriHealthCheckOptions UseHttpMethod(HttpMethod methodToUse) HttpMethod = methodToUse; return this; } - public UriHealthCheckOptions UseTimeout(TimeSpan timeout) { Timeout = timeout; return this; } - public UriHealthCheckOptions AddUri(Uri uriToAdd, Action setup = null) { var uri = new UriOptions(uriToAdd); @@ -132,19 +113,16 @@ public UriHealthCheckOptions AddUri(Uri uriToAdd, Action setup = nu return this; } - public UriHealthCheckOptions ExpectHttpCode(int codeToExpect) { ExpectedHttpCodes = (codeToExpect, codeToExpect); return this; } - public UriHealthCheckOptions ExpectHttpCodes(int minCodeToExpect, int maxCodeToExpect) { ExpectedHttpCodes = (minCodeToExpect, maxCodeToExpect); return this; } - internal static UriHealthCheckOptions CreateFromUris(IEnumerable uris) { var options = new UriHealthCheckOptions(); diff --git a/test/FunctionalTests/HealthCheck.Network/ImapHealthCheckTests.cs b/test/FunctionalTests/HealthCheck.Network/ImapHealthCheckTests.cs index 69c87282d8..85f2b2aa53 100644 --- a/test/FunctionalTests/HealthCheck.Network/ImapHealthCheckTests.cs +++ b/test/FunctionalTests/HealthCheck.Network/ImapHealthCheckTests.cs @@ -20,9 +20,9 @@ public class imap_healthcheck_should private readonly ExecutionFixture _fixture; //Host and login account to fast switch tests against different server - private string _host = "localhost"; - private string _validAccount = "admin@healthchecks.com"; - private string _validPassword = "beatpulse"; + private const string _host = "localhost"; + private const string _validAccount = "admin@healthchecks.com"; + private const string _validPassword = "beatpulse"; public imap_healthcheck_should(ExecutionFixture fixture) { diff --git a/test/FunctionalTests/HealthCheck.Network/PingHealthCheckTests.cs b/test/FunctionalTests/HealthCheck.Network/PingHealthCheckTests.cs index ba0d2ca49c..d5246f6843 100644 --- a/test/FunctionalTests/HealthCheck.Network/PingHealthCheckTests.cs +++ b/test/FunctionalTests/HealthCheck.Network/PingHealthCheckTests.cs @@ -20,7 +20,7 @@ public class ping_healthcheck_should public ping_healthcheck_should(ExecutionFixture fixture) { - _fixture = fixture ?? throw new ArgumentNullException(nameof(fixture)); ; + _fixture = fixture ?? throw new ArgumentNullException(nameof(fixture)); } [Fact] diff --git a/test/FunctionalTests/HealthCheck.Network/SmtpHealthCheckTests.cs b/test/FunctionalTests/HealthCheck.Network/SmtpHealthCheckTests.cs index 6ef6cf024c..c4e5ebdc1f 100644 --- a/test/FunctionalTests/HealthCheck.Network/SmtpHealthCheckTests.cs +++ b/test/FunctionalTests/HealthCheck.Network/SmtpHealthCheckTests.cs @@ -19,9 +19,9 @@ public class smtp_healthcheck_should private readonly ExecutionFixture _fixture; //Host and login account to fast switch tests against different server - private string _host = "localhost"; - private string _validAccount = "admin@healthchecks.com"; - private string _validPassword = "beatpulse"; + private const string _host = "localhost"; + private const string _validAccount = "admin@healthchecks.com"; + private const string _validPassword = "beatpulse"; public smtp_healthcheck_should(ExecutionFixture fixture) { diff --git a/test/FunctionalTests/HealthChecks.System/DiskStorageHealthCheckTests.cs b/test/FunctionalTests/HealthChecks.System/DiskStorageHealthCheckTests.cs index fd7b60d57b..ec08d063e8 100644 --- a/test/FunctionalTests/HealthChecks.System/DiskStorageHealthCheckTests.cs +++ b/test/FunctionalTests/HealthChecks.System/DiskStorageHealthCheckTests.cs @@ -22,7 +22,7 @@ public class disk_storage_healthcheck_should public disk_storage_healthcheck_should(ExecutionFixture fixture) { - _fixture = fixture ?? throw new ArgumentNullException(nameof(fixture)); ; + _fixture = fixture ?? throw new ArgumentNullException(nameof(fixture)); } [Fact]