Search code examples
spring-bootrabbitmqspring-rabbit

What is the ServletFilter equalent of a RabbitMq Listener?


I have a spring-boot web application for which I implemented an MDCFilter that adds a UUID to MDC logging context that i can find in the log file.

The Filter class looks like this.

public class MDCFilter implements Filter {

  @Override
  public void init(FilterConfig filterConfig) {
  }

  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
      throws IOException, ServletException {

    String requestId = UUID.randomUUID().toString();

    MDC.put(REQUEST_ID_KEY, requestId);
    response.addHeader("trace", requestId);
    try {
      chain.doFilter(req, resp);
    } finally {
      MDC.remove("trace");
    }
  }

  @Override
  public void destroy() {
  }
}

But recently we moved towards processing traffic via Queues and I have no clue from the documents to replicate this filter behaviour for the message listeners.

My listener would look something like this.

@RabbitListener(queues = "${queue1}")
public void receiveMessages(Message message) {
doTheBusinessLogic(message)
}

Can anyone point me to the right direction ?


Solution

  • Use the container's adviceChain. Assuming you are using Boot 2.0 and the simple container factory, override boot's factory to add the advice...

    @SpringBootApplication
    public class So49770881Application {
    
        public static void main(String[] args) {
            SpringApplication.run(So49770881Application.class, args);
        }
    
        @Bean(name = "rabbitListenerContainerFactory")
        public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(
                SimpleRabbitListenerContainerFactoryConfigurer configurer,
                ConnectionFactory connectionFactory) {
            SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
            configurer.configure(factory, connectionFactory);
            factory.setAdviceChain(new MDCAdvice());
            return factory;
        }
    
        public static class MDCAdvice implements MethodInterceptor {
    
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                // pre process
                try {
                    return invocation.proceed();
                }
                finally {
                    // post process
                }
            }
    
        }
    
    }