1- using Microsoft . Extensions . Logging ;
1+ using System . Collections . Concurrent ;
2+ using Microsoft . Extensions . Logging ;
3+ using OpenDDD . Infrastructure . Events . Base ;
24using Azure . Messaging . ServiceBus ;
35using Azure . Messaging . ServiceBus . Administration ;
46
@@ -10,7 +12,7 @@ public class AzureServiceBusMessagingProvider : IMessagingProvider, IAsyncDispos
1012 private readonly ServiceBusAdministrationClient _adminClient ;
1113 private readonly bool _autoCreateTopics ;
1214 private readonly ILogger < AzureServiceBusMessagingProvider > _logger ;
13- private readonly List < ServiceBusProcessor > _processors = new ( ) ;
15+ private readonly ConcurrentDictionary < string , AzureServiceBusSubscription > _subscriptions = new ( ) ;
1416 private bool _disposed ;
1517
1618 public AzureServiceBusMessagingProvider (
@@ -25,7 +27,7 @@ public AzureServiceBusMessagingProvider(
2527 _logger = logger ?? throw new ArgumentNullException ( nameof ( logger ) ) ;
2628 }
2729
28- public async Task SubscribeAsync ( string topic , string consumerGroup , Func < string , CancellationToken , Task > messageHandler , CancellationToken cancellationToken = default )
30+ public async Task < ISubscription > SubscribeAsync ( string topic , string consumerGroup , Func < string , CancellationToken , Task > messageHandler , CancellationToken cancellationToken = default )
2931 {
3032 if ( string . IsNullOrWhiteSpace ( topic ) )
3133 {
@@ -59,7 +61,6 @@ public async Task SubscribeAsync(string topic, string consumerGroup, Func<string
5961 await CreateSubscriptionIfNotExistsAsync ( topic , subscriptionName , cancellationToken ) ;
6062
6163 var processor = _client . CreateProcessor ( topic , subscriptionName ) ;
62- _processors . Add ( processor ) ;
6364
6465 processor . ProcessMessageAsync += async args =>
6566 {
@@ -73,41 +74,30 @@ public async Task SubscribeAsync(string topic, string consumerGroup, Func<string
7374 return Task . CompletedTask ;
7475 } ;
7576
76- _logger . LogInformation ( "Starting message processor for topic '{Topic}' and subscription '{Subscription}'" , topic , subscriptionName ) ;
77+ var subscription = new AzureServiceBusSubscription ( topic , consumerGroup , processor ) ;
78+ _subscriptions [ subscription . Id ] = subscription ;
79+
80+ _logger . LogInformation ( "Starting message processor for topic '{Topic}' and subscription '{Subscription}', Subscription ID: {SubscriptionId}" , topic , subscriptionName , subscription . Id ) ;
7781 await processor . StartProcessingAsync ( cancellationToken ) ;
82+
83+ return subscription ;
7884 }
7985
80- public async Task UnsubscribeAsync ( string topic , string consumerGroup , CancellationToken cancellationToken = default )
86+ public async Task UnsubscribeAsync ( ISubscription subscription , CancellationToken cancellationToken = default )
8187 {
82- if ( string . IsNullOrWhiteSpace ( topic ) )
83- {
84- throw new ArgumentException ( "Topic cannot be null or empty." , nameof ( topic ) ) ;
85- }
88+ if ( subscription == null )
89+ throw new ArgumentNullException ( nameof ( subscription ) ) ;
8690
87- if ( string . IsNullOrWhiteSpace ( consumerGroup ) )
91+ if ( subscription is not AzureServiceBusSubscription serviceBusSubscription || ! _subscriptions . TryRemove ( serviceBusSubscription . Id , out _ ) )
8892 {
89- throw new ArgumentException ( "Consumer group cannot be null or empty." , nameof ( consumerGroup ) ) ;
93+ _logger . LogWarning ( "No active subscription found with ID {SubscriptionId}" , subscription . Id ) ;
94+ return ;
9095 }
9196
92- var subscriptionName = consumerGroup ;
93-
94- _logger . LogInformation ( "Unsubscribing from topic '{Topic}' and subscription '{Subscription}'" , topic , subscriptionName ) ;
95-
96- var processor = _processors . FirstOrDefault ( p =>
97- p . EntityPath . Equals ( $ "{ topic } /Subscriptions/{ subscriptionName } ", StringComparison . OrdinalIgnoreCase ) ) ;
98-
99- if ( processor != null )
100- {
101- _processors . Remove ( processor ) ;
102- _logger . LogInformation ( "Stopping and disposing message processor for topic '{Topic}' and subscription '{Subscription}'" , topic , subscriptionName ) ;
97+ _logger . LogInformation ( "Unsubscribing from Azure Service Bus topic '{Topic}' and subscription '{Subscription}', Subscription ID: {SubscriptionId}" , serviceBusSubscription . Topic , serviceBusSubscription . ConsumerGroup , serviceBusSubscription . Id ) ;
10398
104- await processor . StopProcessingAsync ( cancellationToken ) ;
105- await processor . DisposeAsync ( ) ;
106- }
107- else
108- {
109- _logger . LogWarning ( "No active subscription found for topic '{Topic}' and subscription '{Subscription}'" , topic , subscriptionName ) ;
110- }
99+ await serviceBusSubscription . Consumer . StopProcessingAsync ( cancellationToken ) ;
100+ await serviceBusSubscription . DisposeAsync ( ) ;
111101 }
112102
113103 public async Task PublishAsync ( string topic , string message , CancellationToken cancellationToken = default )
@@ -157,14 +147,16 @@ public async ValueTask DisposeAsync()
157147
158148 _logger . LogDebug ( "Disposing AzureServiceBusMessagingProvider..." ) ;
159149
160- foreach ( var processor in _processors )
150+ foreach ( var subscription in _subscriptions . Values )
161151 {
162- _logger . LogDebug ( "Stopping message processor..." ) ;
163- await processor . StopProcessingAsync ( ) ;
164- await processor . DisposeAsync ( ) ;
152+ if ( subscription . Consumer . IsProcessing )
153+ {
154+ await subscription . Consumer . StopProcessingAsync ( CancellationToken . None ) ;
155+ }
156+ await subscription . DisposeAsync ( ) ;
165157 }
166158
167- _logger . LogDebug ( "Disposing ServiceBusClient..." ) ;
159+ _subscriptions . Clear ( ) ;
168160 await _client . DisposeAsync ( ) ;
169161 }
170162 }
0 commit comments