Skip to content
This repository was archived by the owner on Jun 11, 2026. It is now read-only.

Commit 19ea2a4

Browse files
Merge dev to master (#244)
* Fix EventHubsConnectionStringBuilder ctor crash (#219) When supplying SharedAccessSignature as a parameter * Fixing deceptive description of InitialOffsetProvider (#224) * Aad token provider (#225) * Adding AAD token support. * improve lock * Adding MSI provider. * Some small changes * Adddresing comments and couple small fixes. * Remove string resource * Remove test secrets * Renaming paramater endpoint to endpointAddress * Renaming paramater endpoint to endpointAddress * Remove unused AsyncLock * Remove redundant config name * Remove using * Remove usings * Merge fix * API name change * Xmldoc type fix. * Remove SecurityToken internal constructor * Build error fix * Cleanup code * Pass temporary audience instead of empty string to SecurityToken. * Make token type required * Refactoring SharedAccessSignatureToken for cleanup * Function renaming to carry UTC notion. * Remove procted accesors from SecurityToken class properties. * Adding receiver identifier support (#226) * Fixing EventDataBatch with partition-key related issues. (#198) * Fixing DataBatch partition-key usage * Fixing EventDataBatch with partition-key related issues. * Incorporating comments from latest team discussion. * Removing a leftover from debug session. * Adding maxMessageSize to CreateBatch API on clients. * Aligning API with Java client. * Fixing build error. * Adding EH client changes to support sequence number receiver. (#230) * EventData.SystemProperties to inherit Dictionary (#206) * Adding BatchOptions * Avoid application properties to overwrite IOT set properties. * Remove batchoptions, not related to this change * Avoid IOT reserved names to be used in the message propery bag. * SystemProperties to inherit System.Dictionary. * Return system property from dictionary instead of assigning them during message conversion. * Throw if system property is missing. * Fix merge errors * Merge fix * Remove unnecessary partitionid/partitionkey check * Close receivers * Adjusting class comment of EventDataBatch class (#213) * Adjusting class comment of EventDataBatch class Adjusting top comment, as SendBatch and SendBatchAsync methods don't exist on EventHubClient anymore, the methods are called Send and SendAsync and take either a single EventData or an IEnumerable<EventData>. In addition the comment makes it not clear why a dev should use this class. Why not just create an IEnumerable<EventData> on your own? A dev should use this class because it takes care of the size limit, that's the main reason and it should be in the header. * Update EventDataBatch.cs Fixing the comment to make it XML-compliant. * Update EventDataBatch.cs Link EventHubClient in XML comment * Add default batch size for receive handler. (#235) * Add default batch size for receive handler. * Rely on default MaxBatchSize in the unit tests * XMLdoc correction * Address James's comment on PR * Fixed a typographical error (#239) * invokeWhenNoEvents flag for Pump (#238) * Adding invokeWhenNoEvents to pump and wiring up EH null callback on this. * Fix default pump invoke on null behavior * Stop-CancellationToken for PartitionPump (#187) * Temporarily hiding AAD token provider API
1 parent 661fa11 commit 19ea2a4

55 files changed

Lines changed: 2086 additions & 854 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ consumers that filter and/or transform event streams and then forward them on to
4343

4444
[https://github.com/Azure/azure-event-hubs/tree/master/samples](https://github.com/Azure/azure-event-hubs/tree/master/samples)
4545

46-
### How to build client liblaries on Visual Studio 2017?
46+
### How to build client libraries on Visual Studio 2017?
4747

4848
Make sure you have .NET Core Cross-Platform Development SDK installed. If it is missing, you can install the SDK by running Visual Studio Installer. See https://www.microsoft.com/net/core#windowscmd for VS 2017 and SDK installation.
4949

src/Microsoft.Azure.EventHubs.Processor/Checkpoint.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class Checkpoint
1313
/// </summary>
1414
/// <param name="partitionId">The partition ID for the checkpoint</param>
1515
public Checkpoint(string partitionId)
16-
: this(partitionId, PartitionReceiver.StartOfStream, 0)
16+
: this(partitionId, EventPosition.FromStart().Offset, 0)
1717
{
1818
}
1919

src/Microsoft.Azure.EventHubs.Processor/EventHubPartitionPump.cs

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ protected override async Task OnOpenAsync()
5555
// meaning it is safe to set the handler and start calling IEventProcessor.OnEvents.
5656
// Set the status to running before setting the client handler, so the IEventProcessor.OnEvents can never race and see status != running.
5757
this.PumpStatus = PartitionPumpStatus.Running;
58-
this.partitionReceiver.SetReceiveHandler(this.partitionReceiveHandler);
58+
this.partitionReceiver.SetReceiveHandler(
59+
this.partitionReceiveHandler,
60+
this.Host.EventProcessorOptions.InvokeProcessorAfterReceiveTimeout);
5961
}
6062

6163
if (this.PumpStatus == PartitionPumpStatus.OpenFailed)
@@ -69,9 +71,10 @@ protected override async Task OnOpenAsync()
6971
async Task OpenClientsAsync() // throws EventHubsException, IOException, InterruptedException, ExecutionException
7072
{
7173
// Create new clients
72-
object startAt = await this.PartitionContext.GetInitialOffsetAsync().ConfigureAwait(false);
74+
EventPosition eventPosition = await this.PartitionContext.GetInitialOffsetAsync().ConfigureAwait(false);
7375
long epoch = this.Lease.Epoch;
74-
ProcessorEventSource.Log.PartitionPumpCreateClientsStart(this.Host.Id, this.PartitionContext.PartitionId, epoch, startAt?.ToString());
76+
ProcessorEventSource.Log.PartitionPumpCreateClientsStart(this.Host.Id, this.PartitionContext.PartitionId, epoch,
77+
$"Offset:{eventPosition.Offset}, SequenceNumber:{eventPosition.SequenceNumber}, DateTime:{eventPosition.EnqueuedTimeUtc}");
7578
this.eventHubClient = EventHubClient.CreateFromConnectionString(this.Host.EventHubConnectionString);
7679

7780
var receiverOptions = new ReceiverOptions()
@@ -81,24 +84,12 @@ async Task OpenClientsAsync() // throws EventHubsException, IOException, Interru
8184
};
8285

8386
// Create new receiver and set options
84-
if (startAt is string)
85-
{
86-
this.partitionReceiver = this.eventHubClient.CreateEpochReceiver(
87-
this.PartitionContext.ConsumerGroupName,
88-
this.PartitionContext.PartitionId,
89-
(string)startAt,
90-
epoch,
91-
receiverOptions);
92-
}
93-
else if (startAt is DateTime)
94-
{
95-
this.partitionReceiver = this.eventHubClient.CreateEpochReceiver(
96-
this.PartitionContext.ConsumerGroupName,
97-
this.PartitionContext.PartitionId,
98-
(DateTime)startAt,
99-
epoch,
100-
receiverOptions);
101-
}
87+
this.partitionReceiver = this.eventHubClient.CreateEpochReceiver(
88+
this.PartitionContext.ConsumerGroupName,
89+
this.PartitionContext.PartitionId,
90+
eventPosition,
91+
epoch,
92+
receiverOptions);
10293

10394
this.partitionReceiver.PrefetchCount = this.Host.EventProcessorOptions.PrefetchCount;
10495

@@ -146,7 +137,7 @@ public PartitionReceiveHandler(EventHubPartitionPump eventHubPartitionPump)
146137
this.MaxBatchSize = eventHubPartitionPump.Host.EventProcessorOptions.MaxBatchSize;
147138
}
148139

149-
public int MaxBatchSize { get; }
140+
public int MaxBatchSize { get; set; }
150141

151142
public Task ProcessEventsAsync(IEnumerable<EventData> events)
152143
{

src/Microsoft.Azure.EventHubs.Processor/EventProcessorOptions.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public EventProcessorOptions()
3838
this.MaxBatchSize = 10;
3939
this.PrefetchCount = 300;
4040
this.ReceiveTimeout = TimeSpan.FromMinutes(1);
41-
this.InitialOffsetProvider = partitionId => PartitionReceiver.StartOfStream;
41+
this.InitialOffsetProvider = partitionId => EventPosition.FromStart();
4242
}
4343

4444
/// <summary>
@@ -79,12 +79,11 @@ public bool EnableReceiverRuntimeMetric
7979
public int PrefetchCount { get; set; }
8080

8181
/// <summary>
82-
/// Get or sets the current function used to determine the initial offset at which to start receiving
83-
/// events for a partition.
84-
/// <para>A null return indicates that it is using the internal provider, which uses the last checkpointed
85-
/// offset value (if present) or StartOfSTream (if not).</para>
82+
/// Gets or sets a delegate which is used to get the initial position for a given partition to create <see cref="PartitionReceiver"/>.
83+
/// Delegate is invoked by passing in PartitionId and then user can return <see cref="PartitionReceiver"/> for receiving messages.
84+
/// This is only used when <see cref="Lease.Offset"/> is not provided and receiver is being created for the very first time.
8685
/// </summary>
87-
public Func<string, object> InitialOffsetProvider { get; set; }
86+
public Func<string, EventPosition> InitialOffsetProvider { get; set; }
8887

8988
/// <summary>
9089
/// Returns whether the EventProcessorHost will call IEventProcessor.OnEvents(null) when a receive

src/Microsoft.Azure.EventHubs.Processor/Microsoft.Azure.EventHubs.Processor.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
</PropertyGroup>
3030

3131
<PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0'">
32-
<DefineConstants>$(DefineConstants);UAP10_0</DefineConstants>
3332
<NugetTargetMoniker>UAP,Version=v10.0</NugetTargetMoniker>
3433
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
3534
<TargetPlatformVersion>10.0.14393.0</TargetPlatformVersion>

src/Microsoft.Azure.EventHubs.Processor/PartitionContext.cs

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace Microsoft.Azure.EventHubs.Processor
55
{
66
using System;
7+
using System.Threading;
78
using System.Threading.Tasks;
89

910
/// <summary>
@@ -13,18 +14,24 @@ public class PartitionContext
1314
{
1415
readonly EventProcessorHost host;
1516

16-
internal PartitionContext(EventProcessorHost host, string partitionId, string eventHubPath, string consumerGroupName)
17+
internal PartitionContext(EventProcessorHost host, string partitionId, string eventHubPath, string consumerGroupName, CancellationToken cancellationToken)
1718
{
1819
this.host = host;
1920
this.PartitionId = partitionId;
2021
this.EventHubPath = eventHubPath;
2122
this.ConsumerGroupName = consumerGroupName;
23+
this.CancellationToken = cancellationToken;
2224
this.ThisLock = new object();
23-
this.Offset = PartitionReceiver.StartOfStream;
25+
this.Offset = EventPosition.FromStart().Offset;
2426
this.SequenceNumber = 0;
2527
this.RuntimeInformation = new ReceiverRuntimeInformation(partitionId);
2628
}
2729

30+
/// <summary>
31+
/// Gets triggered when the partition gets closed.
32+
/// </summary>
33+
public CancellationToken CancellationToken { get; }
34+
2835
/// <summary>
2936
/// Gets the name of the consumer group.
3037
/// </summary>
@@ -84,43 +91,28 @@ internal void SetOffsetAndSequenceNumber(EventData eventData)
8491
}
8592
}
8693

87-
internal async Task<object> GetInitialOffsetAsync() // throws InterruptedException, ExecutionException
94+
internal async Task<EventPosition> GetInitialOffsetAsync() // throws InterruptedException, ExecutionException
8895
{
8996
Checkpoint startingCheckpoint = await this.host.CheckpointManager.GetCheckpointAsync(this.PartitionId).ConfigureAwait(false);
90-
object startAt;
97+
EventPosition eventPosition;
9198

9299
if (startingCheckpoint == null)
93100
{
94101
// No checkpoint was ever stored. Use the initialOffsetProvider instead.
95-
Func<string, object> initialOffsetProvider = this.host.EventProcessorOptions.InitialOffsetProvider;
102+
Func<string, EventPosition> initialOffsetProvider = this.host.EventProcessorOptions.InitialOffsetProvider;
96103
ProcessorEventSource.Log.PartitionPumpInfo(this.host.Id, this.PartitionId, "Calling user-provided initial offset provider");
97-
startAt = initialOffsetProvider(this.PartitionId);
98-
99-
if (startAt is string)
100-
{
101-
this.Offset = (string)startAt;
102-
this.SequenceNumber = 0; // TODO we use sequenceNumber to check for regression of offset, 0 could be a problem until it gets updated from an event
103-
ProcessorEventSource.Log.PartitionPumpInfo(this.host.Id, this.PartitionId, $"Initial offset/sequenceNumber provided: {this.Offset}/{this.SequenceNumber}");
104-
}
105-
else if (startAt is DateTime)
106-
{
107-
// can't set offset/sequenceNumber
108-
ProcessorEventSource.Log.PartitionPumpInfo(this.host.Id, this.PartitionId, $"Initial timestamp provided: {(DateTime)startAt}");
109-
}
110-
else
111-
{
112-
throw new ArgumentException("Unexpected object type returned by user-provided initialOffsetProvider");
113-
}
104+
eventPosition = initialOffsetProvider(this.PartitionId);
105+
ProcessorEventSource.Log.PartitionPumpInfo(this.host.Id, this.PartitionId, $"Initial Position Provider. Offset:{eventPosition.Offset}, SequenceNumber:{eventPosition.SequenceNumber}, DateTime:{eventPosition.EnqueuedTimeUtc}");
114106
}
115107
else
116108
{
117109
this.Offset = startingCheckpoint.Offset;
118110
this.SequenceNumber = startingCheckpoint.SequenceNumber;
119111
ProcessorEventSource.Log.PartitionPumpInfo(this.host.Id, this.PartitionId, $"Retrieved starting offset/sequenceNumber: {this.Offset}/{this.SequenceNumber}");
120-
startAt = this.Offset;
112+
eventPosition = EventPosition.FromOffset(this.Offset);
121113
}
122114

123-
return startAt;
115+
return eventPosition;
124116
}
125117

126118
/// <summary>
@@ -154,7 +146,7 @@ public Task CheckpointAsync(EventData eventData)
154146
{
155147
throw new ArgumentNullException("eventData");
156148
}
157-
149+
158150
// We have never seen this sequence number yet
159151
if (eventData.SystemProperties.SequenceNumber > this.SequenceNumber)
160152
{

src/Microsoft.Azure.EventHubs.Processor/PartitionPump.cs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ namespace Microsoft.Azure.EventHubs.Processor
66
using System;
77
using System.Collections.Generic;
88
using System.Linq;
9+
using System.Threading;
910
using System.Threading.Tasks;
1011

1112
abstract class PartitionPump
12-
{
13+
{
14+
CancellationTokenSource cancellationTokenSource;
15+
1316
protected PartitionPump(EventProcessorHost host, Lease lease)
1417
{
1518
this.Host = host;
@@ -37,7 +40,9 @@ public async Task OpenAsync()
3740
{
3841
this.PumpStatus = PartitionPumpStatus.Opening;
3942

40-
this.PartitionContext = new PartitionContext(this.Host, this.Lease.PartitionId, this.Host.EventHubPath, this.Host.ConsumerGroupName);
43+
this.cancellationTokenSource = new CancellationTokenSource();
44+
45+
this.PartitionContext = new PartitionContext(this.Host, this.Lease.PartitionId, this.Host.EventHubPath, this.Host.ConsumerGroupName, this.cancellationTokenSource.Token);
4146
this.PartitionContext.Lease = this.Lease;
4247

4348
if (this.PumpStatus == PartitionPumpStatus.Opening)
@@ -86,6 +91,8 @@ public async Task CloseAsync(CloseReason reason)
8691
this.PumpStatus = PartitionPumpStatus.Closing;
8792
try
8893
{
94+
this.cancellationTokenSource.Cancel();
95+
8996
await this.OnClosingAsync(reason).ConfigureAwait(false);
9097

9198
if (this.Processor != null)
@@ -111,8 +118,8 @@ public async Task CloseAsync(CloseReason reason)
111118

112119
if (reason != CloseReason.LeaseLost)
113120
{
114-
// Since this pump is dead, release the lease.
115-
// Ignore LeaseLostException
121+
// Since this pump is dead, release the lease.
122+
// Ignore LeaseLostException
116123
try
117124
{
118125
await this.Host.LeaseManager.ReleaseLeaseAsync(this.PartitionContext.Lease).ConfigureAwait(false);
@@ -130,15 +137,7 @@ protected async Task ProcessEventsAsync(IEnumerable<EventData> events)
130137
{
131138
if (events == null)
132139
{
133-
if (this.Host.EventProcessorOptions.InvokeProcessorAfterReceiveTimeout)
134-
{
135-
// Assumes that .NET Core client will call with empty EventData on receive timeout.
136-
events = Enumerable.Empty<EventData>();
137-
}
138-
else
139-
{
140-
return;
141-
}
140+
events = Enumerable.Empty<EventData>();
142141
}
143142

144143
// Synchronize to serialize calls to the processor.

src/Microsoft.Azure.EventHubs/Amqp/AmqpClientConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class AmqpClientConstants
1515
public static readonly AmqpSymbol EntityTypeName = AmqpConstants.Vendor + ":entity-type";
1616
public static readonly AmqpSymbol TimeoutName = AmqpConstants.Vendor + ":timeout";
1717
public static readonly AmqpSymbol EnableReceiverRuntimeMetricName = AmqpConstants.Vendor + ":enable-receiver-runtime-metric";
18+
public static readonly AmqpSymbol ReceiverIdentifierName = AmqpConstants.Vendor + ":receiver-name";
1819

1920
// Error codes
2021
public static readonly AmqpSymbol DeadLetterName = AmqpConstants.Vendor + ":dead-letter";
@@ -42,6 +43,7 @@ class AmqpClientConstants
4243
public static readonly AmqpSymbol MessageReceiptsFilterName = AmqpConstants.Vendor + ":message-receipts-filter";
4344
public static readonly AmqpSymbol ClientSideCursorFilterName = AmqpConstants.Vendor + ":client-side-filter";
4445
public static readonly TimeSpan ClientMinimumTokenRefreshInterval = TimeSpan.FromMinutes(4);
46+
public const string FilterSeqNumberName = "amqp.annotation." + ClientConstants.SequenceNumberName;
4547
public const string FilterOffsetPartName = "amqp.annotation.x-opt-offset";
4648
public const string FilterOffset = FilterOffsetPartName + " > ";
4749
public const string FilterInclusiveOffset = FilterOffsetPartName + " >= ";

src/Microsoft.Azure.EventHubs/Amqp/AmqpEventHubClient.cs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ namespace Microsoft.Azure.EventHubs.Amqp
55
{
66
using System;
77
using System.Linq;
8-
using System.Net;
98
using System.Threading.Tasks;
109
using Microsoft.Azure.Amqp.Sasl;
1110
using Microsoft.Azure.Amqp;
@@ -26,17 +25,33 @@ public AmqpEventHubClient(EventHubsConnectionStringBuilder csb)
2625

2726
if (!string.IsNullOrWhiteSpace(csb.SharedAccessSignature))
2827
{
29-
this.TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(csb.SharedAccessSignature);
28+
this.InternalTokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(csb.SharedAccessSignature);
3029
}
3130
else
3231
{
33-
this.TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(csb.SasKeyName, csb.SasKey);
32+
this.InternalTokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(csb.SasKeyName, csb.SasKey);
3433
}
3534

3635
this.CbsTokenProvider = new TokenProviderAdapter(this);
3736
this.ConnectionManager = new FaultTolerantAmqpObject<AmqpConnection>(this.CreateConnectionAsync, this.CloseConnection);
3837
}
3938

39+
public AmqpEventHubClient(
40+
Uri endpointAddress,
41+
string entityPath,
42+
ITokenProvider tokenProvider,
43+
TimeSpan operationTimeout,
44+
TransportType transportType)
45+
: base(new EventHubsConnectionStringBuilder(endpointAddress, entityPath, operationTimeout, transportType))
46+
{
47+
this.ContainerId = Guid.NewGuid().ToString("N");
48+
this.AmqpVersion = new Version(1, 0, 0, 0);
49+
this.MaxFrameSize = AmqpConstants.DefaultMaxFrameSize;
50+
this.InternalTokenProvider = tokenProvider;
51+
this.CbsTokenProvider = new TokenProviderAdapter(this);
52+
this.ConnectionManager = new FaultTolerantAmqpObject<AmqpConnection>(this.CreateConnectionAsync, this.CloseConnection);
53+
}
54+
4055
internal ICbsTokenProvider CbsTokenProvider { get; }
4156

4257
internal FaultTolerantAmqpObject<AmqpConnection> ConnectionManager { get; }
@@ -47,18 +62,18 @@ public AmqpEventHubClient(EventHubsConnectionStringBuilder csb)
4762

4863
uint MaxFrameSize { get; }
4964

50-
internal TokenProvider TokenProvider { get; }
65+
internal ITokenProvider InternalTokenProvider { get; }
5166

5267
internal override EventDataSender OnCreateEventSender(string partitionId)
5368
{
5469
return new AmqpEventDataSender(this, partitionId);
5570
}
5671

5772
protected override PartitionReceiver OnCreateReceiver(
58-
string consumerGroupName, string partitionId, string startOffset, bool offsetInclusive, DateTime? startTime, long? epoch, ReceiverOptions receiverOptions)
73+
string consumerGroupName, string partitionId, EventPosition eventPosition, long? epoch, ReceiverOptions receiverOptions)
5974
{
6075
return new AmqpPartitionReceiver(
61-
this, consumerGroupName, partitionId, startOffset, offsetInclusive, startTime, epoch, receiverOptions);
76+
this, consumerGroupName, partitionId, eventPosition, epoch, receiverOptions);
6277
}
6378

6479
protected override Task OnCloseAsync()
@@ -110,7 +125,7 @@ internal static AmqpSettings CreateAmqpSettings(
110125
string sslHostName = null,
111126
bool useWebSockets = false,
112127
bool sslStreamUpgrade = false,
113-
NetworkCredential networkCredential = null,
128+
System.Net.NetworkCredential networkCredential = null,
114129
bool forceTokenProvider = true)
115130
{
116131
var settings = new AmqpSettings();
@@ -266,11 +281,9 @@ public TokenProviderAdapter(AmqpEventHubClient eventHubClient)
266281

267282
public async Task<CbsToken> GetTokenAsync(Uri namespaceAddress, string appliesTo, string[] requiredClaims)
268283
{
269-
string claim = requiredClaims?.FirstOrDefault();
270-
var tokenProvider = this.eventHubClient.TokenProvider;
271284
var timeout = this.eventHubClient.ConnectionStringBuilder.OperationTimeout;
272-
var token = await tokenProvider.GetTokenAsync(appliesTo, claim, timeout).ConfigureAwait(false);
273-
return new CbsToken(token.TokenValue, CbsConstants.ServiceBusSasTokenType, token.ExpiresAtUtc);
285+
var token = await this.eventHubClient.InternalTokenProvider.GetTokenAsync(appliesTo, timeout).ConfigureAwait(false);
286+
return new CbsToken(token.TokenValue, token.TokenType, token.ExpiresAtUtc);
274287
}
275288
}
276289
}

src/Microsoft.Azure.EventHubs/Amqp/AmqpExceptionHelper.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ public static Exception ToMessagingContract(string condition, string message, bo
115115
{
116116
return new ReceiverDisconnectedException(message);
117117
}
118+
else if (string.Equals(condition, AmqpErrorCode.ResourceLimitExceeded.Value))
119+
{
120+
return new QuotaExceededException(message);
121+
}
118122
else
119123
{
120124
return new EventHubsException(true, message);

0 commit comments

Comments
 (0)