-
Notifications
You must be signed in to change notification settings - Fork 803
/
ElasticsearchHealthCheck.cs
120 lines (102 loc) · 4.92 KB
/
ElasticsearchHealthCheck.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System.Collections.Concurrent;
using System.Diagnostics;
using Elastic.Clients.Elasticsearch;
using Elastic.Transport;
using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace HealthChecks.Elasticsearch;
public class ElasticsearchHealthCheck : IHealthCheck
{
private static readonly ConcurrentDictionary<string, ElasticsearchClient> _connections = new();
private readonly ElasticsearchOptions _options;
public ElasticsearchHealthCheck(ElasticsearchOptions options)
{
Debug.Assert(options.Uri is not null || options.Client is not null || options.AuthenticateWithElasticCloud);
_options = Guard.ThrowIfNull(options);
}
/// <inheritdoc />
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
ElasticsearchClient? elasticsearchClient = null;
if (_options.Client is not null)
{
elasticsearchClient = _options.Client;
}
else
{
ElasticsearchClientSettings? settings = null;
settings = _options.AuthenticateWithElasticCloud
? new ElasticsearchClientSettings(_options.CloudId!, new ApiKey(_options.ApiKey!))
: new ElasticsearchClientSettings(new Uri(_options.Uri!));
if (_options.RequestTimeout.HasValue)
{
settings = settings.RequestTimeout(_options.RequestTimeout.Value);
}
if (!_connections.TryGetValue(_options.Uri!, out elasticsearchClient))
{
if (_options.AuthenticateWithBasicCredentials)
{
if (_options.UserName is null)
{
throw new ArgumentNullException(nameof(_options.UserName));
}
if (_options.Password is null)
{
throw new ArgumentNullException(nameof(_options.Password));
}
settings = settings.Authentication(new BasicAuthentication(_options.UserName, _options.Password));
}
else if (_options.AuthenticateWithCertificate)
{
if (_options.Certificate is null)
{
throw new ArgumentNullException(nameof(_options.Certificate));
}
settings = settings.ClientCertificate(_options.Certificate);
}
else if (_options.AuthenticateWithApiKey)
{
if (_options.ApiKey is null)
{
throw new ArgumentNullException(nameof(_options.ApiKey));
}
settings.Authentication(new ApiKey(_options.ApiKey));
}
if (_options.CertificateValidationCallback != null)
{
settings = settings.ServerCertificateValidationCallback(_options.CertificateValidationCallback);
}
elasticsearchClient = new ElasticsearchClient(settings);
if (!_connections.TryAdd(_options.Uri!, elasticsearchClient))
{
elasticsearchClient = _connections[_options.Uri!];
}
}
}
if (_options.UseClusterHealthApi)
{
var healthResponse = await elasticsearchClient.Cluster.HealthAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
if (healthResponse.ApiCallDetails.HttpStatusCode != 200)
{
return new HealthCheckResult(context.Registration.FailureStatus);
}
return healthResponse.Status switch
{
Elastic.Clients.Elasticsearch.HealthStatus.Green => HealthCheckResult.Healthy(),
Elastic.Clients.Elasticsearch.HealthStatus.Yellow => HealthCheckResult.Degraded(),
_ => new HealthCheckResult(context.Registration.FailureStatus)
};
}
var pingResult = await elasticsearchClient.PingAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
bool isSuccess = pingResult.ApiCallDetails.HttpStatusCode == 200;
return isSuccess
? HealthCheckResult.Healthy()
: new HealthCheckResult(context.Registration.FailureStatus);
}
catch (Exception ex)
{
return new HealthCheckResult(context.Registration.FailureStatus, exception: ex);
}
}
}