Search code examples
javaapache-camelamq

How to process message just before it send to DLQ


I am using the following server side re-delivery configurations

 <plugins>
    <redeliveryPlugin fallbackToDeadLetter="true" sendToDlqIfMaxRetriesExceeded="true">
        <redeliveryPolicyMap>
            <redeliveryPolicyMap>
                <redeliveryPolicyEntries>
                    <redeliveryPolicy 
                        queue = "com.api.RequestQueue.v1"
                        maximumRedeliveries="20"                        
                        initialRedeliveryDelay="60000" 
                        redeliveryDelay="60000" />

                    <redeliveryPolicy 
                        queue = "com.api.RequestQueue.v2"
                        maximumRedeliveries="10"                        
                        initialRedeliveryDelay="30000" 
                        redeliveryDelay="30000" />
                    <redeliveryPolicy 
                        queue = "com.api.ResponseQueue.v1"
                        maximumRedeliveries="3"                         
                        initialRedeliveryDelay="34000" 
                        redeliveryDelay="34000" />                          
                </redeliveryPolicyEntries>
            </redeliveryPolicyMap>
        </redeliveryPolicyMap>
    </redeliveryPlugin>
</plugins>

How to set a custom end point to process the failed message after retries and just before it send to the DLQ? I did refer the following links but couldn't find anything mentioned about server side or redeliveryPlugin configurations

1.dead-letter-channel

2.logging-camel-exceptions-and-sending-to-the-dead-letter-channel


Solution

  • I am using spring but the re-delivery configurations are in a separate broker container, which can't change at present.

    But the following configuration works.

    Route:

         public class MyMessageRoute extends RouteBuilder {
           public void configure() throws Exception {
               onException(Exception.class)
                .handled(true)
                .bean(PreDLQLogWriter.class) ;
    
               from(fromQueueName).id("RouteId")
                .transacted()
                //process message 
    
                ;
           }}
    
    public class PreDLQLogWriter {
    private static final org.slf4j.Logger LOG = 
                     org.slf4j.LoggerFactory.getLogger( PreDLQLogWriter.class ); 
    
    int configuredDeliveryCount = maximumRedeliveries+1;
    public void logMessageDetails(Exchange exchange) throws Exception {
    
      int actualDeliveryCount = exchange.getIn().getHeader("JMSXDeliveryCount") 
                       != null ? exchange.getIn().getHeader("JMSXDeliveryCount", 
                        Integer.class) : 0 ;
      if(actualDeliveryCount = configuredDeliveryCount) {
                 LOG.info(" Pre-DLQ Log: Log the message with message id ");
       }}