title: Spring AMQP - How to confirm that a message is delivered and Routed successfully?
body: <p>I am looking for a way to delivery a message, and once the message is delivered (and routed) successfully, i need to perform some operations.</p>
  
  <p>I have enabled publisher confirms and returns by:</p>
  
  <pre><code>spring.rabbitmq.publisher-confirm-type=correlated
  spring.rabbitmq.publisher-returns=true
  </code></pre>
  
  <p>I have configured return and confirm callback on the rabbit template:</p>
  
  <pre><code>rabbitTemplate.setMandatory(true);
  rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -&gt; {
    System.out.println("Message returned");
  });
  rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -&gt; {
    System.out.println("confirm"); //correlationData.returnedMessage has the original message
  });
  </code></pre>
  
  <p>Here is my publish code:</p>
  
  <pre><code>CorrelationData crd = new CorrelationData(UUID.randomUUID().toString());
  rabbitTemplate.convertAndSend("X-ORDERS", "ORDER_PLACED", request, crd);
  
  crd.getFuture().addCallback(new ListenableFutureCallback&lt;Confirm&gt;() {
    @Override
    public void onFailure(Throwable throwable) {
      log.info("Failure received");
    }
  
    @Override
    public void onSuccess(Confirm confirm) {
      if(confirm.isAck()){
      log.info("Success received");
      doSomethingAfterSuccess();
    }}
  });
  </code></pre>
  
  <p>Now, when i publish a message that is unable to route the message :-</p>
  
  <ol>
  <li><p>rabbitTemplate's returnCallBack AND confirmCallBack are also being<br>
  called</p></li>
  <li><p>the onSuccess(..) of the correlationData is still called with
  isAck() = true</p></li>
  </ol>
  
  <p>So, how can I check if the message is delivered successfully and routed? </p>
  
  <p>EDIT: Found solution. The publish code :</p>
  
  <pre><code>CorrelationData crd = new CorrelationData(UUID.randomUUID().toString());
      rabbitTemplate.convertAndSend("X-ORDERS", "ORDER_PLACED", request, crd);
  
      crd.getFuture().addCallback(new ListenableFutureCallback&lt;Confirm&gt;() {
        @Override
        public void onFailure(Throwable throwable) {
          log.info("Failure received");
        }
  
        @Override
        public void onSuccess(Confirm confirm) {
          if(confirm.isAck() &amp;&amp; crd.getReturnedMessage == null){
          log.info("Success received");
          doSomethingAfterSuccess();
        }}
      });
  </code></pre>
  
  <p>basically changed the condition in onSuccess to "confirm.isAck() &amp;&amp; crd.getReturnedMessage == null"</p>