Azure / Azure/azure-sdk-for-java

AzurePipelinesCredential does async over sync (over async) causing problems in AMQP tests

Open
#44,519 2 comments 0 reactions 1 assignee Assigned to @g2vinay View on GitHub
Azure.Core Azure.Identity bug Client needs-team-attention
Dominant language
Java
Stars
2.6k
Forks
2.2k
Avg merge
2d 8h
Merged PRs (30d)
178

Description

AMQP has a specific threading model and gets token on a thread that can't be blocked. It uses async getToken API.
In the case of `AzurePipelinesCredential` this results in something like this

```log
06 Mar 2025 02:34:28,193 [reactor-executor-1] ERROR com.azure.core.http.netty.NettyAsyncHttpClient - block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-executor-1
java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-executor-1
at reactor.core@3.4.41/reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:83)
at reactor.core@3.4.41/reactor.core.publisher.Mono.block(Mono.java:1742)
at com.azure.http.netty@1.15.10/com.azure.core.http.netty.NettyAsyncHttpClient.sendSync(NettyAsyncHttpClient.java:195)
at com.azure.core@1.55.2/com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:51)
at com.azure.core@1.55.2/com.azure.core.http.policy.HttpLoggingPolicy.processSync(HttpLoggingPolicy.java:175)
at com.azure.core@1.55.2/com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:53)
at com.azure.core@1.55.2/com.azure.core.implementation.http.policy.InstrumentationPolicy.processSync(InstrumentationPolicy.java:101)
at com.azure.core@1.55.2/com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:53)
at com.azure.core@1.55.2/com.azure.core.http.policy.RetryPolicy.attemptSync(RetryPolicy.java:217)
at com.azure.core@1.55.2/com.azure.core.http.policy.RetryPolicy.processSync(RetryPolicy.java:161)
at com.azure.core@1.55.2/com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:53)
at com.azure.core@1.55.2/com.azure.core.http.policy.AddHeadersPolicy.processSync(AddHeadersPolicy.java:66)
at com.azure.core@1.55.2/com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:53)
at com.azure.core@1.55.2/com.azure.core.http.policy.HttpPipelineSyncPolicy.processSync(HttpPipelineSyncPolicy.java:51)
at com.azure.core@1.55.2/com.azure.core.http.policy.UserAgentPolicy.processSync(UserAgentPolicy.java:174)
at com.azure.core@1.55.2/com.azure.core.http.HttpPipelineNextSyncPolicy.processSync(HttpPipelineNextSyncPolicy.java:53)
at com.azure.core@1.55.2/com.azure.core.http.HttpPipeline.sendSync(HttpPipeline.java:138)
at com.azure.identity.AzurePipelinesCredential.lambda$new$0(AzurePipelinesCredential.java:80)
at com.azure.identity.implementation.IdentityClientBase.getConfidentialClient(IdentityClientBase.java:232)
at com.azure.identity.implementation.IdentityClient.lambda$getConfidentialClientApplication$5(IdentityClient.java:152)
at reactor.core@3.4.41/reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:45)
at reactor.core@3.4.41/reactor.core.publisher.MonoCacheTime.subscribeOrReturn(MonoCacheTime.java:143)
at reactor.core@3.4.41/reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
at reactor.core@3.4.41/reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157)
at reactor.core@3.4.41/reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1839)
at reactor.core@3.4.41/reactor.core.publisher.MonoCacheInvalidateIf$CoordinatorSubscriber.onNext(MonoCacheInvalidateIf.java:319)
at reactor.core@3.4.41/reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:126)
at reactor.core@3.4.41/reactor.core.publisher.SerializedSubscriber.onNext(SerializedSubscriber.java:99)
at reactor.core@3.4.41/reactor.core.publisher.FluxRetryWhen$RetryWhenMainSubscriber.onNext(FluxRetryWhen.java:174)
at reactor.core@3.4.41/reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1839)
at reactor.core@3.4.41/reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:249)
at reactor.core@3.4.41/reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:292)
at reactor.core@3.4.41/reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187)
at reactor.core@3.4.41/reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:236)
at reactor.core@3.4.41/reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203)
at reactor.core@3.4.41/reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260)
at reactor.core@3.4.41/reactor.core.publisher.SerializedSubscriber.onComplete(SerializedSubscriber.java:146)
at reactor.core@3.4.41/reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.onComplete(FluxTimeout.java:234)
at reactor.core@3.4.41/reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85)
at reactor.core@3.4.41/reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102)
at reactor.core@3.4.41/reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:83)
at reactor.core@3.4.41/reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:113)
at reactor.core@3.4.41/reactor.core.publisher.EmitterProcessor.drain(EmitterProcessor.java:537)
at reactor.core@3.4.41/reactor.core.publisher.EmitterProcessor.tryEmitNext(EmitterProcessor.java:343)
at reactor.core@3.4.41/reactor.core.publisher.SinkManySerialized.tryEmitNext(SinkManySerialized.java:100)
at reactor.core@3.4.41/reactor.core.publisher.InternalManySink.emitNext(InternalManySink.java:27)
at com.azure.core.amqp.implementation.RequestResponseChannel.updateEndpointState(RequestResponseChannel.java:496)
```

because of this code

https://github.com/Azure/azure-sdk-for-java/blob/fe75c7d72a3561ac83cb1efedeeea2dcb68e6538/sdk/identity/azure-identity/src/main/java/com/azure/identity/AzurePipelinesCredential.java#L80

that does sync over async (and back to async under because of Netty).

While this affects tests only, it'd be nice to avoid async over sync and minimize issues like this.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.