Skip to content

Commit

Permalink
Storage service extension for health check service (#46) (#47)
Browse files Browse the repository at this point in the history
* Add health check for MinIO
* Update packages & licenses

Signed-off-by: Victor Chang <[email protected]>

Signed-off-by: Victor Chang <[email protected]>
  • Loading branch information
mocsharp authored Aug 30, 2022
1 parent 5519a23 commit a746587
Show file tree
Hide file tree
Showing 30 changed files with 461 additions and 448 deletions.
1 change: 1 addition & 0 deletions .licenserc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ header:
- '**/*.ruleset'
- 'src/.sonarlint/**'
- 'src/coverlet.runsettings'
- 'src/Monai.Deploy.Storage.sln'

comment: on-failure

Expand Down
64 changes: 25 additions & 39 deletions doc/dependency_decisions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,22 @@
- :who: mocsharp
:why: Apache-2.0 (https://github.com/aws/aws-sdk-net/raw/master/License.txt)
:versions:
- 3.7.12
:when: 2022-08-16 18:10:42.589246033 Z
- - :approve
- AWSSDK.Core
- :who: mocsharp
:why: Apache-2.0 (https://github.com/aws/aws-sdk-net/raw/master/License.txt)
:versions:
- 3.7.12.21
:when: 2022-08-16 18:11:12.923214877 Z
- 3.7.12.26
:when: 2022-08-29 18:11:12.923214877 Z
- - :approve
- AWSSDK.S3
- :who: mocsharp
:why: Apache-2.0 (https://github.com/aws/aws-sdk-net/raw/master/License.txt)
:versions:
- 3.7.9.39
:when: 2022-08-16 18:11:13.354973002 Z
- 3.7.9.44
:when: 2022-08-29 18:11:13.354973002 Z
- - :approve
- AWSSDK.SecurityToken
- :who: mocsharp
:why: Apache-2.0 (https://github.com/aws/aws-sdk-net/raw/master/License.txt)
:versions:
- 3.7.1.165
- 3.7.1.190
:when: 2022-08-16 18:11:13.781079769 Z
- - :approve
- AWSSDK.SecurityToken
- :who: mocsharp
:why: Apache-2.0 (https://github.com/aws/aws-sdk-net/raw/master/License.txt)
:versions:
- 3.7.1.185
:when: 2022-08-16 18:11:14.209852227 Z
- - :approve
- Ardalis.GuardClauses
- :who: mocsharp
Expand Down Expand Up @@ -81,15 +67,8 @@
- :who: mocsharp
:why: MIT (https://github.com/microsoft/vstest/raw/v17.3.0/LICENSE)
:versions:
- 17.3.0
- 17.3.1
:when: 2022-08-16 18:11:17.245887971 Z
- - :approve
- Microsoft.CodeCoverage
- :who: mocsharp
:why: MIT (https://github.com/microsoft/vstest/raw/v17.3.0/LICENSE)
:versions:
- 17.3.0
:when: 2022-08-16 18:11:17.665958106 Z
- - :approve
- Microsoft.Extensions.Configuration
- :who: mocsharp
Expand Down Expand Up @@ -160,6 +139,20 @@
:versions:
- 6.0.0
:when: 2022-08-16 18:11:22.090772006 Z
- - :approve
- Microsoft.Extensions.Diagnostics.HealthChecks
- :who: mocsharp
:why: MIT (https://github.com/dotnet/aspnetcore/raw/main/LICENSE.txt)
:versions:
- 6.0.8
:when: 2022-08-29 18:11:22.090772006 Z
- - :approve
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions
- :who: mocsharp
:why: MIT (https://github.com/dotnet/aspnetcore/raw/main/LICENSE.txt)
:versions:
- 6.0.8
:when: 2022-08-29 18:11:22.090772006 Z
- - :approve
- Microsoft.Extensions.FileProviders.Abstractions
- :who: mocsharp
Expand Down Expand Up @@ -207,8 +200,8 @@
- :who: mocsharp
:why: MIT (https://github.com/dotnet/runtime/raw/main/LICENSE.TXT)
:versions:
- 6.0.0
:when: 2022-08-16 18:11:25.167886026 Z
- 6.0.1
:when: 2022-08-29 18:11:25.167886026 Z
- - :approve
- Microsoft.Extensions.Logging.Configuration
- :who: mocsharp
Expand Down Expand Up @@ -270,15 +263,8 @@
- :who: mocsharp
:why: MIT (https://github.com/microsoft/vstest/raw/v17.3.0/LICENSE)
:versions:
- 17.3.0
- 17.3.1
:when: 2022-08-16 18:11:29.155295778 Z
- - :approve
- Microsoft.NET.Test.Sdk
- :who: mocsharp
:why: MIT (https://github.com/microsoft/vstest/raw/v17.3.0/LICENSE)
:versions:
- 17.3.0
:when: 2022-08-16 18:11:29.588968034 Z
- - :approve
- Microsoft.NETCore.Platforms
- :who: mocsharp
Expand Down Expand Up @@ -312,14 +298,14 @@
- :who: mocsharp
:why: MIT (https://github.com/microsoft/vstest/raw/v17.3.0/LICENSE)
:versions:
- 17.3.0
- 17.3.1
:when: 2022-08-16 18:11:32.293966383 Z
- - :approve
- Microsoft.TestPlatform.TestHost
- :who: mocsharp
:why: MIT (https://github.com/microsoft/vstest/raw/v17.3.0/LICENSE)
:versions:
- 17.3.0
- 17.3.1
:when: 2022-08-16 18:11:33.162650175 Z
- - :approve
- Microsoft.Win32.Primitives
Expand Down
16 changes: 0 additions & 16 deletions src/Monai.Deploy.Storage.sln
Original file line number Diff line number Diff line change
@@ -1,20 +1,4 @@
Microsoft Visual Studio Solution File, Format Version 12.00
<!--
~ Copyright 2022 MONAI Consortium
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

# Visual Studio Version 17
VisualStudioVersion = 17.1.32210.238
MinimumVisualStudioVersion = 10.0.40219.1
Expand Down
6 changes: 3 additions & 3 deletions src/Plugins/AWSS3/Monai.Deploy.Storage.AWSS3.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--
<!--
~ Copyright 2022 MONAI Consortium
~
~ Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -49,8 +49,8 @@

<ItemGroup>
<PackageReference Include="Ardalis.GuardClauses" Version="4.0.1" />
<PackageReference Include="AWSSDK.S3" Version="3.7.9.39" />
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.1.185" />
<PackageReference Include="AWSSDK.S3" Version="3.7.9.44" />
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.1.190" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
Expand Down
4 changes: 0 additions & 4 deletions src/Plugins/AWSS3/ServiceRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ namespace Monai.Deploy.Storage.AWSS3
{
public class ServiceRegistration : ServiceRegistrationBase
{
public ServiceRegistration(string fullyQualifiedAssemblyName) : base(fullyQualifiedAssemblyName)
{
}

public override IServiceCollection Configure(IServiceCollection services)
{
services.AddSingleton<IStorageService, Awss3StorageService>();
Expand Down
2 changes: 2 additions & 0 deletions src/Plugins/AWSS3/StorageAdminService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ namespace Monai.Deploy.Storage.AWSS3
public class StorageAdminService : IStorageAdminService
{
public Task<Credentials> CreateUserAsync(string username, AccessPermissions permissions, string[] bucketNames) => throw new NotImplementedException();

public Task<Credentials> CreateUserAsync(string username, PolicyRequest[] policyRequests) => throw new NotImplementedException();

public Task RemoveUserAsync(string username) => throw new NotImplementedException();
}
}
2 changes: 2 additions & 0 deletions src/Plugins/MinIO/ConfigurationKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ namespace Monai.Deploy.Storage.MinIO
{
internal static class ConfigurationKeys
{
public static readonly string StorageServiceName = "minio";

public static readonly string EndPoint = "endpoint";
public static readonly string AccessKey = "accessKey";
public static readonly string AccessToken = "accessToken";
Expand Down
45 changes: 45 additions & 0 deletions src/Plugins/MinIO/HealthCheckBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2022 MONAI Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;

namespace Monai.Deploy.Storage.MinIO
{
public class HealthCheckBuilder : HealthCheckRegistrationBase
{
public override IHealthChecksBuilder Configure(
IHealthChecksBuilder builder,
HealthStatus? failureStatus = null,
IEnumerable<string>? tags = null,
TimeSpan? timeout = null)
{
builder.Add(new HealthCheckRegistration(
ConfigurationKeys.StorageServiceName,
serviceProvider =>
{
var logger = serviceProvider.GetRequiredService<ILogger<MinIoHealthCheck>>();
var minioClientFactory = serviceProvider.GetRequiredService<IMinIoClientFactory>();
return new MinIoHealthCheck(minioClientFactory, logger);
},
failureStatus,
tags,
timeout));
return builder;
}
}
}
1 change: 1 addition & 0 deletions src/Plugins/MinIO/InternalsVisibleTo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Monai.Deploy.Storage.MinIO.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
3 changes: 3 additions & 0 deletions src/Plugins/MinIO/LoggerMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ public static partial class LoggerMethods

[LoggerMessage(EventId = 20002, Level = LogLevel.Error, Message = "Error verifying objects in bucket '{bucketName}'.")]
public static partial void VerifyObjectError(this ILogger logger, string bucketName, Exception ex);

[LoggerMessage(EventId = 20003, Level = LogLevel.Error, Message = "Health check failure.")]
public static partial void HealthCheckError(this ILogger logger, Exception ex);
}
}
Binary file removed src/Plugins/MinIO/Mc/mc.exe
Binary file not shown.
49 changes: 49 additions & 0 deletions src/Plugins/MinIO/MinIoHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2022 MONAI Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;

namespace Monai.Deploy.Storage.MinIO
{
internal class MinIoHealthCheck : IHealthCheck
{
private readonly IMinIoClientFactory _minIoClientFactory;
private readonly ILogger<MinIoHealthCheck> _logger;

public MinIoHealthCheck(IMinIoClientFactory minIoClientFactory, ILogger<MinIoHealthCheck> logger)
{
_minIoClientFactory = minIoClientFactory ?? throw new ArgumentNullException(nameof(minIoClientFactory));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new())
{
try
{
var minioClient = _minIoClientFactory.GetClient();
await minioClient.ListBucketsAsync(cancellationToken).ConfigureAwait(false);

return HealthCheckResult.Healthy();
}
catch (Exception exception)
{
_logger.HealthCheckError(exception);
return HealthCheckResult.Unhealthy(exception: exception);
}
}
}
}
4 changes: 2 additions & 2 deletions src/Plugins/MinIO/Monai.Deploy.Storage.MinIO.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--
<!--
~ Copyright 2022 MONAI Consortium
~
~ Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -48,7 +48,7 @@

<ItemGroup>
<PackageReference Include="Ardalis.GuardClauses" Version="4.0.1" />
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.1.185" />
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.1.190" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Minio" Version="4.0.5" />
Expand Down
4 changes: 0 additions & 4 deletions src/Plugins/MinIO/ServiceRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ namespace Monai.Deploy.Storage.MinIO
{
public class ServiceRegistration : ServiceRegistrationBase
{
public ServiceRegistration(string fullyQualifiedAssemblyName) : base(fullyQualifiedAssemblyName)
{
}

public override IServiceCollection Configure(IServiceCollection services)
{
services.AddSingleton<IMinIoClientFactory, MinIoClientFactory>();
Expand Down
15 changes: 7 additions & 8 deletions src/Plugins/MinIO/StorageAdminService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private async Task<List<string>> ExecuteAsync(string cmd)

using (var process = CreateProcess(cmd))
{
var (lines, errors) = await RunProcessAsync(process);
var (lines, errors) = await RunProcessAsync(process).ConfigureAwait(false);
if (errors.Any())
{
throw new InvalidOperationException($"Unknown Error {string.Join("\n", errors)}");
Expand Down Expand Up @@ -174,7 +174,7 @@ public async Task<bool> HasConnectionAsync()

public async Task<bool> SetConnectionAsync()
{
if (await HasConnectionAsync())
if (await HasConnectionAsync().ConfigureAwait(false))
{
return true;
}
Expand Down Expand Up @@ -227,11 +227,11 @@ public async Task<Credentials> CreateUserAsync(string username, PolicyRequest[]
Guard.Against.NullOrWhiteSpace(username, nameof(username));
Guard.Against.Null(policyRequests, nameof(policyRequests));

if (!await SetConnectionAsync())
if (!await SetConnectionAsync().ConfigureAwait(false))
{
throw new InvalidOperationException("Unable to set connection for more information, attempt mc alias set {_serviceName} http://{_endpoint} {_accessKey} {_secretKey}");
throw new InvalidOperationException($"Unable to set connection for more information, attempt mc alias set {_serviceName} http://{_endpoint} {_accessKey} {_secretKey}");
}
if (await UserAlreadyExistsAsync(username))
if (await UserAlreadyExistsAsync(username).ConfigureAwait(false))
{
throw new InvalidOperationException("User already exists");
}
Expand All @@ -245,11 +245,10 @@ public async Task<Credentials> CreateUserAsync(string username, PolicyRequest[]

if (result.Any(r => r.Contains($"Added user `{username}` successfully.")) is false)
{
await RemoveUserAsync(username);
await RemoveUserAsync(username).ConfigureAwait(false);
throw new InvalidOperationException($"Unknown Output {string.Join("\n", result)}");
}


var policyName = await CreatePolicyAsync(policyRequests.ToArray(), username).ConfigureAwait(false);
var minioPolicies = new List<string> { policyName };

Expand Down Expand Up @@ -280,7 +279,7 @@ private async Task<string> CreatePolicyAsync(PolicyRequest[] policyRequests, str
var result = await ExecuteAsync($"admin policy add {_serviceName} pol_{username} {policyFileName}").ConfigureAwait(false);
if (result.Any(r => r.Contains($"Added policy `pol_{username}` successfully.")) is false)
{
await RemoveUserAsync(username);
await RemoveUserAsync(username).ConfigureAwait(false);
File.Delete($"{username}.json");
throw new InvalidOperationException("Failed to create policy, user has been removed");
}
Expand Down
Loading

0 comments on commit a746587

Please sign in to comment.