reactor / reactor-core

Non-Blocking Reactive Foundation for the JVM

Home Page:http://projectreactor.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

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 Monos 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.