Skip to content

Commit e37399c

Browse files
authored
Fixing the infinite loop that runs to renew SAS token after 20 minutes when a connection string contains the SAS token instead of SAS key. (#342)
1 parent 56df106 commit e37399c

File tree

7 files changed

+20
-10
lines changed

7 files changed

+20
-10
lines changed

azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/CommonRequestResponseOperations.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ static CompletableFuture<Void> sendCBSTokenAsync(RequestResponseLink requestResp
8080
Message requestMessage = RequestResponseUtils.createRequestMessageFromValueBody(ClientConstants.REQUEST_RESPONSE_PUT_TOKEN_OPERATION, securityToken.getTokenValue(), Util.adjustServerTimeout(operationTimeout));
8181
requestMessage.getApplicationProperties().getValue().put(ClientConstants.REQUEST_RESPONSE_PUT_TOKEN_TYPE, securityToken.getTokenType().toString());
8282
requestMessage.getApplicationProperties().getValue().put(ClientConstants.REQUEST_RESPONSE_PUT_TOKEN_AUDIENCE, securityToken.getTokenAudience());
83-
requestMessage.getApplicationProperties().getValue().put(ClientConstants.REQUEST_RESPONSE_PUT_TOKEN_EXPIRATION, securityToken.getValidUntil().toEpochMilli());
8483
CompletableFuture<Message> responseFuture = requestResponseLink.requestAysnc(requestMessage, operationTimeout);
8584
return responseFuture.thenComposeAsync((responseMessage) -> {
8685
CompletableFuture<Void> returningFuture = new CompletableFuture<Void>();

azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/CoreMessageReceiver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,7 @@ private synchronized CompletableFuture<Void> ensureLinkIsOpen()
11671167
Throwable cause = ExceptionUtil.extractAsyncCompletionCause(sendTokenEx);
11681168
TRACE_LOGGER.error("Sending SAS Token to '{}' failed.", this.receivePath, cause);
11691169
this.receiveLinkReopenFuture.completeExceptionally(sendTokenEx);
1170+
this.clearAllPendingWorkItems(sendTokenEx);
11701171
}
11711172
else
11721173
{
@@ -1214,7 +1215,7 @@ private void completePendingUpdateStateWorkItem(Delivery delivery, String delive
12141215
this.pendingUpdateStateRequests.remove(deliveryTagAsString);
12151216
}
12161217

1217-
private void clearAllPendingWorkItems(Exception exception)
1218+
private void clearAllPendingWorkItems(Throwable exception)
12181219
{
12191220
TRACE_LOGGER.info("Completeing all pending receive and updateState operation on the receiver to '{}'", this.receivePath);
12201221
final boolean isTransientException = exception == null ||

azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/CoreMessageSender.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ else if (outcome instanceof Released)
553553
}
554554
}
555555

556-
private void clearAllPendingSendsWithException(Exception failureException)
556+
private void clearAllPendingSendsWithException(Throwable failureException)
557557
{
558558
synchronized (this.pendingSendLock)
559559
{
@@ -567,7 +567,7 @@ private void clearAllPendingSendsWithException(Exception failureException)
567567
}
568568
}
569569

570-
private void cleanupFailedSend(final SendWorkItem<Void> failedSend, final Exception exception)
570+
private void cleanupFailedSend(final SendWorkItem<Void> failedSend, final Throwable exception)
571571
{
572572
failedSend.cancelTimeoutTask(false);
573573
ExceptionUtil.completeExceptionally(failedSend.getWork(), exception, this, true);
@@ -730,6 +730,7 @@ private synchronized CompletableFuture<Void> ensureLinkIsOpen()
730730
Throwable cause = ExceptionUtil.extractAsyncCompletionCause(sendTokenEx);
731731
TRACE_LOGGER.error("Sending SAS Token to '{}' failed.", this.sendPath, cause);
732732
this.sendLinkReopenFuture.completeExceptionally(sendTokenEx);
733+
this.clearAllPendingSendsWithException(sendTokenEx);
733734
}
734735
else
735736
{

azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/ExceptionUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ else if (errorCondition.getCondition() == ClientConstants.ENTITY_ALREADY_EXISTS_
121121
return new ServiceBusException(ClientConstants.DEFAULT_IS_TRANSIENT, errorCondition.toString());
122122
}
123123

124-
static <T> void completeExceptionally(CompletableFuture<T> future, Exception exception, IErrorContextProvider contextProvider, boolean completeAsynchronously)
124+
static <T> void completeExceptionally(CompletableFuture<T> future, Throwable exception, IErrorContextProvider contextProvider, boolean completeAsynchronously)
125125
{
126126
if (exception != null && exception instanceof ServiceBusException)
127127
{

azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/MessagingFactory.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,17 @@ private CompletableFuture<Instant> generateAndSendSecurityToken(String sasTokenA
627627

628628
private static ScheduledFuture<?> scheduleRenewTimer(Instant currentTokenValidUntil, Runnable validityRenewer)
629629
{
630-
// It will eventually expire. Renew it
631-
int renewInterval = Util.getTokenRenewIntervalInSeconds((int)Duration.between(Instant.now(), currentTokenValidUntil).getSeconds());
632-
return Timer.schedule(validityRenewer, Duration.ofSeconds(renewInterval), TimerType.OneTimeRun);
630+
if(currentTokenValidUntil == Instant.MAX)
631+
{
632+
// User provided token or will never expire
633+
return null;
634+
}
635+
else
636+
{
637+
// It will eventually expire. Renew it
638+
int renewInterval = Util.getTokenRenewIntervalInSeconds((int)Duration.between(Instant.now(), currentTokenValidUntil).getSeconds());
639+
return Timer.schedule(validityRenewer, Duration.ofSeconds(renewInterval), TimerType.OneTimeRun);
640+
}
633641
}
634642

635643
CompletableFuture<RequestResponseLink> obtainRequestResponseLinkAsync(String entityPath, MessagingEntityType entityType)

azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/RequestResponseLink.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ private CompletableFuture<Void> recreateInternalLinks()
343343
Throwable cause = ExceptionUtil.extractAsyncCompletionCause(sasTokenEx);
344344
TRACE_LOGGER.error("Sending SAS Token failed. RequestResponseLink path:{}", this.linkPath, cause);
345345
recreateInternalLinksFuture.completeExceptionally(cause);
346+
this.completeAllPendingRequestsWithException(cause);
346347
}
347348
else
348349
{
@@ -405,7 +406,7 @@ public void run()
405406
return recreateInternalLinksFuture;
406407
}
407408

408-
private void completeAllPendingRequestsWithException(Exception exception)
409+
private void completeAllPendingRequestsWithException(Throwable exception)
409410
{
410411
TRACE_LOGGER.warn("Completing all pending requests with exception in request response link to {}", this.linkPath);
411412
for(RequestResponseWorkItem workItem : this.pendingRequests.values())

azure-servicebus/src/main/java/com/microsoft/azure/servicebus/primitives/Util.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ public static ClientSettings getClientSettingsFromConnectionStringBuilder(Connec
425425
}
426426
else
427427
{
428-
tokenProvider = new SharedAccessSignatureTokenProvider(builder.getSharedAccessSignatureToken(), Instant.now().plus(Duration.ofSeconds(SecurityConstants.DEFAULT_SAS_TOKEN_VALIDITY_IN_SECONDS)));
428+
tokenProvider = new SharedAccessSignatureTokenProvider(builder.getSharedAccessSignatureToken(), Instant.MAX); // Max validity as we will not generate another token
429429
}
430430

431431
return new ClientSettings(tokenProvider, builder.getRetryPolicy(), builder.getOperationTimeout());

0 commit comments

Comments
 (0)