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.vm.functional.transactions;
8   
9   import org.hamcrest.core.Is;
10  import org.hamcrest.core.IsInstanceOf;
11  import org.hamcrest.core.IsNull;
12  import org.junit.Before;
13  import org.junit.Test;
14  import org.mule.api.MuleEventContext;
15  import org.mule.api.MuleMessage;
16  import org.mule.api.lifecycle.Callable;
17  import org.mule.api.transformer.TransformerException;
18  import org.mule.config.i18n.CoreMessages;
19  import org.mule.message.DefaultExceptionPayload;
20  import org.mule.message.ExceptionMessage;
21  import org.mule.module.client.MuleClient;
22  import org.mule.tck.junit4.FunctionalTestCase;
23  import org.mule.transformer.AbstractTransformer;
24  import org.mule.transport.NullPayload;
25  import org.mule.util.concurrent.Latch;
26  
27  import static edu.emory.mathcs.backport.java.util.concurrent.TimeUnit.MILLISECONDS;
28  import static org.junit.Assert.assertThat;
29  import static org.junit.Assert.fail;
30  
31  public class VmExceptionStrategyRequestResponseTestCase extends FunctionalTestCase
32  {
33  
34      public static final int TIMEOUT = 3000;
35      public static final int TINY_TIMEOUT = 300;
36      public static final String ORIGINAL_MESSAGE = "some message";
37      private static Latch outboundComponentLatch;
38      private static Latch deadLetterQueueLatch;
39      private static boolean outboundComponentReached;
40  
41      @Override
42      protected String getConfigResources()
43      {
44          return "vm/vm-exception-strategy-config-request-response.xml";
45      }
46  
47      @Before
48      public void setUp() throws Exception
49      {
50          outboundComponentLatch = new Latch();
51          deadLetterQueueLatch = new Latch();
52          outboundComponentReached = false;
53      }
54  
55      @Test
56      public void testDeadLetterQueueWithInboundEndpointException() throws Exception
57      {
58          MuleClient muleClient = new MuleClient(muleContext);
59          MuleMessage response = muleClient.send("vm://in1", ORIGINAL_MESSAGE, null);
60          if (!deadLetterQueueLatch.await(TIMEOUT, MILLISECONDS)) {
61              fail("dead letter queue must be reached");
62          }
63          assertThat(outboundComponentReached, Is.is(false));
64          assertThat(response, IsNull.<Object>notNullValue());
65          assertThat(response.getPayload(),IsInstanceOf.instanceOf(NullPayload.class));
66          assertThat(response.getExceptionPayload(), IsNull.<Object>notNullValue());
67          assertThat(response.getExceptionPayload(), IsInstanceOf.instanceOf(DefaultExceptionPayload.class));
68          assertThat(muleClient.request("vm://out1", TINY_TIMEOUT), IsNull.<Object>nullValue());
69      }
70  
71      @Test
72      public void testDeadLetterQueueWithInboundEndpointResponseException() throws Exception
73      {
74          MuleClient muleClient = new MuleClient(muleContext);
75          MuleMessage response = muleClient.send("vm://in2", ORIGINAL_MESSAGE, null);
76          //TODO PLG - ES - fix this, dlq is failing because transaction was already commited by next flow despite is called using one-way with vm
77          /*if (!deadLetterQueueLatch.await(TIMEOUT, MILLISECONDS)) {
78              fail("dead letter queue must be reached");
79          }*/
80          assertThat(response, IsNull.<Object>notNullValue());
81          assertThat(response.getPayload(),IsInstanceOf.instanceOf(NullPayload.class));
82          assertThat(response.getExceptionPayload(), IsNull.<Object>notNullValue());
83          assertThat(response.getExceptionPayload(), IsInstanceOf.instanceOf(DefaultExceptionPayload.class));
84          assertThat(muleClient.request("vm://out2", TINY_TIMEOUT), IsNull.<Object>nullValue());
85          if (!outboundComponentLatch.await(TINY_TIMEOUT, MILLISECONDS))
86          {
87              fail("outbound component not reached");
88          }
89      }
90  
91      @Test
92      public void testDeadLetterQueueWithComponentException() throws Exception
93      {
94          MuleClient muleClient = new MuleClient(muleContext);
95          MuleMessage response = muleClient.send("vm://in3", ORIGINAL_MESSAGE, null);
96          if (!deadLetterQueueLatch.await(TIMEOUT, MILLISECONDS)) {
97              fail("dead letter queue must be reached");
98          }
99          assertThat(outboundComponentReached, Is.is(false));
100         assertThat(response, IsNull.<Object>notNullValue());
101         assertThat(response.getPayload(),IsInstanceOf.instanceOf(NullPayload.class));
102         assertThat(response.getExceptionPayload(), IsNull.<Object>notNullValue());
103         assertThat(response.getExceptionPayload(), IsInstanceOf.instanceOf(DefaultExceptionPayload.class));
104         assertThat(muleClient.request("vm://out3", TINY_TIMEOUT), IsNull.<Object>nullValue());
105     }
106 
107     @Test
108     public void testDeadLetterQueueWithOutboundEndpointException() throws Exception
109     {
110         MuleClient muleClient = new MuleClient(muleContext);
111         MuleMessage response = muleClient.send("vm://in4", ORIGINAL_MESSAGE, null);
112         if (!deadLetterQueueLatch.await(TIMEOUT, MILLISECONDS)) {
113             fail("dead letter queue must be reached");
114         }
115         assertThat(outboundComponentReached, Is.is(false));
116         assertThat(response, IsNull.<Object>notNullValue());
117         assertThat(response.getPayload(),IsInstanceOf.instanceOf(NullPayload.class));
118         assertThat(response.getExceptionPayload(), IsNull.<Object>notNullValue());
119         assertThat(response.getExceptionPayload(), IsInstanceOf.instanceOf(DefaultExceptionPayload.class));
120         assertThat(muleClient.request("vm://out4", TINY_TIMEOUT), IsNull.<Object>nullValue());
121     }
122 
123     @Test
124     public void testDeadLetterQueueWithOutboundEndpointResponseException() throws Exception
125     {
126         MuleClient muleClient = new MuleClient(muleContext);
127         MuleMessage response = muleClient.send("vm://in5", ORIGINAL_MESSAGE, null);
128         //TODO PLG - ES - fix this issue, the response must have an exception since there was a failire in the flow. It seems that response chain was not executed
129         /*assertThat(response, IsNull.<Object>notNullValue());
130         assertThat(response.getPayload(),IsInstanceOf.instanceOf(NullPayload.class));
131         assertThat(response.getExceptionPayload(), IsNull.<Object>notNullValue());
132         assertThat(response.getExceptionPayload(), IsInstanceOf.instanceOf(DefaultExceptionPayload.class));*/
133         assertThat(muleClient.request("vm://out5", TINY_TIMEOUT), IsNull.<Object>nullValue());
134         if (!outboundComponentLatch.await(TINY_TIMEOUT, MILLISECONDS))
135         {
136             fail("outbound component not reached");
137         }
138         //TODO PLG - ES - fix this issue. dead letter queue component is not reached
139         /*if (!deadLetterQueueLatch.await(TIMEOUT, MILLISECONDS)) {
140             fail("dead letter queue must be reached");
141         }*/
142     }
143 
144     public static class FailingTransformer extends AbstractTransformer
145     {
146 
147         @Override
148         protected Object doTransform(Object src, String enc) throws TransformerException
149         {
150             throw new TransformerException(CoreMessages.failedToBuildMessage(), this);
151         }
152     }
153 
154     public static class DeadLetterQueueComponent implements Callable
155     {
156 
157         public Object onCall(MuleEventContext eventContext) throws Exception
158         {
159             deadLetterQueueLatch.release();
160             MuleMessage message = eventContext.getMessage();
161             assertThat(message, IsNull.<Object>notNullValue());
162             assertThat(message.getExceptionPayload(), IsNull.<Object>nullValue());
163             assertThat(message.getPayload(), IsInstanceOf.instanceOf(ExceptionMessage.class));
164             return eventContext.getMessage();
165         }
166     }
167 
168     public static class OutboundComponent implements Callable
169     {
170 
171         public Object onCall(MuleEventContext eventContext) throws Exception
172         {
173             outboundComponentLatch.release();
174             return eventContext.getMessage();
175         }
176     }
177 }