1
2
3
4
5
6
7 package org.mule.test.integration.exceptions;
8
9 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
10 import org.hamcrest.core.IsNull;
11 import org.junit.Rule;
12 import org.junit.Test;
13 import org.junit.runners.Parameterized;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.MuleEventContext;
16 import org.mule.api.MuleException;
17 import org.mule.api.MuleMessage;
18 import org.mule.api.client.LocalMuleClient;
19 import org.mule.api.lifecycle.Stoppable;
20 import org.mule.api.processor.MessageProcessor;
21 import org.mule.exception.AbstractMessagingExceptionStrategy;
22 import org.mule.message.ExceptionMessage;
23 import org.mule.tck.AbstractServiceAndFlowTestCase;
24 import org.mule.tck.functional.EventCallback;
25 import org.mule.tck.functional.FunctionalTestComponent;
26 import org.mule.tck.junit4.rule.DynamicPort;
27 import org.mule.transport.NullPayload;
28 import org.mule.transport.email.FixedPortGreenMailSupport;
29 import org.mule.transport.email.functional.AbstractEmailFunctionalTestCase;
30 import org.mule.util.concurrent.Latch;
31
32 import javax.mail.internet.MimeMessage;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.List;
37 import java.util.concurrent.CountDownLatch;
38
39 import static org.hamcrest.core.Is.is;
40 import static org.hamcrest.core.IsInstanceOf.instanceOf;
41 import static org.junit.Assert.*;
42
43 public class ExceptionStrategyCommonScenariosTestCase extends AbstractServiceAndFlowTestCase
44 {
45
46 public static final String MESSAGE_TO_SEND = "A message";
47 public static final String MESSAGE_MODIFIED = "A message with some text added";
48 public static final int TIMEOUT = 5000;
49 private final static Latch endMessageProcessorExecuted = new Latch();
50 @Rule
51 public DynamicPort dynamicPort1 = new DynamicPort("port1");
52
53 @Rule
54 public DynamicPort dynamicPort2 = new DynamicPort("port2");
55
56 @Rule
57 public DynamicPort dynamicPort3 = new DynamicPort("port3");
58
59 @Rule
60 public DynamicPort dynamicPort4 = new DynamicPort("port4");
61
62 @Rule
63 public DynamicPort dynamicPort5 = new DynamicPort("port5");
64
65 @Rule
66 public DynamicPort dynamicPort6 = new DynamicPort("port6");
67
68 public ExceptionStrategyCommonScenariosTestCase(AbstractServiceAndFlowTestCase.ConfigVariant variant, String configResources)
69 {
70 super(variant, configResources);
71 }
72
73 @Parameterized.Parameters
74 public static Collection<Object[]> parameters()
75 {
76 return Arrays.asList(new Object[][]{{AbstractServiceAndFlowTestCase.ConfigVariant.SERVICE, "org/mule/test/integration/exceptions/exception-strategy-common-scenarios-service.xml"},
77 {AbstractServiceAndFlowTestCase.ConfigVariant.FLOW, "org/mule/test/integration/exceptions/exception-strategy-common-scenarios-flow.xml"}});
78 }
79
80 @Test
81 public void testRoutePayloadBeforeException() throws Exception
82 {
83 final Latch messageProcessedLatch = new Latch();
84 FunctionalTestComponent ftc = getFunctionalTestComponent("LastMessageStateRouting");
85 ftc.setEventCallback(new EventCallback()
86 {
87 public void eventReceived(MuleEventContext context, Object component) throws Exception
88 {
89 messageProcessedLatch.release();
90 throw new RuntimeException();
91 }
92 });
93 LocalMuleClient client = muleContext.getClient();
94 client.dispatch("jms://in1?connector=jmsConnector", MESSAGE_TO_SEND, null);
95 if (!messageProcessedLatch.await(TIMEOUT, TimeUnit.MILLISECONDS))
96 {
97 fail("Message never received by mule");
98 }
99 MuleMessage response = client.request("jms://dead.letter1?connector=jmsConnector", TIMEOUT);
100 assertThat(response, IsNull.<Object>notNullValue());
101 assertThat(response.getPayloadAsString(), is(MESSAGE_MODIFIED));
102 }
103
104 @Test
105 public void testRouteOriginalPayload() throws Exception
106 {
107 final Latch messageProcessedLatch = new Latch();
108 FunctionalTestComponent ftc = getFunctionalTestComponent("OriginalMessageRouting");
109 ftc.setEventCallback(new EventCallback()
110 {
111 public void eventReceived(MuleEventContext context, Object component) throws Exception
112 {
113 messageProcessedLatch.release();
114 throw new RuntimeException();
115 }
116 });
117 LocalMuleClient client = muleContext.getClient();
118 client.dispatch("jms://in2?connector=jmsConnector", MESSAGE_TO_SEND, null);
119 if (!messageProcessedLatch.await(TIMEOUT, TimeUnit.MILLISECONDS))
120 {
121 fail("Message never received by mule");
122 }
123 MuleMessage response = client.request("jms://dead.letter2?connector=jmsConnector", TIMEOUT);
124 assertThat(response, IsNull.<Object>notNullValue());
125 assertThat(response.getPayloadAsString(), is(MESSAGE_TO_SEND));
126 }
127
128 @Test
129 public void testRouteByExceptionType() throws Exception
130 {
131 final CountDownLatch messageProcessedLatch = new CountDownLatch(3);
132 FunctionalTestComponent ftc = getFunctionalTestComponent("RouteByExceptionType");
133 ftc.setEventCallback(new EventCallback()
134 {
135 public void eventReceived(MuleEventContext context, Object component) throws Exception
136 {
137 messageProcessedLatch.countDown();
138 throw new RuntimeException();
139 }
140 });
141 LocalMuleClient client = muleContext.getClient();
142 client.dispatch("jms://in3?connector=jmsConnector", MESSAGE_TO_SEND, null);
143 if (!messageProcessedLatch.await(TIMEOUT, java.util.concurrent.TimeUnit.MILLISECONDS))
144 {
145 fail("Message never received by mule");
146 }
147 MuleMessage response = client.request("jms://dead.letter3?connector=jmsConnector", TIMEOUT);
148 assertThat(response, IsNull.<Object>notNullValue());
149 assertThat(response.getPayloadAsString(), is(MESSAGE_TO_SEND));
150 assertThat(client.request("jms://exceptions?connector=jmsConnector", TIMEOUT), IsNull.<Object>notNullValue());
151 assertThat(client.request("jms://exceptions?connector=jmsConnector", TIMEOUT), IsNull.notNullValue());
152 MuleMessage exceptionResponse = client.request("jms://exceptions?connector=jmsConnector", TIMEOUT);
153 assertThat(exceptionResponse, IsNull.<Object>notNullValue());
154 assertThat(exceptionResponse.getPayload(), instanceOf(ExceptionMessage.class));
155 }
156
157 @Test
158 public void testPreservePayloadExceptionStrategy() throws Exception
159 {
160 LocalMuleClient client = muleContext.getClient();
161 MuleMessage response = client.send("vm://in4", MESSAGE_TO_SEND, null, TIMEOUT);
162 assertThat(response, IsNull.<Object>notNullValue());
163 assertThat(response.getPayloadAsString(), is(MESSAGE_MODIFIED));
164 }
165
166
167 @Test(expected = org.mule.api.transport.NoReceiverForEndpointException.class)
168 public void testStopFlowBasedOnExceptionType() throws Throwable
169 {
170 LocalMuleClient client = muleContext.getClient();
171 MuleMessage response = client.send("vm://in5", MESSAGE_TO_SEND, null, TIMEOUT);
172 assertThat((NullPayload) response.getPayload(), is(NullPayload.getInstance()));
173 assertThat(response.getExceptionPayload(), IsNull.<Object>notNullValue());
174 try
175 {
176 client.send("vm://in5", MESSAGE_TO_SEND, null, TIMEOUT);
177 }
178 catch (Exception e)
179 {
180 throw e.getCause();
181 }
182 }
183
184 @Test
185 public void testRollbackTransactionAndSendAnEmail() throws Exception
186 {
187 if (variant.equals(ConfigVariant.SERVICE))
188 {
189
190 return;
191 }
192 FixedPortGreenMailSupport greenMailSupport = new FixedPortGreenMailSupport(dynamicPort2.getNumber());
193
194 List<Integer> ports = new ArrayList<Integer>(6);
195 ports.add(dynamicPort1.getNumber());
196 ports.add(dynamicPort2.getNumber());
197 ports.add(dynamicPort3.getNumber());
198 ports.add(dynamicPort4.getNumber());
199 ports.add(dynamicPort5.getNumber());
200 ports.add(dynamicPort6.getNumber());
201
202 greenMailSupport.startServers(ports);
203 LocalMuleClient client = muleContext.getClient();
204 client.dispatch("jms://in6?connector=jmsConnectorNoRedelivery", MESSAGE_TO_SEND, null);
205 endMessageProcessorExecuted.await(TIMEOUT, TimeUnit.MILLISECONDS);
206 MuleMessage response = client.request("jms://in6?connector=jmsConnectorNoRedelivery", TIMEOUT);
207 assertThat(response, IsNull.<Object>notNullValue());
208 assertThat(response.getPayloadAsString(), is(MESSAGE_TO_SEND));
209 greenMailSupport.getServers().waitForIncomingEmail(AbstractEmailFunctionalTestCase.DELIVERY_DELAY_MS, 1);
210 MimeMessage[] messages = greenMailSupport.getServers().getReceivedMessages();
211 assertNotNull("did not receive any messages", messages);
212 assertEquals("did not receive 1 mail", 1, messages.length);
213 }
214
215 public static class EndMessageProcessor implements MessageProcessor
216 {
217
218 public MuleEvent process(MuleEvent event) throws MuleException
219 {
220 endMessageProcessorExecuted.release();
221 if (event.getFlowConstruct() instanceof Stoppable)
222 {
223 ((Stoppable)event.getFlowConstruct()).stop();
224 }
225 return event;
226 }
227 }
228
229 public static class PreservePayloadExceptionStrategy extends AbstractMessagingExceptionStrategy
230 {
231 @Override
232 public MuleEvent handleException(Exception e, MuleEvent event)
233 {
234 Object payloadBeforeException = event.getMessage().getPayload();
235 MuleEvent resultEvent = super.handleException(e, event);
236 resultEvent.getMessage().setPayload(payloadBeforeException);
237 return resultEvent;
238 }
239 }
240 }