Skip to content

Commit dba8555

Browse files
authored
Add minio admin heath check (#55)
* add minio admin health check Signed-off-by: Lillie Dae <[email protected]>
1 parent b88c7c6 commit dba8555

File tree

6 files changed

+154
-1
lines changed

6 files changed

+154
-1
lines changed

src/Plugins/AWSS3/StorageAdminService.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
using System;
18+
using System.Collections.Generic;
1819
using System.Threading.Tasks;
1920
using Amazon.SecurityToken.Model;
2021
using Monai.Deploy.Storage.API;
@@ -28,6 +29,10 @@ public class StorageAdminService : IStorageAdminService
2829

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

32+
public Task<List<string>> GetConnectionAsync() => throw new NotImplementedException();
33+
34+
public Task<bool> HasConnectionAsync() => throw new NotImplementedException();
35+
3136
public Task RemoveUserAsync(string username) => throw new NotImplementedException();
3237
}
3338
}

src/Plugins/MinIO/HealthCheckBuilder.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using Microsoft.Extensions.DependencyInjection;
1818
using Microsoft.Extensions.Diagnostics.HealthChecks;
1919
using Microsoft.Extensions.Logging;
20+
using Monai.Deploy.Storage.API;
2021

2122
namespace Monai.Deploy.Storage.MinIO
2223
{
@@ -39,6 +40,19 @@ public override IHealthChecksBuilder Configure(
3940
failureStatus,
4041
tags,
4142
timeout));
43+
44+
builder.Add(new HealthCheckRegistration(
45+
$"{ConfigurationKeys.StorageServiceName}-admin",
46+
serviceProvider =>
47+
{
48+
var logger = serviceProvider.GetRequiredService<ILogger<MinIoAdminHealthCheck>>();
49+
var storageAdminService = serviceProvider.GetRequiredService<IStorageAdminService>();
50+
return new MinIoAdminHealthCheck(storageAdminService, logger);
51+
},
52+
failureStatus,
53+
tags,
54+
timeout));
55+
4256
return builder;
4357
}
4458
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2022 MONAI Consortium
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using System.Collections.ObjectModel;
18+
using Microsoft.Extensions.Diagnostics.HealthChecks;
19+
using Microsoft.Extensions.Logging;
20+
using Monai.Deploy.Storage.API;
21+
22+
namespace Monai.Deploy.Storage.MinIO
23+
{
24+
internal class MinIoAdminHealthCheck : IHealthCheck
25+
{
26+
private readonly IStorageAdminService _storageAdminService;
27+
private readonly ILogger<MinIoAdminHealthCheck> _logger;
28+
29+
public MinIoAdminHealthCheck(IStorageAdminService storageAdminService, ILogger<MinIoAdminHealthCheck> logger)
30+
{
31+
_storageAdminService = storageAdminService ?? throw new ArgumentNullException(nameof(storageAdminService));
32+
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
33+
}
34+
35+
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new())
36+
{
37+
try
38+
{
39+
var hasConnection = await _storageAdminService.HasConnectionAsync();
40+
var connectionResult = await _storageAdminService.GetConnectionAsync();
41+
var joinedResult = string.Join("\n", connectionResult);
42+
43+
var roDict = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>() { { "MinoAdminResult", joinedResult } });
44+
45+
if (hasConnection)
46+
{
47+
return HealthCheckResult.Healthy(data: roDict);
48+
}
49+
50+
return HealthCheckResult.Unhealthy(data: roDict);
51+
}
52+
catch (Exception exception)
53+
{
54+
_logger.HealthCheckError(exception);
55+
return HealthCheckResult.Unhealthy(exception: exception);
56+
}
57+
}
58+
}
59+
}

src/Plugins/MinIO/StorageAdminService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,12 @@ private Process CreateProcess(string cmd)
168168

169169
public async Task<bool> HasConnectionAsync()
170170
{
171-
var result = await ExecuteAsync(_get_connections_cmd).ConfigureAwait(false);
171+
var result = await GetConnectionAsync().ConfigureAwait(false);
172172
return result.Any(r => r.Equals(_serviceName));
173173
}
174174

175+
public async Task<List<string>> GetConnectionAsync() => await ExecuteAsync(_get_connections_cmd).ConfigureAwait(false);
176+
175177
public async Task<bool> SetConnectionAsync()
176178
{
177179
if (await HasConnectionAsync().ConfigureAwait(false))
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2022 MONAI Consortium
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using Microsoft.Extensions.Diagnostics.HealthChecks;
18+
using Microsoft.Extensions.Logging;
19+
using Monai.Deploy.Storage.API;
20+
using Moq;
21+
using Xunit;
22+
23+
namespace Monai.Deploy.Storage.MinIO.Tests
24+
{
25+
public class MinIoAdminHealthCheckTest
26+
{
27+
private readonly Mock<IStorageAdminService> _storageAdminService;
28+
private readonly Mock<ILogger<MinIoAdminHealthCheck>> _logger;
29+
30+
public MinIoAdminHealthCheckTest()
31+
{
32+
_storageAdminService = new Mock<IStorageAdminService>();
33+
_logger = new Mock<ILogger<MinIoAdminHealthCheck>>();
34+
}
35+
36+
[Fact]
37+
public async Task CheckHealthAsync_WhenConnectionThrows_ReturnUnhealthy()
38+
{
39+
_storageAdminService.Setup(p => p.HasConnectionAsync()).Throws(new Exception("error"));
40+
41+
var healthCheck = new MinIoAdminHealthCheck(_storageAdminService.Object, _logger.Object);
42+
var results = await healthCheck.CheckHealthAsync(new HealthCheckContext()).ConfigureAwait(false);
43+
44+
Assert.Equal(HealthStatus.Unhealthy, results.Status);
45+
Assert.NotNull(results.Exception);
46+
Assert.Equal("error", results.Exception.Message);
47+
}
48+
49+
[Fact]
50+
public async Task CheckHealthAsync_WhenConnectionSucceeds_ReturnHealthy()
51+
{
52+
_storageAdminService.Setup(p => p.HasConnectionAsync()).ReturnsAsync(true);
53+
_storageAdminService.Setup(p => p.GetConnectionAsync()).ReturnsAsync(new List<string>() { "strings" });
54+
var healthCheck = new MinIoAdminHealthCheck(_storageAdminService.Object, _logger.Object);
55+
var results = await healthCheck.CheckHealthAsync(new HealthCheckContext()).ConfigureAwait(false);
56+
57+
Assert.Equal(HealthStatus.Healthy, results.Status);
58+
Assert.Null(results.Exception);
59+
}
60+
}
61+
}

src/Storage/API/IStorageAdminService.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,17 @@ public interface IStorageAdminService
4444
/// </summary>
4545
/// <param name="username">Username</param>
4646
Task RemoveUserAsync(string username);
47+
48+
/// <summary>
49+
/// Gets list of alias connections.
50+
/// </summary>
51+
/// <returns></returns>
52+
Task<List<string>> GetConnectionAsync();
53+
54+
/// <summary>
55+
/// If connection contains configured service name.
56+
/// </summary>
57+
/// <returns></returns>
58+
Task<bool> HasConnectionAsync();
4759
}
4860
}

0 commit comments

Comments
 (0)