Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ internal class AmqpConnectionScope : IDisposable
///
private static TimeSpan MinimumAuthorizationRefresh { get; } = TimeSpan.FromMinutes(2);

/// <summary>
/// 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.
/// </summary>
///
/// <remarks>
/// 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.
/// </remarks>
///
private static TimeSpan MaximumAuthorizationRefresh { get; } = TimeSpan.FromDays(49);

/// <summary>
/// The amount time to allow to refresh authorization of an AMQP link.
/// </summary>
Expand Down Expand Up @@ -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
};
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
}

/// <summary>
/// Verifies functionality of the <see cref="AmqpConnectionScope.CalculateLinkAuthorizationRefreshInterval" />
/// method.
/// </summary>
///
[Test]
public void CalculateLinkAuthorizationRefreshIntervalRespectsTheMinimumDuration()
{
var endPoint = new Uri("sb://mine.hubs.com");
var credential = new Mock<EventHubTokenCredential>(Mock.Of<TokenCredential>(), "{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.");
}

/// <summary>
/// Verifies functionality of the <see cref="AmqpConnectionScope.CalculateLinkAuthorizationRefreshInterval" />
/// method.
/// </summary>
///
[Test]
public void CalculateLinkAuthorizationRefreshIntervalRespectsTheMaximumDuration()
{
var endPoint = new Uri("sb://mine.hubs.com");
var credential = new Mock<EventHubTokenCredential>(Mock.Of<TokenCredential>(), "{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.");
}

/// <summary>
/// Gets the active connection for the given scope, using the
/// private property accessor.
Expand Down Expand Up @@ -2047,6 +2086,28 @@ private static TimeSpan GetAuthorizationRefreshBuffer() =>
.GetProperty("AuthorizationRefreshBuffer", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
.GetValue(null);

/// <summary>
/// Gets the minimum authorization refresh interval, using the
/// private property accessor.
/// </summary>
///
private static TimeSpan GetMinimumAuthorizationRefresh() =>
(TimeSpan)
typeof(AmqpConnectionScope)
.GetProperty("MinimumAuthorizationRefresh", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
.GetValue(null);

/// <summary>
/// Gets the maximum authorization refresh interval, using the
/// private property accessor.
/// </summary>
///
private static TimeSpan GetMaximumAuthorizationRefresh() =>
(TimeSpan)
typeof(AmqpConnectionScope)
.GetProperty("MaximumAuthorizationRefresh", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
.GetValue(null);

/// <summary>
/// Creates a set of dummy settings for testing purposes.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ internal class AmqpConnectionScope : TransportConnectionScope
/// </summary>
private static TimeSpan MinimumAuthorizationRefresh { get; } = TimeSpan.FromMinutes(2);

/// <summary>
/// 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.
/// </summary>
///
/// <remarks>
/// 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.
/// </remarks>
///
private static TimeSpan MaximumAuthorizationRefresh { get; } = TimeSpan.FromDays(49);

/// <summary>
/// The amount time to allow to refresh authorization of an AMQP link.
/// </summary>
Expand Down Expand Up @@ -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
};
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
}

/// <summary>
/// Verifies functionality of the <see cref="AmqpConnectionScope.CalculateLinkAuthorizationRefreshInterval" />
/// method.
/// </summary>
///
[Test]
public void CalculateLinkAuthorizationRefreshIntervalRespectsTheMinimumDuration()
{
var credential = new Mock<ServiceBusTokenCredential>(Mock.Of<TokenCredential>(), "{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.");
}

/// <summary>
/// Verifies functionality of the <see cref="AmqpConnectionScope.CalculateLinkAuthorizationRefreshInterval" />
/// method.
/// </summary>
///
[Test]
public void CalculateLinkAuthorizationRefreshIntervalRespectsTheMaximumDuration()
{
var credential = new Mock<ServiceBusTokenCredential>(Mock.Of<TokenCredential>(), "{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.");
}

/// <summary>
/// Gets the token refresh buffer for the scope, using the
/// private property accessor.
Expand All @@ -54,6 +91,28 @@ private static TimeSpan GetAuthorizationRefreshBuffer() =>
.GetProperty("AuthorizationRefreshBuffer", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
.GetValue(null);

/// <summary>
/// Gets the minimum authorization refresh interval, using the
/// private property accessor.
/// </summary>
///
private static TimeSpan GetMinimumAuthorizationRefresh() =>
(TimeSpan)
typeof(AmqpConnectionScope)
.GetProperty("MinimumAuthorizationRefresh", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
.GetValue(null);

/// <summary>
/// Gets the maximum authorization refresh interval, using the
/// private property accessor.
/// </summary>
///
private static TimeSpan GetMaximumAuthorizationRefresh() =>
(TimeSpan)
typeof(AmqpConnectionScope)
.GetProperty("MaximumAuthorizationRefresh", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetProperty)
.GetValue(null);

/// <summary>
/// Creates a set of dummy settings for testing purposes.
/// </summary>
Expand Down