Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b430409

Browse files
authored
Reuse Event Hubs client for health checks (#7625)
1 parent a838286 commit b430409

File tree

6 files changed

+56
-16
lines changed

6 files changed

+56
-16
lines changed

src/Components/Aspire.Azure.Messaging.EventHubs/EventHubProducerClientComponent.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44
using Aspire.Azure.Messaging.EventHubs;
55
using Azure.Core.Extensions;
66
using Azure.Messaging.EventHubs.Producer;
7-
using HealthChecks.Azure.Messaging.EventHubs;
87
using Microsoft.Extensions.Azure;
98
using Microsoft.Extensions.Configuration;
10-
using Microsoft.Extensions.Diagnostics.HealthChecks;
119

1210
namespace Microsoft.Extensions.Hosting;
1311

@@ -51,9 +49,4 @@ protected override IAzureClientBuilder<EventHubProducerClient, EventHubProducerC
5149

5250
}, requiresCredential: false);
5351
}
54-
55-
protected override IHealthCheck CreateHealthCheck(EventHubProducerClient client, AzureMessagingEventHubsProducerSettings settings)
56-
{
57-
return new AzureEventHubHealthCheck(client);
58-
}
5952
}

src/Components/Aspire.Azure.Messaging.EventHubs/EventHubsComponent.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ namespace Microsoft.Extensions.Hosting;
1414

1515
internal abstract class EventHubsComponent<TSettings, TClient, TClientOptions> :
1616
AzureComponent<TSettings, TClient, TClientOptions>
17-
where TClientOptions: class
17+
where TClientOptions : class
1818
where TClient : class
1919
where TSettings : AzureMessagingEventHubsSettings, new()
2020
{
21+
private EventHubProducerClient? _healthCheckClient;
22+
2123
// each EventHub client class is in a different namespace, so the base AzureComponent.ActivitySourceNames logic doesn't work
2224
protected override string[] ActivitySourceNames => ["Azure.Messaging.EventHubs.*"];
2325

@@ -26,15 +28,26 @@ protected override IHealthCheck CreateHealthCheck(TClient client, TSettings sett
2628
// HealthChecks.Azure.Messaging.EventHubs currently only supports EventHubProducerClient.
2729
// https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/issues/2258 tracks supporting other client types.
2830

29-
var producerClientOptions = new EventHubProducerClientOptions
31+
// Reuse the client if it's an EventHubProducerClient
32+
if (client is EventHubProducerClient producerClient)
33+
{
34+
_healthCheckClient = producerClient;
35+
}
36+
37+
// Create a custom EventHubProducerClient otherwise
38+
if (_healthCheckClient == null)
3039
{
31-
Identifier = $"AspireEventHubHealthCheck-{settings.EventHubName}",
32-
};
33-
var producerClient = !string.IsNullOrEmpty(settings.ConnectionString) ?
34-
new EventHubProducerClient(settings.ConnectionString, producerClientOptions) :
35-
new EventHubProducerClient(settings.FullyQualifiedNamespace, settings.EventHubName, settings.Credential ?? new DefaultAzureCredential(), producerClientOptions);
40+
var producerClientOptions = new EventHubProducerClientOptions
41+
{
42+
Identifier = $"AspireEventHubHealthCheck-{settings.EventHubName}",
43+
};
44+
45+
_healthCheckClient = !string.IsNullOrEmpty(settings.ConnectionString) ?
46+
new EventHubProducerClient(settings.ConnectionString, producerClientOptions) :
47+
new EventHubProducerClient(settings.FullyQualifiedNamespace, settings.EventHubName, settings.Credential ?? new DefaultAzureCredential(), producerClientOptions);
48+
}
3649

37-
return new AzureEventHubHealthCheck(producerClient);
50+
return new AzureEventHubHealthCheck(_healthCheckClient);
3851
}
3952

4053
protected override bool GetHealthCheckEnabled(TSettings settings)

src/Components/Aspire.Azure.Messaging.EventHubs/PartitionReceiverClientComponent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ protected override IAzureClientBuilder<PartitionReceiver, PartitionReceiverOptio
6969
settings.EventPosition,
7070
settings.ConnectionString,
7171
settings.EventHubName,
72-
options);
72+
options);
7373

7474
}, requiresCredential: false);
7575
}
File renamed without changes.
File renamed without changes.

tests/Aspire.Azure.Messaging.EventHubs.Tests/ConformanceTestsBase.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Reflection;
45
using Aspire.Components.ConformanceTests;
6+
using HealthChecks.Azure.Messaging.EventHubs;
57
using Microsoft.DotNet.RemoteExecutor;
68
using Microsoft.Extensions.Configuration;
79
using Microsoft.Extensions.DependencyInjection;
10+
using Microsoft.Extensions.Diagnostics.HealthChecks;
11+
using Microsoft.Extensions.Hosting;
12+
using Microsoft.Extensions.Options;
13+
using Xunit;
814

915
namespace Aspire.Azure.Messaging.EventHubs.Tests;
1016

@@ -60,4 +66,32 @@ protected static RemoteInvokeOptions EnableTracingForAzureSdk()
6066
{
6167
RuntimeConfigurationOptions = { { "Azure.Experimental.EnableActivitySource", true } }
6268
};
69+
70+
[ConditionalFact]
71+
public void HealthChecksClientsAreReused()
72+
{
73+
SkipIfHealthChecksAreNotSupported();
74+
75+
// DisableRetries so the test doesn't take so long retrying when the server isn't available.
76+
using IHost host = CreateHostWithComponent(configureComponent: DisableRetries);
77+
78+
HealthCheckServiceOptions healthCheckServiceOptions = host.Services.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
79+
80+
var registration = healthCheckServiceOptions.Registrations.First();
81+
82+
var healthCheck1 = registration.Factory(host.Services) as AzureEventHubHealthCheck;
83+
var healthCheck2 = registration.Factory(host.Services) as AzureEventHubHealthCheck;
84+
85+
Assert.NotNull(healthCheck1);
86+
Assert.NotNull(healthCheck2);
87+
88+
var clientAccessor = typeof(AzureEventHubHealthCheck).GetField("_client", BindingFlags.NonPublic | BindingFlags.Instance);
89+
90+
Assert.NotNull(clientAccessor);
91+
92+
var client1 = clientAccessor?.GetValue(healthCheck1);
93+
var client2 = clientAccessor?.GetValue(healthCheck2);
94+
95+
Assert.Same(client1, client2);
96+
}
6397
}

0 commit comments

Comments
 (0)