2

at the moment I have the following problem: The external RabbitMQ remote server expects from me first an async reply login message and then a broadcast queue broadcastQueue.MYUSER_123 is created by this remote server. From this I want to consume via @RabbitListener annotation, which is seen in the code example. But i got an error, you can see below.

While debugging I noticed that a container starts this listener before I have executed the login in my code and so it comes to a rejection when connecting against this broadcast queue. I found the post in How to Lazy Load RabbitMQ queue using @Lazy in spring boot? but the problem on my side is, that the autostart did not work and the container is started for the listener. What i'm doing wrong? Is it possible to create lazy queues.?

Another point is: Is there an easy way to make a direct reply configuration for the RabbitMQ template where I can specify the reply address? According to the spring amqp code it seems that you can only make a directy reply connection if you don't specify a reply address yourself. So i need to create a custom container.

Thank you for your help .

Kind Regards Sven

@SpringBootTest
@Slf4j
class DemoAmqpApplicationTests {

    @RabbitListener(queues="broadcastQueue.MYUSER_123",autoStartup = "false")
    public void handleMessage(Object obj) {
        log.info("{}",obj);

    }

    @Test
    void contextLoads() throws InterruptedException {
        Message<User> login = login();
                

    }

Configuration

@Configuration
@Slf4j
@EnableRabbit
public class RabbitMqConfiguration {

    @Bean
    public RabbitAdmin amqpAdmin(RabbitTemplate rabbitTemplate) {
        return new RabbitAdmin(rabbitTemplate);
    }

    @Bean
    public RabbitTemplate rabbitTemplate(@NonNull CachingConnectionFactory connectionFactory,
                                         @NonNull MessageConverter messageConverter,
                                         @NonNull Queue inquiryResponseQueue,
                                         @NonNull RabbitTemplateConfigurer configurer) {

        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        configurer.configure(rabbitTemplate, connectionFactory);

        String username = connectionFactory.getUsername();

        configurePostReceiveProcessor(rabbitTemplate);

        rabbitTemplate.setMessageConverter(messageConverter);

        configurePrepareSendingProcessor(rabbitTemplate, username, inquiryResponseQueue.getName());

        configureReply(rabbitTemplate, inquiryResponseQueue);

        return rabbitTemplate;
    }

    private void configureReply(RabbitTemplate rabbitTemplate,
                             
                                @NonNull Queue inquiryResponseQueue) {
        rabbitTemplate.setReplyAddress(inquiryResponseQueue.getName());
        rabbitTemplate.setDefaultReceiveQueue(inquiryResponseQueue.getName());
    }

    @Bean
    public SimpleMessageListenerContainer replyListenerContainer(
            @NonNull CachingConnectionFactory connectionFactory,
            @NonNull List<Queue> inquiryResponseQueue,
            @NonNull RabbitTemplate rabbitTemplate,
            @NonNull RabbitAdmin rabbitAdmin) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueues(inquiryResponseQueue.get(0));
        container.setMessageListener(rabbitTemplate);
        return container;
    }

    @Bean
    public Queue privateInquiryResponseQueue(
            @NonNull CachingConnectionFactory connectionFactory) {
        return new Queue(privateInquiryResponseQueueName(connectionFactory.getUsername()),
                false,
                true,
                true);
    }

    

}

Error Log:

    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:721) ~[spring-rabbit-2.3.10.jar:2.3.10]
    ... 5 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'broadcastQueue.MYUSER_123' in vhost 'app', class-id=50, method-id=10)
SvenR
  • 39
  • 1
  • 6

1 Answers1

1

autoStartup works fine - something else must be starting the container - add a breakpoint to see what is starting it - are you calling start() on the application context? That will start the container.

Direct reply-to is a special RabbitMQ mode that uses a pseudo queue for replies; for a named reply queue, you need a listener container.

https://docs.spring.io/spring-amqp/docs/current/reference/html/#direct-reply-to

Gary Russell
  • 166,535
  • 14
  • 146
  • 179