Question:
I am working on a legacy web API project hosted on Azure App Services. We are using the legacy WindowsAzure.ServiceBus 7.0.1 NuGet package for performing operations on Azure Service Bus.
The method PublishMessageBatch is supposed to push messages in a batch into the queue. For authentication, I'm using AzureActiveDirectoryTokenProvider.AuthenticationCallback. However, every call to PublishMessageBatch is resulting in a timeout, and no messages are being pushed into the queue.
What I've Tried
Deadlock Investigation: Updated my code to add ConfigureAwait(false) to avoid potential deadlocks.
Log Analysis: Checked Azure App Service log streams and found that all API calls resulted in HTTP 499 status code, indicating that the client automatically cancels the request after 2 minutes.
For the managed identity I have assigned the correct permissions. Operations other than 'SendBatchAsync' are working.
I want to understand what changes I need to make to get PublishMessageBatch working without timing out. Are there any known issues with WindowsAzure.ServiceBus 7.0.1 and Azure App Services that could cause this timeout?
public async Task PublishMessageBatch(IEnumerable<BrokeredMessage> queueMessages)
{
await _logger.ExecuteWithInstrumentationAsync("ServiceBusQueueClient.PublishMessageBatch", string.Empty, async () =>
{
_logger.TraceInfo("Pushing message in Queue");
InitializeIfUnavailable();
await _sbQueueClient.SendBatchAsync(queueMessages).ConfigureAwait(false);
return true;
});
}
public void InitializeIfUnavailable()
{
Uri serviceBusURI = _queueConnectionString.GetServiceBusURIFromConnectionString();
string aadAuthority = _configuration.GetValue<string>(CCMConstants.AADAuthorityURL);
if (_sbQueueClient?.IsClosed != false)
{
lock (_lock)
{
if (_sbQueueClient?.IsClosed != false)
{
_logger.TraceInfo("initializing QueueClient AAD");
var azureAuthCallback = new AzureActiveDirectoryTokenProvider.AuthenticationCallback(GetTokenAsync);
_sbQueueClient = QueueClient.CreateWithAzureActiveDirectory(serviceBusURI, _queuePath, azureAuthCallback, aadAuthority, ReceiveMode.PeekLock);
_logger.TraceInfo("QueueClient initialized successfully with AAD");
_sbQueueClient.RetryPolicy = RetryPolicy.Default;
}
}
}
if (_sbNamespaceManager == null)
{
var azureAuthCallback = new AzureActiveDirectoryTokenProvider.AuthenticationCallback(GetTokenAsync);
TokenProvider token = TokenProvider.CreateAzureActiveDirectoryTokenProvider(azureAuthCallback, serviceBusURI, aadAuthority);
_sbNamespaceManager = new NamespaceManager(serviceBusURI, token);
_logger.TraceInfo("Initialized NamespaceManager for ServiceBus with AAD");
}
}
private async Task<string> GetTokenAsync(string audience, string authority, object state)
{
_logger.TraceInfo($"Value of audience: {audience}, authority: {authority} and state {state}");
return (await (new ManagedIdentityCredential("<client-id>")).GetTokenAsync(new TokenRequestContext(new[] { "https://servicebus.azure.net/.default" }), CancellationToken.None)).Token;
}
We are pushing all our logs into kusto clusters and the last log was _logger.TraceInfo($"Value of audience: {audience}, authority: {authority} and state {state}");
after this there was no exception or error seen in the logs.
I figure out the root cause was missing ConfigureAwait(false) in the the GetTokenAsync callback. WindowsAzure.ServiceBus expects this callback to independent of synchronization or request context.