diff --git a/sdk/eventhub/Azure.Messaging.EventHubs/src/Amqp/AmqpConnectionScope.cs b/sdk/eventhub/Azure.Messaging.EventHubs/src/Amqp/AmqpConnectionScope.cs
index 8fd0d57aa14f..af0925545893 100644
--- a/sdk/eventhub/Azure.Messaging.EventHubs/src/Amqp/AmqpConnectionScope.cs
+++ b/sdk/eventhub/Azure.Messaging.EventHubs/src/Amqp/AmqpConnectionScope.cs
@@ -76,6 +76,18 @@ internal class AmqpConnectionScope : IDisposable
///
private static TimeSpan MinimumAuthorizationRefresh { get; } = TimeSpan.FromMinutes(2);
+ ///
+ /// The maximum amount of time to allow before authorization is refreshed; any calculations
+ /// that call for refreshing less frequently will be substituted with this value.
+ ///
+ ///
+ ///
+ /// This value must be less than 49 days, 17 hours, 2 minutes, 47 seconds, 294 milliseconds
+ /// in order to not overflow the Timer used to track authorization refresh.
+ ///
+ ///
+ private static TimeSpan MaximumAuthorizationRefresh { get; } = TimeSpan.FromDays(49);
+
///
/// The amount time to allow to refresh authorization of an AMQP link.
///
@@ -758,7 +770,13 @@ protected virtual TimeSpan CalculateLinkAuthorizationRefreshInterval(DateTime ex
currentTimeUtc ??= DateTime.UtcNow;
var refreshDueInterval = (expirationTimeUtc.Subtract(AuthorizationRefreshBuffer)).Subtract(currentTimeUtc.Value);
- return (refreshDueInterval < MinimumAuthorizationRefresh) ? MinimumAuthorizationRefresh : refreshDueInterval;
+
+ return refreshDueInterval switch
+ {
+ _ when (refreshDueInterval < MinimumAuthorizationRefresh) => MinimumAuthorizationRefresh,
+ _ when (refreshDueInterval > MaximumAuthorizationRefresh) => MaximumAuthorizationRefresh,
+ _ => refreshDueInterval
+ };
}
///
diff --git a/sdk/eventhub/Azure.Messaging.EventHubs/tests/Amqp/AmqpConnectionScopeTests.cs b/sdk/eventhub/Azure.Messaging.EventHubs/tests/Amqp/AmqpConnectionScopeTests.cs
index 57fcb88e564c..2abbdeabe86c 100644
--- a/sdk/eventhub/Azure.Messaging.EventHubs/tests/Amqp/AmqpConnectionScopeTests.cs
+++ b/sdk/eventhub/Azure.Messaging.EventHubs/tests/Amqp/AmqpConnectionScopeTests.cs
@@ -2003,6 +2003,45 @@ public void CalculateLinkAuthorizationRefreshIntervalRespectsTheRefreshBuffer()
Assert.That(calculatedExpire, Is.EqualTo(expireTime.Subtract(buffer)).Within(TimeSpan.FromSeconds(2)), "The authorization buffer should have been used for buffering.");
}
+ ///
+ /// Verifies functionality of the
+ /// method.
+ ///
+ ///
+ [Test]
+ public void CalculateLinkAuthorizationRefreshIntervalRespectsTheMinimumDuration()
+ {
+ var endPoint = new Uri("sb://mine.hubs.com");
+ var credential = new Mock(Mock.Of(), "{namespace}.servicebus.windows.net");
+ var mockScope = new MockConnectionMockScope(endPoint, endPoint, "test", credential.Object, EventHubsTransportType.AmqpTcp, null);
+ var currentTime = new DateTime(2015, 10, 27, 00, 00, 00);
+ var minimumRefresh = GetMinimumAuthorizationRefresh();
+ var expireTime = currentTime.Add(minimumRefresh.Subtract(TimeSpan.FromMilliseconds(500)));
+ var calculatedRefresh = mockScope.InvokeCalculateLinkAuthorizationRefreshInterval(expireTime, currentTime);
+
+ Assert.That(calculatedRefresh, Is.EqualTo(minimumRefresh), "The minimum refresh duration should have been used.");
+ }
+
+ ///
+ /// Verifies functionality of the
+ /// method.
+ ///
+ ///
+ [Test]
+ public void CalculateLinkAuthorizationRefreshIntervalRespectsTheMaximumDuration()
+ {
+ var endPoint = new Uri("sb://mine.hubs.com");
+ var credential = new Mock(Mock.Of(), "{namespace}.servicebus.windows.net");
+ var mockScope = new MockConnectionMockScope(endPoint, endPoint, "test", credential.Object, EventHubsTransportType.AmqpTcp, null);
+ var currentTime = new DateTime(2015, 10, 27, 00, 00, 00);
+ var refreshBuffer = GetAuthorizationRefreshBuffer();
+ var maximumRefresh = GetMaximumAuthorizationRefresh();
+ var expireTime = currentTime.Add(maximumRefresh.Add(refreshBuffer).Add(TimeSpan.FromMilliseconds(500)));
+ var calculatedRefresh = mockScope.InvokeCalculateLinkAuthorizationRefreshInterval(expireTime, currentTime);
+
+ Assert.That(calculatedRefresh, Is.EqualTo(maximumRefresh), "The maximum refresh duration should have been used.");
+ }
+
///
/// Gets the active connection for the given scope, using the
/// private property accessor.
@@ -2047,6 +2086,28 @@ private static TimeSpan GetAuthorizationRefreshBuffer() =>
.GetProperty("AuthorizationRefreshBuffer", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
.GetValue(null);
+ ///
+ /// Gets the minimum authorization refresh interval, using the
+ /// private property accessor.
+ ///
+ ///
+ private static TimeSpan GetMinimumAuthorizationRefresh() =>
+ (TimeSpan)
+ typeof(AmqpConnectionScope)
+ .GetProperty("MinimumAuthorizationRefresh", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
+ .GetValue(null);
+
+ ///
+ /// Gets the maximum authorization refresh interval, using the
+ /// private property accessor.
+ ///
+ ///
+ private static TimeSpan GetMaximumAuthorizationRefresh() =>
+ (TimeSpan)
+ typeof(AmqpConnectionScope)
+ .GetProperty("MaximumAuthorizationRefresh", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
+ .GetValue(null);
+
///
/// Creates a set of dummy settings for testing purposes.
///
diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Amqp/AmqpConnectionScope.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Amqp/AmqpConnectionScope.cs
index bab7c93de223..c6dab02cffdd 100644
--- a/sdk/servicebus/Azure.Messaging.ServiceBus/src/Amqp/AmqpConnectionScope.cs
+++ b/sdk/servicebus/Azure.Messaging.ServiceBus/src/Amqp/AmqpConnectionScope.cs
@@ -61,6 +61,18 @@ internal class AmqpConnectionScope : TransportConnectionScope
///
private static TimeSpan MinimumAuthorizationRefresh { get; } = TimeSpan.FromMinutes(2);
+ ///
+ /// The maximum amount of time to allow before authorization is refreshed; any calculations
+ /// that call for refreshing less frequently will be substituted with this value.
+ ///
+ ///
+ ///
+ /// This value must be less than 49 days, 17 hours, 2 minutes, 47 seconds, 294 milliseconds
+ /// in order to not overflow the Timer used to track authorization refresh.
+ ///
+ ///
+ private static TimeSpan MaximumAuthorizationRefresh { get; } = TimeSpan.FromDays(49);
+
///
/// The amount time to allow to refresh authorization of an AMQP link.
///
@@ -893,7 +905,13 @@ protected virtual TimeSpan CalculateLinkAuthorizationRefreshInterval(
currentTimeUtc ??= DateTime.UtcNow;
var refreshDueInterval = (expirationTimeUtc.Subtract(AuthorizationRefreshBuffer)).Subtract(currentTimeUtc.Value);
- return (refreshDueInterval < MinimumAuthorizationRefresh) ? MinimumAuthorizationRefresh : refreshDueInterval;
+
+ return refreshDueInterval switch
+ {
+ _ when (refreshDueInterval < MinimumAuthorizationRefresh) => MinimumAuthorizationRefresh,
+ _ when (refreshDueInterval > MaximumAuthorizationRefresh) => MaximumAuthorizationRefresh,
+ _ => refreshDueInterval
+ };
}
///
diff --git a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Amqp/AmqpConnectionScopeTests.cs b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Amqp/AmqpConnectionScopeTests.cs
index da4750d4f11d..7ceb7de5b533 100644
--- a/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Amqp/AmqpConnectionScopeTests.cs
+++ b/sdk/servicebus/Azure.Messaging.ServiceBus/tests/Amqp/AmqpConnectionScopeTests.cs
@@ -43,6 +43,43 @@ public void CalculateLinkAuthorizationRefreshIntervalRespectsTheRefreshBuffer()
Assert.That(calculatedExpire, Is.EqualTo(expireTime.Subtract(buffer)).Within(TimeSpan.FromSeconds(2)), "The authorization buffer should have been used for buffering.");
}
+ ///
+ /// Verifies functionality of the
+ /// method.
+ ///
+ ///
+ [Test]
+ public void CalculateLinkAuthorizationRefreshIntervalRespectsTheMinimumDuration()
+ {
+ var credential = new Mock(Mock.Of(), "{namespace}.servicebus.windows.net");
+ var mockScope = new MockConnectionMockScope(new Uri("sb://mine.hubs.com"), credential.Object, ServiceBusTransportType.AmqpTcp, null);
+ var currentTime = new DateTime(2015, 10, 27, 00, 00, 00);
+ var minimumRefresh = GetMinimumAuthorizationRefresh();
+ var expireTime = currentTime.Add(minimumRefresh.Subtract(TimeSpan.FromMilliseconds(500)));
+ var calculatedRefresh = mockScope.InvokeCalculateLinkAuthorizationRefreshInterval(expireTime, currentTime);
+
+ Assert.That(calculatedRefresh, Is.EqualTo(minimumRefresh), "The minimum refresh duration should have been used.");
+ }
+
+ ///
+ /// Verifies functionality of the
+ /// method.
+ ///
+ ///
+ [Test]
+ public void CalculateLinkAuthorizationRefreshIntervalRespectsTheMaximumDuration()
+ {
+ var credential = new Mock(Mock.Of(), "{namespace}.servicebus.windows.net");
+ var mockScope = new MockConnectionMockScope(new Uri("sb://mine.hubs.com"), credential.Object, ServiceBusTransportType.AmqpTcp, null);
+ var currentTime = new DateTime(2015, 10, 27, 00, 00, 00);
+ var refreshBuffer = GetAuthorizationRefreshBuffer();
+ var maximumRefresh = GetMaximumAuthorizationRefresh();
+ var expireTime = currentTime.Add(maximumRefresh.Add(refreshBuffer).Add(TimeSpan.FromMilliseconds(500)));
+ var calculatedRefresh = mockScope.InvokeCalculateLinkAuthorizationRefreshInterval(expireTime, currentTime);
+
+ Assert.That(calculatedRefresh, Is.EqualTo(maximumRefresh), "The maximum refresh duration should have been used.");
+ }
+
///
/// Gets the token refresh buffer for the scope, using the
/// private property accessor.
@@ -54,6 +91,28 @@ private static TimeSpan GetAuthorizationRefreshBuffer() =>
.GetProperty("AuthorizationRefreshBuffer", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
.GetValue(null);
+ ///
+ /// Gets the minimum authorization refresh interval, using the
+ /// private property accessor.
+ ///
+ ///
+ private static TimeSpan GetMinimumAuthorizationRefresh() =>
+ (TimeSpan)
+ typeof(AmqpConnectionScope)
+ .GetProperty("MinimumAuthorizationRefresh", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
+ .GetValue(null);
+
+ ///
+ /// Gets the maximum authorization refresh interval, using the
+ /// private property accessor.
+ ///
+ ///
+ private static TimeSpan GetMaximumAuthorizationRefresh() =>
+ (TimeSpan)
+ typeof(AmqpConnectionScope)
+ .GetProperty("MaximumAuthorizationRefresh", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
+ .GetValue(null);
+
///
/// Creates a set of dummy settings for testing purposes.
///