How to acknowledge message through program using Spring AMQP/Spring integration

Vijay Srinivasaraghavan picture Vijay Srinivasaraghavan · Oct 31, 2012 · Viewed 8.2k times · Source

1) Server sends a message to client.

2) Inbound channel adapter is configured to wait for "MANUAL" acknowledge mode operation from consumer

3) "TaskBundlereceiver" bean is implementing "ChannelAwareMessageListener" and in the implementation method, I am performing message acknowledgement.

I don't see "TaskBundlereceiver" getting executed. Am I missing something ?

Below is the configuration details of the steps that I have explained.

Appreciate your inputs.

    @Override
    public void onMessage(org.springframework.amqp.core.Message message, Channel channel) throws Exception 
    {
        logger.debug("In onMessage method of the channel aware listener. message =["+message.getBody().toString()+"]");
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
    }

XML Configuration :

    <!-- Channel that receives the task bundle from the server for execution -->
    <int:channel id="fromKServerChannel"/>

    <int-amqp:inbound-channel-adapter id="taskBundleReceiverAdapter"
                                      channel="fromKServerChannel"
                                      error-channel="taskBundleErrorChannel"
                                      acknowledge-mode="MANUAL"
                                      expose-listener-channel="true"
                                      queue-names="kanga_task_queue"
                                      connection-factory="connectionFactory"
                                      concurrent-consumers="20"/>

    <int:chain input-channel="fromKServerChannel" output-channel="nullChannel">
        <int:service-activator ref="taskBundleReceiver" method="onMessage"/>
        <int:service-activator ref="taskBundleExecutor" method="executeBundle"/>
    </int:chain>

Answer

Gary Russell picture Gary Russell · Oct 31, 2012

It doesn't work that way; the listener is the adapter, not the service invoked via the service-activator. The adapter currently does not support passing the channel to the client for manual acks. The expose-listener-channel attribute is for use when using transactions, so a down-stack rabbit template can participate in the transaction.

Why do you want MANUAL acks? AUTO (default) means the ack will be done automatically by the container when the thread returns normally; if your service throws an exception, the message will be nacked.

So, that's how to control the ack.

If you really want to use MANUAL acks, you'll have to use a <rabbit:listener-container/> to invoke your taskBundleReceiver directly. It could then send a message to the executor using a messaging gateway.