Context being lost between @RabbitListener and Webclient
Jojoooo1 opened this issue · comments
Trace are not being propagated between @RabbitListener and downstream webClient using Spring Boot 3.2 and reactor 3.6.0
Expected Behavior
[service-webhook] [pool-6-thread-4] [0846b5f279f31bdeaf059557fc0950a6-3f2563a3260e8510] c.s.webhook.clients.WebhookHttpClient : HTTP[webhook] retryCount[0] url[https://webhook.site/b4b43dbd-9980-4690-8db7-e50be66e4d0c] body[{}]
[service-webhook] [or-http-epoll-4] [ this should have traces ] c.s.webhook.clients.WebhookHttpClient : HTTP[webhook] '{}'
Actual Behavior
[service-webhook] [pool-6-thread-4] [0846b5f279f31bdeaf059557fc0950a6-3f2563a3260e8510] c.s.webhook.clients.WebhookHttpClient : HTTP[webhook] retryCount[0] url[https://webhook.site/b4b43dbd-9980-4690-8db7-e50be66e4d0c] body[{}]
[service-webhook] [or-http-epoll-4] [ ] c.s.webhook.clients.WebhookHttpClient : HTTP[webhook] '{}'
Steps to Reproduce
clone project https://github.com/Jojoooo1/spring-microservice-webhook-reactive
make start-rabbitmq
- Start application with
dev
profile - Access RabbitMQ dashboard with user:password
- Access webhook queue http://localhost:15672/#/queues/%2F/webhook
- Publish message with header url: any-webhooksite-url body: {}
The code part is within the WebhookHttpClient.java
[...]
return this.webClient
.post()
.uri(url)
.contentType(MediaType.APPLICATION_JSON)
.headers(
httpHeaders ->
headers.forEach((k, v) -> httpHeaders.add(k, v != null ? v.toString() : null)))
.bodyValue(requestBody)
.exchangeToMono(this::defaultResponseHandler)
[...]
private Mono<Void> defaultResponseHandler(final ClientResponse response) {
final HttpStatusCode status = response.statusCode();
return response
// Does not enforce any class to keep http client generic.
.bodyToMono(String.class)
// Necessary to force mono execution on empty response.
.defaultIfEmpty(StringUtils.EMPTY)
.map(
body -> {
if (status.is2xxSuccessful()) {
log.info("HTTP[webhook] response '{}'", body);
It is pretty strange as the context is only separate by an exchangeToMono and bodyToMono.
Possible Solution
Your Environment
- Reactor version(s) used: 3.6.0-SNAPSHOT
- Other relevant libraries versions (eg.
netty
, ...): Spring Boot 3.2.0-SNAPSHOT - JVM version (
java -version
): Java 21 graalce - OS and version (eg
uname -a
): Linux 6.2.0-37-generic
Please report at spring-amqp project repository. I have some suspicion they might need to attach the Observation
to the reactive context here or here, or elsewhere. These are just quick glimpses.
Those Mono
s have nothing to do with downstream propagation within the listener; they are only used when the @RabbitListener
method returns a Mono
, perhaps with a reply that is sent to the caller, or to asynchronously acknowledge the incoming message when the downstream process completes.
Bear in mind that the Observation
created by the listener container only lives for the scope of the listener method; the observation is closed when the listener method returns. The container cannot handle async listener methods (it knows nothing about the actual listener method - that is all handled in the listener adapter).
I suspect you will need to handle it yourself in your listener.
Just for transparency, I responded in the linked spring-amqp issue.