View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.jms.redelivery;
8   
9   import org.mule.api.MuleException;
10  import org.mule.api.MuleMessage;
11  import org.mule.api.construct.FlowConstruct;
12  import org.mule.api.endpoint.ImmutableEndpoint;
13  import org.mule.transport.jms.JmsConnector;
14  
15  import java.util.Collections;
16  import java.util.Map;
17  
18  import javax.jms.JMSException;
19  import javax.jms.Message;
20  
21  import org.apache.commons.collections.map.LRUMap;
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  
25  /**
26   * This redelivery handler will keep counting the redelivery attempts for each message redelivered. Used for
27   * providers not implementing the {@code JMSXDeliveryCount} property support.
28   */
29  public class CountingRedeliveryHandler extends AbstractRedeliveryHandler
30  {
31      /**
32       * logger used by this class
33       */
34      protected static final Log logger = LogFactory.getLog(CountingRedeliveryHandler.class);
35  
36      private Map<String, Integer> messages = null;
37  
38      @SuppressWarnings("unchecked")
39      public CountingRedeliveryHandler()
40      {
41          super();
42          messages = Collections.synchronizedMap(new LRUMap(256));
43      }
44  
45      /**
46       * process the redelivered message. If the Jms receiver should process the
47       * message, it should be returned. Otherwise the connector should throw a
48       * <code>MessageRedeliveredException</code> to indicate that the message should
49       * be handled by the connector Exception Handler.
50       * 
51       */
52      @Override
53      public void handleRedelivery(Message message, ImmutableEndpoint endpoint, FlowConstruct flow) throws JMSException, MuleException
54      {
55          final int connectorRedelivery = connector.getMaxRedelivery();
56          if (connectorRedelivery == JmsConnector.REDELIVERY_IGNORE || connectorRedelivery < 0 ) // just in case, for manual setting)
57          {
58              if (logger.isDebugEnabled())
59              {
60                  logger.debug("We were asked to ignore the redelivery count, nothing to do here.");
61              }
62              return;
63          }
64  
65          String id = message.getJMSMessageID();
66  
67          if (id == null)
68          {
69              if (logger.isDebugEnabled())
70              {
71                  logger.debug("Message doesn't have a JMSMessageID set, Mule can't handle redelivery for it. " + message);
72              }
73              return;
74          }
75  
76          Integer redeliveryCount = messages.remove(id);
77          if (redeliveryCount != null)
78          {
79              redeliveryCount += 1; // inc the count
80          }
81  
82          if (redeliveryCount == null)
83          {
84              if (logger.isDebugEnabled())
85              {
86                  logger.debug("Message with id: " + id + " has been redelivered for the first time");
87              }
88              messages.put(id, 1);
89          }
90          else if (redeliveryCount == 1)
91          {
92              if (logger.isDebugEnabled())
93              {
94                  logger.debug("Message with id: " + id + " has been redelivered for the first time");
95              }
96  
97              if (connectorRedelivery == JmsConnector.REDELIVERY_FAIL_ON_FIRST)
98              {
99                  MuleMessage msg = createMuleMessage(message);
100                 throw new MessageRedeliveredException(id, redeliveryCount, connectorRedelivery, endpoint, flow, msg);
101             }
102         }
103         else if (redeliveryCount > connectorRedelivery)
104         {
105             MuleMessage msg = createMuleMessage(message);
106             throw new MessageRedeliveredException(id, redeliveryCount, connectorRedelivery, endpoint, flow, msg);
107         }
108         else
109         {
110             messages.put(id, redeliveryCount);
111             if (logger.isDebugEnabled())
112             {
113                 logger.debug("Message with id: " + id + " has been redelivered " + redeliveryCount + " times");
114             }
115         }
116     }
117 }