generated from dailydevops/dotnet-template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Added `Azure.Blobs` * chore: Additional Blob related changes * chore: Added missing test * fix: Parallelization of the tests so that we obtain uniform test results. * chore: Added tests for Mode `SharedKey` * fix: Removed whitespace terror * chore: Simplified blob implementation and tests * chore: Polished xml summaries * fix: Mark `.Tests.Integration` Assemblies with `CollectionBehavior(CollectionBehavior.CollectionPerAssembly)` * fix: Added missing packages * style: Updated formatting * fix: `new-project.ps1` * chore: Renamed `ClientCreationMode` into `BlobClientCreationMode` * fix: Namespaces * feat: Added `NetEvolve.HealthChecks.Azure.Queues` * fix(style): Reformatted files * fix: Renamed `QueueName` * fix: Further renames * chore: Recreated test files * fix: GNARF Kafka/Redpanda * chore: Renamed * feat: Added `NetEvolve.HealthChecks.Azure.Tables` * fix: whitespace formatting
- Loading branch information
Showing
143 changed files
with
7,404 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ks.Abstractions/src/NetEvolve.HealthChecks.Abstractions/IHealthChecksBuilderExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
...HealthChecks.Azure.Blobs/src/NetEvolve.HealthChecks.Azure.Blobs/BlobClientCreationMode.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
namespace NetEvolve.HealthChecks.Azure.Blobs; | ||
|
||
using System; | ||
using global::Azure.Identity; | ||
using global::Azure.Storage.Blobs; | ||
|
||
/// <summary> | ||
/// Describes the mode used to create the <see cref="BlobServiceClient"/>. | ||
/// </summary> | ||
public enum BlobClientCreationMode | ||
{ | ||
/// <summary> | ||
/// The default mode. The <see cref="BlobServiceClient"/> is loading the preregistered instance from the <see cref="IServiceProvider"/>. | ||
/// </summary> | ||
ServiceProvider = 0, | ||
|
||
/// <summary> | ||
/// The <see cref="BlobServiceClient"/> is created using the <see cref="DefaultAzureCredential"/>. | ||
/// </summary> | ||
DefaultAzureCredentials = 1, | ||
|
||
/// <summary> | ||
/// The <see cref="BlobServiceClient"/> is created using the <see cref="BlobContainerAvailableOptions.ConnectionString"/>. | ||
/// </summary> | ||
ConnectionString = 2, | ||
|
||
/// <summary> | ||
/// The <see cref="BlobServiceClient"/> is created using the <see cref="BlobContainerAvailableOptions.AccountName"/> | ||
/// and <see cref="BlobContainerAvailableOptions.AccountKey"/>. As well as the <see cref="BlobContainerAvailableOptions.ServiceUri"/>. | ||
/// </summary> | ||
SharedKey = 3, | ||
|
||
/// <summary> | ||
/// The <see cref="BlobServiceClient"/> is created using the <see cref="BlobContainerAvailableOptions.ServiceUri"/>. | ||
/// </summary> | ||
AzureSasCredential = 4 | ||
} |
182 changes: 182 additions & 0 deletions
182
...cks.Azure.Blobs/src/NetEvolve.HealthChecks.Azure.Blobs/BlobContainerAvailableConfigure.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
namespace NetEvolve.HealthChecks.Azure.Blobs; | ||
|
||
using System; | ||
using System.Threading; | ||
using global::Azure.Storage.Blobs; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Options; | ||
using NetEvolve.Arguments; | ||
using static Microsoft.Extensions.Options.ValidateOptionsResult; | ||
|
||
internal sealed class BlobContainerAvailableConfigure | ||
: IConfigureNamedOptions<BlobContainerAvailableOptions>, | ||
IValidateOptions<BlobContainerAvailableOptions> | ||
{ | ||
private readonly IConfiguration _configuration; | ||
private readonly IServiceProvider _serviceProvider; | ||
|
||
public BlobContainerAvailableConfigure( | ||
IConfiguration configuration, | ||
IServiceProvider serviceProvider | ||
) | ||
{ | ||
_configuration = configuration; | ||
_serviceProvider = serviceProvider; | ||
} | ||
|
||
public void Configure(string? name, BlobContainerAvailableOptions options) | ||
{ | ||
Argument.ThrowIfNullOrWhiteSpace(name); | ||
_configuration.Bind($"HealthChecks:AzureBlobContainer:{name}", options); | ||
} | ||
|
||
public void Configure(BlobContainerAvailableOptions options) => | ||
Configure(Options.DefaultName, options); | ||
|
||
public ValidateOptionsResult Validate(string? name, BlobContainerAvailableOptions options) | ||
{ | ||
if (string.IsNullOrWhiteSpace(name)) | ||
{ | ||
return Fail("The name cannot be null or whitespace."); | ||
} | ||
|
||
if (options is null) | ||
{ | ||
return Fail("The option cannot be null."); | ||
} | ||
|
||
if (options.Timeout < Timeout.Infinite) | ||
{ | ||
return Fail("The timeout cannot be less than infinite (-1)."); | ||
} | ||
|
||
if (string.IsNullOrWhiteSpace(options.ContainerName)) | ||
{ | ||
return Fail("The container name cannot be null or whitespace."); | ||
} | ||
|
||
var mode = options.Mode; | ||
|
||
return options.Mode switch | ||
{ | ||
BlobClientCreationMode.ServiceProvider => ValidateModeServiceProvider(), | ||
BlobClientCreationMode.ConnectionString => ValidateModeConnectionString(options), | ||
BlobClientCreationMode.DefaultAzureCredentials | ||
=> ValidateModeDefaultAzureCredentials(options), | ||
BlobClientCreationMode.SharedKey => ValidateModeSharedKey(options), | ||
BlobClientCreationMode.AzureSasCredential => ValidateModeAzureSasCredential(options), | ||
_ => Fail($"The mode `{mode}` is not supported."), | ||
}; | ||
} | ||
|
||
private static ValidateOptionsResult ValidateModeAzureSasCredential( | ||
BlobContainerAvailableOptions options | ||
) | ||
{ | ||
if (options.ServiceUri is null) | ||
{ | ||
return Fail( | ||
$"The service url cannot be null when using `{nameof(BlobClientCreationMode.AzureSasCredential)}` mode." | ||
); | ||
} | ||
|
||
if (!options.ServiceUri.IsAbsoluteUri) | ||
{ | ||
return Fail( | ||
$"The service url must be an absolute url when using `{nameof(BlobClientCreationMode.AzureSasCredential)}` mode." | ||
); | ||
} | ||
|
||
if (string.IsNullOrWhiteSpace(options.ServiceUri.Query)) | ||
{ | ||
return Fail( | ||
$"The sas query token cannot be null or whitespace when using `{nameof(BlobClientCreationMode.AzureSasCredential)}` mode." | ||
); | ||
} | ||
|
||
return Success; | ||
} | ||
|
||
private static ValidateOptionsResult ValidateModeSharedKey( | ||
BlobContainerAvailableOptions options | ||
) | ||
{ | ||
if (options.ServiceUri is null) | ||
{ | ||
return Fail( | ||
$"The service url cannot be null when using `{nameof(BlobClientCreationMode.SharedKey)}` mode." | ||
); | ||
} | ||
|
||
if (!options.ServiceUri.IsAbsoluteUri) | ||
{ | ||
return Fail( | ||
$"The service url must be an absolute url when using `{nameof(BlobClientCreationMode.SharedKey)}` mode." | ||
); | ||
} | ||
|
||
if (string.IsNullOrWhiteSpace(options.AccountName)) | ||
{ | ||
return Fail( | ||
$"The account name cannot be null or whitespace when using `{nameof(BlobClientCreationMode.SharedKey)}` mode." | ||
); | ||
} | ||
|
||
if (string.IsNullOrWhiteSpace(options.AccountKey)) | ||
{ | ||
return Fail( | ||
$"The account key cannot be null or whitespace when using `{nameof(BlobClientCreationMode.SharedKey)}` mode." | ||
); | ||
} | ||
|
||
return Success; | ||
} | ||
|
||
private static ValidateOptionsResult ValidateModeDefaultAzureCredentials( | ||
BlobContainerAvailableOptions options | ||
) | ||
{ | ||
if (options.ServiceUri is null) | ||
{ | ||
return Fail( | ||
$"The service url cannot be null when using `{nameof(BlobClientCreationMode.DefaultAzureCredentials)}` mode." | ||
); | ||
} | ||
|
||
if (!options.ServiceUri.IsAbsoluteUri) | ||
{ | ||
return Fail( | ||
$"The service url must be an absolute url when using `{nameof(BlobClientCreationMode.DefaultAzureCredentials)}` mode." | ||
); | ||
} | ||
|
||
return Success; | ||
} | ||
|
||
private static ValidateOptionsResult ValidateModeConnectionString( | ||
BlobContainerAvailableOptions options | ||
) | ||
{ | ||
if (string.IsNullOrWhiteSpace(options.ConnectionString)) | ||
{ | ||
return Fail( | ||
$"The connection string cannot be null or whitespace when using `{nameof(BlobClientCreationMode.ConnectionString)}` mode." | ||
); | ||
} | ||
|
||
return Success; | ||
} | ||
|
||
private ValidateOptionsResult ValidateModeServiceProvider() | ||
{ | ||
if (_serviceProvider.GetService<BlobServiceClient>() is null) | ||
{ | ||
return Fail( | ||
$"No service of type `{nameof(BlobServiceClient)}` registered. Please execute `builder.AddAzureClients()`." | ||
); | ||
} | ||
|
||
return Success; | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
...s.Azure.Blobs/src/NetEvolve.HealthChecks.Azure.Blobs/BlobContainerAvailableHealthCheck.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
namespace NetEvolve.HealthChecks.Azure.Blobs; | ||
|
||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Diagnostics.HealthChecks; | ||
using Microsoft.Extensions.Options; | ||
using NetEvolve.Extensions.Tasks; | ||
using NetEvolve.HealthChecks.Abstractions; | ||
|
||
internal sealed class BlobContainerAvailableHealthCheck | ||
: ConfigurableHealthCheckBase<BlobContainerAvailableOptions> | ||
{ | ||
private readonly IServiceProvider _serviceProvider; | ||
|
||
public BlobContainerAvailableHealthCheck( | ||
IServiceProvider serviceProvider, | ||
IOptionsMonitor<BlobContainerAvailableOptions> optionsMonitor | ||
) | ||
: base(optionsMonitor) => _serviceProvider = serviceProvider; | ||
|
||
protected override async ValueTask<HealthCheckResult> ExecuteHealthCheckAsync( | ||
string name, | ||
HealthStatus failureStatus, | ||
BlobContainerAvailableOptions options, | ||
CancellationToken cancellationToken | ||
) | ||
{ | ||
var blobClient = ClientCreation.GetBlobServiceClient(name, options, _serviceProvider); | ||
|
||
var blobTask = blobClient | ||
.GetBlobContainersAsync(cancellationToken: cancellationToken) | ||
.AsPages(pageSizeHint: 1) | ||
.GetAsyncEnumerator(cancellationToken) | ||
.MoveNextAsync(); | ||
|
||
var (isValid, result) = await blobTask | ||
.WithTimeoutAsync(options.Timeout, cancellationToken) | ||
.ConfigureAwait(false); | ||
|
||
var container = blobClient.GetBlobContainerClient(options.ContainerName); | ||
|
||
var containerExists = await container.ExistsAsync(cancellationToken).ConfigureAwait(false); | ||
if (!containerExists) | ||
{ | ||
return HealthCheckResult.Unhealthy( | ||
$"{name}: Container `{options.ContainerName}` does not exist." | ||
); | ||
} | ||
|
||
(var containerInTime, _) = await container | ||
.GetPropertiesAsync(cancellationToken: cancellationToken) | ||
.WithTimeoutAsync(options.Timeout, cancellationToken) | ||
.ConfigureAwait(false); | ||
|
||
return (isValid && result && containerInTime) | ||
? HealthCheckResult.Healthy($"{name}: Healthy") | ||
: HealthCheckResult.Degraded($"{name}: Degraded"); | ||
} | ||
} |
Oops, something went wrong.