5
respostas

Failed to declare queue(s):[pagamento.datalhes-pedido]

Após fazer as implementações da aula 3, estou com erro ao executar a aplicação Pedido-ms:

2024-10-19 14:55:35.834  INFO 33100 --- [  restartedMain] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [localhost:5672]
2024-10-19 14:55:35.877  INFO 33100 --- [  restartedMain] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#307c9bf0:0/SimpleConnection@59b011c [delegate=amqp://guest@127.0.0.1:5672/, localPort= 54595]
2024-10-19 14:55:35.881  INFO 33100 --- [  restartedMain] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (pagamentos.detalhes-pedido) durable:false, auto-delete:false, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
2024-10-19 14:55:35.917  WARN 33100 --- [ntContainer#0-1] o.s.a.r.listener.BlockingQueueConsumer   : Failed to declare queue: pagamento.datalhes-pedido
2024-10-19 14:55:35.920  WARN 33100 --- [ntContainer#0-1] o.s.a.r.listener.BlockingQueueConsumer   : Queue declaration failed; retries left=3

org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[pagamento.datalhes-pedido]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:743) ~[spring-rabbit-2.4.4.jar:2.4.4]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.passiveDeclarations(BlockingQueueConsumer.java:620) ~[spring-rabbit-2.4.4.jar:2.4.4]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:607) ~[spring-rabbit-2.4.4.jar:2.4.4]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1375) ~[spring-rabbit-2.4.4.jar:2.4.4]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1220) ~[spring-rabbit-2.4.4.jar:2.4.4]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.io.IOException: null

Resumindo as mensagens mais relevantes da pilha exception:

Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'pagamento.datalhes-pedido' in vhost '/', class-id=50, method-id=10)

2024-10-19 14:55:45.932  WARN 33100 --- [ntContainer#0-1] o.s.a.r.listener.BlockingQueueConsumer   : Failed to declare queue: pagamento.datalhes-pedido
2024-10-19 14:55:45.933  WARN 33100 --- [ntContainer#0-1] o.s.a.r.listener.BlockingQueueConsumer   : Queue declaration failed; retries left=1
5 respostas

MInha classe PedidoAMQPConfiguration

package br.com.alurafood.pedidos.amqp;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PedidoAMQPConfiguration {

    @Bean
    public Jackson2JsonMessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public RabbitTemplate rabbitTemplate(
            ConnectionFactory connectionFactory,
            Jackson2JsonMessageConverter messageConverter
    ) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(messageConverter);
        return rabbitTemplate;
    }

    @Bean
    public Queue filaDetalhesPedido() {
        return QueueBuilder.nonDurable("pagamentos.detalhes-pedido").build();
    }

    @Bean
    public FanoutExchange fanoutExchange() {
        return ExchangeBuilder.fanoutExchange("pagamentos.exchange").build();
    }

    @Bean
    public Binding bindPagamentoPedido(FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(filaDetalhesPedido()).to(fanoutExchange);
    }

    @Bean
    public RabbitAdmin criaRabbitAdmin(ConnectionFactory conn) {
        return new RabbitAdmin(conn);
    }

    @Bean
    public ApplicationListener<ApplicationReadyEvent> inicializaAdmin(RabbitAdmin rabbitAdmin) {
        return event -> rabbitAdmin.initialize();
    }
}

No console do docker do rabbitmq loga isso:

2024-10-20 12:07:19.166155+00:00 [info] <0.1770.0> closing AMQP connection <0.1770.0> (172.17.0.1:55634 -> 172.17.0.2:5672 - rabbitConnectionFactory#6f20542e:0, vhost: '/', user: 'guest')
2024-10-20 12:29:13.863942+00:00 [error] <0.1690.0> Channel error on connection <0.1681.0> (172.17.0.1:36420 -> 172.17.0.2:5672, vhost: '/', user: 'guest'), channel 1:
2024-10-20 12:29:13.863942+00:00 [error] <0.1690.0> operation basic.publish caused a channel exception not_found: no exchange 'pagamento.exchange' in vhost '/'

Minha classe PagamentoListener

package br.com.alurafood.pedidos.amqp;

import br.com.alurafood.pedidos.dto.PagamentoDto;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

@Component
public class PagamentoListener {

    @RabbitListener(queues = "pagamentos.datalhes-pedido")
    public void recebeMensagem(@Payload PagamentoDto pagamento) {
        String mensagem = """
                ---------------------------------------
                Dados do pagamento: %s
                Número do Pedido: %s
                Cliente: %s
                Valor R$: %s
                Status: %s
                ----------------------------------------
                """.formatted(pagamento.getId(), pagamento.getPedidoId(), pagamento.getNome(), pagamento.getValor(), pagamento.getStatus());
        System.out.println("Recebi a mensagem");
        System.out.println(mensagem);
    }

}

Só pra constar, na classe AvaliacaoAMQPConfiguration do projeto Pagamento-ms eu declarei o nome da FanoutExchange como "pagamentos.exchange" ao invés de ""pagamentos.ex"

Oi, Cleyton! Tudo bem?

Sobre sua última dúvida, o problema aqui é que o RabbitMQ não está encontrando a fila ou a exchange que você declarou. Isso pode estar relacionado ao nome incorreto da exchange e ao nome da fila em seu código.

Para resolver, faça os ajustes a seguir:

  1. Verifique a nomenclatura da exchange que você criou na classe PedidoAMQPConfiguration. Certifique-se de que o nome dela seja exatamente o mesmo que o declarado no outro serviço. No seu código, você usou "pagamentos.exchange", mas na classe AvaliacaoAMQPConfiguration mencionou que o nome da exchange é "pagamentos.ex". Corrija para garantir que ambos os serviços estão referenciando o mesmo nome.

  2. O erro de declaração da fila pode ser um erro de digitação no nome da fila. Você declarou a fila como "pagamentos.detalhes-pedido", mas no log o erro está relacionado à fila "pagamento.datalhes-pedido" (observe o erro na palavra datalhes).

Ajuste o nome da fila corretamente para "pagamentos.detalhes-pedido" em todos os lugares.

Veja como deve ficar:

@Bean
public Queue filaDetalhesPedido() {
    return QueueBuilder.nonDurable("pagamentos.detalhes-pedido").build();
}

Também certifique-se de que o nome da exchange seja consistente:

@Bean
public FanoutExchange fanoutExchange() {
    return ExchangeBuilder.fanoutExchange("pagamentos.exchange").build();
}

Fico à disposição. Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.