View Javadoc

1   /*
2    * $Id: JmsExceptionStrategyTestCase.java 19191 2010-08-25 21:05:23Z 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.integration;
12  
13  import org.mule.api.config.MuleProperties;
14  import org.mule.message.ExceptionMessage;
15  
16  import javax.jms.BytesMessage;
17  import javax.jms.JMSException;
18  import javax.jms.Message;
19  import javax.jms.MessageConsumer;
20  import javax.jms.ObjectMessage;
21  import javax.jms.Session;
22  import javax.jms.TextMessage;
23  
24  import org.apache.commons.lang.SerializationUtils;
25  import org.junit.Test;
26  
27  /**
28   * Tests a transactional exception strategy.
29   */
30  public class JmsExceptionStrategyTestCase extends AbstractJmsFunctionalTestCase
31  {
32      public static final String DEADLETTER_QUEUE_NAME = "dlq";
33  
34      protected String getConfigResources()
35      {
36          return "integration/jms-exception-strategy.xml";
37      }
38  
39      @Test
40      public void testTransactedRedeliveryToDLDestination() throws Exception
41      {
42          send(scenarioDeadLetter);
43          // Verify outbound message did _not_ get delivered.
44          receive(scenarioNotReceive);
45          // Verify message got sent to dead letter queue instead.
46          receive(scenarioDeadLetter);
47      }
48  
49      @Test
50      public void testTransactedRedeliveryToDLDestinationRollback() throws Exception
51      {
52          send(scenarioDeadLetter);
53          // Receive message but roll back transaction.
54          receive(scenarioDeadLetterRollback);
55          // Receive message again and commit transaction.
56          receive(scenarioDeadLetter);
57          // Verify there is no more message to receive.
58          receive(scenarioDeadLetterNotReceive);
59      }
60  
61      Scenario scenarioDeadLetter = new ScenarioDeadLetter();
62  
63      class ScenarioDeadLetter extends ScenarioCommit
64      {
65          // @Override
66          public String getOutputDestinationName()
67          {
68              return DEADLETTER_QUEUE_NAME;
69          }
70  
71          // @Override
72          public Message receive(Session session, MessageConsumer consumer) throws JMSException
73          {
74              // Verify message got sent to dead letter queue.
75              Message message = consumer.receive(getTimeout());
76              assertNotNull(message);
77  
78              Object obj = null;
79              // ExceptionMessage got serialized by JMS provider
80              if (message instanceof BytesMessage)
81              {
82                  byte[] messageBytes = new byte[(int) ((BytesMessage) message).getBodyLength()];
83                  ((BytesMessage) message).readBytes(messageBytes);
84                  obj = SerializationUtils.deserialize(messageBytes);
85              }
86              // ExceptionMessage did not get serialized by JMS provider
87              else if (message instanceof ObjectMessage)
88              {
89                  obj = ((ObjectMessage) message).getObject();
90              }
91              else
92              {
93                  fail("Message is an unexpected type: " + message.getClass().getName());
94              }
95              assertTrue(obj instanceof ExceptionMessage);
96  
97              // The payload should be the original message, not the reply message
98              // since the FTC threw an exception.
99  
100             Object payload = ((ExceptionMessage) obj).getPayload();
101             // Original JMS message was serializable
102             if (payload instanceof TextMessage)
103             {
104                 assertEquals(DEFAULT_INPUT_MESSAGE, ((TextMessage) payload).getText());
105             }
106             // Original JMS message was not serializable and toString() was called instead
107             // (see AbstractExceptionListener.routeException() )
108             else if (payload instanceof String)
109             {
110                 assertEquals(DEFAULT_INPUT_MESSAGE, payload);
111             }
112             else
113             {
114                 fail("Payload is an unexpected type: " + payload.getClass().getName());
115             }
116 
117             String dest = message.getStringProperty(MuleProperties.MULE_ENDPOINT_PROPERTY);
118             // Some JMS providers do not allow custom properties to be set on JMS messages
119             if (dest != null)
120             {
121                 assertEquals("jms://" + DEADLETTER_QUEUE_NAME, dest);
122             }
123 
124             applyTransaction(session);
125             return message;
126         }
127     }
128 
129     Scenario scenarioDeadLetterRollback = new ScenarioDeadLetterRollback();
130 
131     class ScenarioDeadLetterRollback extends ScenarioDeadLetter
132     {
133         // @Override
134         protected void applyTransaction(Session session) throws JMSException
135         {
136             session.rollback();
137         }
138     }
139 
140     Scenario scenarioDeadLetterNotReceive = new ScenarioDeadLetterNotReceive();
141 
142     class ScenarioDeadLetterNotReceive extends ScenarioDeadLetter
143     {
144         // @Override
145         public Message receive(Session session, MessageConsumer consumer) throws JMSException
146         {
147             Message message = consumer.receive(getSmallTimeout());
148             assertNull(message);
149             return message;
150         }
151     }
152 }