diff --git a/BuildingBlocks/src/BuildingBlocks.Infrastructure/BuildingBlocks.Infrastructure.csproj b/BuildingBlocks/src/BuildingBlocks.Infrastructure/BuildingBlocks.Infrastructure.csproj
index bd7e3e2076..cfddde7c78 100644
--- a/BuildingBlocks/src/BuildingBlocks.Infrastructure/BuildingBlocks.Infrastructure.csproj
+++ b/BuildingBlocks/src/BuildingBlocks.Infrastructure/BuildingBlocks.Infrastructure.csproj
@@ -11,6 +11,7 @@
+
diff --git a/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/BlobStorage/BlobStorageHealthCheck.cs b/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/BlobStorage/BlobStorageHealthCheck.cs
new file mode 100644
index 0000000000..b6cf815560
--- /dev/null
+++ b/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/BlobStorage/BlobStorageHealthCheck.cs
@@ -0,0 +1,82 @@
+using System.Text;
+using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.BlobStorage;
+using Backbone.Tooling.Extensions;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+
+namespace Backbone.BuildingBlocks.Infrastructure.Persistence.BlobStorage;
+
+public class BlobStorageHealthCheck : IHealthCheck
+{
+ private const string FILE_TEXT = "healthcheck";
+ private const int MAX_NUMBER_OF_TRIES = 5;
+
+ private static bool? _isHealthy;
+ private static int _numberOfTries;
+
+ private readonly IBlobStorage _storage;
+ private readonly string _bucketName;
+
+ public BlobStorageHealthCheck(IBlobStorage storage, string bucketName)
+ {
+ _storage = storage;
+ _bucketName = bucketName;
+ }
+
+ public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
+ {
+ if (!_isHealthy.HasValue || (_isHealthy == false && _numberOfTries < MAX_NUMBER_OF_TRIES))
+ {
+ var filename = Guid.NewGuid().ToString();
+ var isUploadPossible = await IsUploadPossible(filename);
+ var isDownloadPossible = await IsDownloadPossible(filename);
+ var isDeletionPossible = await IsDeletionPossible(filename);
+
+ _isHealthy = isUploadPossible && isDownloadPossible && isDeletionPossible;
+ _numberOfTries++;
+ }
+
+ return _isHealthy.Value ? HealthCheckResult.Healthy() : HealthCheckResult.Unhealthy();
+ }
+
+ private async Task IsUploadPossible(string filename)
+ {
+ try
+ {
+ _storage.Add(_bucketName, filename, FILE_TEXT.GetBytes());
+ await _storage.SaveAsync();
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
+ private async Task IsDownloadPossible(string filename)
+ {
+ try
+ {
+ var downloadBytes = await _storage.FindAsync(_bucketName, filename);
+ var downloadedString = Encoding.UTF8.GetString(downloadBytes);
+ return downloadedString == FILE_TEXT;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
+ private async Task IsDeletionPossible(string filename)
+ {
+ try
+ {
+ _storage.Remove(_bucketName, filename);
+ await _storage.SaveAsync();
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+}
diff --git a/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/BlobStorage/BlobStorageServiceCollectionExtensions.cs b/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/BlobStorage/BlobStorageServiceCollectionExtensions.cs
index e6ece37294..f6c9c85826 100644
--- a/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/BlobStorage/BlobStorageServiceCollectionExtensions.cs
+++ b/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/BlobStorage/BlobStorageServiceCollectionExtensions.cs
@@ -1,7 +1,9 @@
+using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.BlobStorage;
using Backbone.BuildingBlocks.Infrastructure.Persistence.BlobStorage.AzureStorageAccount;
using Backbone.BuildingBlocks.Infrastructure.Persistence.BlobStorage.GoogleCloudStorage;
using Backbone.Tooling.Extensions;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace Backbone.BuildingBlocks.Infrastructure.Persistence.BlobStorage;
@@ -41,6 +43,14 @@ public static void AddBlobStorage(this IServiceCollection services, BlobStorageO
$"{options.CloudProvider} is not a currently supported cloud provider.");
}
}
+
+ services.AddHealthChecks().Add(
+ new HealthCheckRegistration(
+ "blob_storage",
+ sp => new BlobStorageHealthCheck(sp.GetRequiredService(), options.Container),
+ HealthStatus.Unhealthy, null
+ )
+ );
}
}