View Javadoc

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