Damien Schadeck
Damien Schadeck

Reputation: 1

How to retreive message body on fail on rabbitmq

In Java, with Spring AMQ:

I'm looking for a way to retreive the message body when the message is sent on a exchange that does not exist.

With the confirmCallback, I can get the correlation data ID, the cause of the error but the returned message is empty.

Same using the CorrelationData and the Future, the callback is called as it was a success. So I get nothing.

Is there any way to retreive the message body ?

The idea is not to use any DB to save the message body and the UUID of the correlation data to retreive it in the confirm call back.

This is how I create the connection factory:

CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setUsername(as_userName);
        connectionFactory.setPassword(as_pwd);
        connectionFactory.setVirtualHost(PONOSEnvConst.QUEUE_VHOST);
        connectionFactory.setHost(PONOSEnvConst.URL_SERV_MQ);
        connectionFactory.setPort(PONOSEnvConst.PORT_SERV_MQ);
        connectionFactory.setPublisherReturns(true);
        connectionFactory.setPublisherConfirms(true);

This is for the RabbitTemplate:

RabbitTemplate rabbitTemplate = new RabbitTemplate(ao_factory);

        rabbitTemplate.setMessageConverter(jsonMessageConverter());
        rabbitTemplate.setReturnsCallback(ao_returned -> {
            System.err.println("Returned: " + ao_returned);
        });
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            System.err.println("##### confirm : ##### ack = " + ack //
                + "\n cause = " + cause //
                + "\n data = " + correlationData //
                + "\n returned = " + correlationData.getReturned() //
                + "\n######");
        });

This is the code that send the message on non-existing exchange:

CorrelationData lo_data = new CorrelationData(UUID.randomUUID().toString());
        amqpTemplate.convertAndSend("non-existing-exchange", "", "Message body to an non-existing exchange", lo_data);
        lo_data.getFuture().addCallback(new ListenableFutureCallback<Confirm>()
        {
            @Override
            public void onFailure(Throwable throwable)
            {
                System.err.println("-----> FAIL !");
            }

            @Override
            public void onSuccess(Confirm confirm)
            {
                System.err.println("-----> SUCCESS !");
                System.err.println("-----> " + confirm.isAck()//
                    + "\n" + lo_data.getReturned() ////
                    + "\n" + lo_data.getReturnedMessage() //
                );
            }
        });

The output for the send part:

-----> SUCCESS !

-----> false
null
null

The output for the confirm callback part:

##### confirm : ##### ack = false
 cause = channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'non-existing-exchange' in vhost 'XXX', class-id=60, method-id=40)
 data = CorrelationData [id=4a9dd7a0-27d5-456d-9018-4e7384038730]
 returned = null
######

Upvotes: 0

Views: 63

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121552

There is no Return in case of non-existing exchange. That even mentioned in the docs: https://docs.spring.io/spring-amqp/reference/amqp/template.html#publishing-is-async.

You probably would need to extract that message body into a variable and get access to it from your lo_data.getFuture().addCallback().

Upvotes: 0

Related Questions