View Javadoc

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