View Javadoc

1   /*
2    * $Id: ExceptionBasedRouterTestCase.java 22377 2011-07-11 12:41:42Z dirk.olmes $
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.routing.outbound;
12  
13  import org.mule.DefaultMuleEvent;
14  import org.mule.DefaultMuleMessage;
15  import org.mule.MessageExchangePattern;
16  import org.mule.api.MuleEvent;
17  import org.mule.api.MuleException;
18  import org.mule.api.MuleMessage;
19  import org.mule.api.MuleSession;
20  import org.mule.api.endpoint.OutboundEndpoint;
21  import org.mule.api.processor.MessageProcessor;
22  import org.mule.api.routing.CouldNotRouteOutboundMessageException;
23  import org.mule.api.routing.RoutingException;
24  import org.mule.message.DefaultExceptionPayload;
25  import org.mule.routing.LoggingCatchAllStrategy;
26  import org.mule.routing.filters.RegExFilter;
27  import org.mule.tck.MuleTestUtils;
28  import org.mule.tck.junit4.AbstractMuleContextTestCase;
29  
30  import com.mockobjects.dynamic.Mock;
31  
32  import java.util.ArrayList;
33  import java.util.List;
34  
35  import org.junit.Test;
36  
37  import static org.junit.Assert.assertEquals;
38  import static org.junit.Assert.assertNotNull;
39  import static org.junit.Assert.assertNull;
40  import static org.junit.Assert.assertTrue;
41  import static org.junit.Assert.fail;
42  
43  public class ExceptionBasedRouterTestCase extends AbstractMuleContextTestCase
44  {
45      public ExceptionBasedRouterTestCase()
46      {
47          setStartContext(true);
48      }
49  
50      /**
51       * Multiple targets, no failures. MuleEvent dispatched asynchronously, but forced
52       * into sync mode. Test case ends here.
53       */
54      /* TODO MULE-4476
55      @Test
56      public void testSuccessfulExceptionRouterAsynchronous() throws Exception
57      {
58          Mock mockSession = MuleTestUtils.getMockSession();
59          mockSession.matchAndReturn("getFlowConstruct", getTestService());
60  
61          DefaultOutboundRouterCollection messageRouter = new DefaultOutboundRouterCollection();
62          messageRouter.setCatchAllStrategy(new LoggingCatchAllStrategy());
63  
64          OutboundEndpoint endpoint1 = muleContext.getRegistry()
65              .lookupEndpointFactory()
66              .getOutboundEndpoint("test://Dummy1");
67  
68          OutboundEndpoint endpoint2 = muleContext.getRegistry()
69              .lookupEndpointFactory()
70              .getOutboundEndpoint("test://Dummy2");
71  
72          OutboundEndpoint endpoint3 = muleContext.getRegistry()
73              .lookupEndpointFactory()
74              .getOutboundEndpoint("test://Dummy3");
75  
76          Mock mockendpoint1 = RouterTestUtils.getMockEndpoint(endpoint1);
77          Mock mockendpoint2 = RouterTestUtils.getMockEndpoint(endpoint2);
78          Mock mockendpoint3 = RouterTestUtils.getMockEndpoint(endpoint3);
79          ExceptionBasedRouter router = new ExceptionBasedRouter();
80          router.setMuleContext(muleContext);
81          RegExFilter filter = new RegExFilter("(.*) event");
82          router.setFilter(filter);
83          List<MessageProcessor> endpoints = new ArrayList<MessageProcessor>();
84          endpoints.add((OutboundEndpoint) mockendpoint1.proxy());
85          endpoints.add((OutboundEndpoint) mockendpoint2.proxy());
86          endpoints.add((OutboundEndpoint) mockendpoint3.proxy());
87          router.setRoutes(endpoints);
88  
89          assertEquals(filter, router.getFilter());
90  
91          MuleMessage message = new DefaultMuleMessage("test event", muleContext);
92  
93          assertTrue(router.isMatch(message));
94  
95          mockendpoint1.expect("process", RouterTestUtils.getArgListCheckerMuleEvent());
96          MuleEvent result = router.route(new OutboundRoutingTestEvent(message, (MuleSession)mockSession.proxy()));
97          assertNull("Async call should've returned null.", result);
98          mockendpoint1.verify();
99      }
100     */
101 
102     @Test
103     public void testSuccessfulExceptionRouterSynchronous() throws Exception
104     {
105         Mock mockSession = MuleTestUtils.getMockSession();
106         mockSession.matchAndReturn("getFlowConstruct", getTestService());
107 
108         DefaultOutboundRouterCollection messageRouter = new DefaultOutboundRouterCollection();
109         messageRouter.setCatchAllStrategy(new LoggingCatchAllStrategy());
110 
111         OutboundEndpoint endpoint1 =
112             muleContext.getEndpointFactory().getOutboundEndpoint("test://Dummy1?exchangePattern=request-response");
113 
114         OutboundEndpoint endpoint2 =
115             muleContext.getEndpointFactory().getOutboundEndpoint("test://Dummy2?exchangePattern=request-response");
116 
117         OutboundEndpoint endpoint3 =
118             muleContext.getEndpointFactory().getOutboundEndpoint("test://Dummy3?exchangePattern=request-response");
119 
120         Mock mockendpoint1 = RouterTestUtils.getMockEndpoint(endpoint1);
121         Mock mockendpoint2 = RouterTestUtils.getMockEndpoint(endpoint2);
122         Mock mockendpoint3 = RouterTestUtils.getMockEndpoint(endpoint3);
123 
124         ExceptionBasedRouter router = new ExceptionBasedRouter();
125         router.setMuleContext(muleContext);
126         RegExFilter filter = new RegExFilter("(.*) event");
127         router.setFilter(filter);
128         List<MessageProcessor> endpoints = new ArrayList<MessageProcessor>();
129         endpoints.add((OutboundEndpoint) mockendpoint1.proxy());
130         endpoints.add((OutboundEndpoint) mockendpoint2.proxy());
131         endpoints.add((OutboundEndpoint) mockendpoint3.proxy());
132         router.setRoutes(endpoints);
133 
134         assertEquals(filter, router.getFilter());
135 
136         MuleMessage message = new DefaultMuleMessage("test event", muleContext);
137         MuleEvent event = new OutboundRoutingTestEvent(message, null, muleContext);
138         // only one send should be called and succeed, the others should not be
139         // called
140         mockendpoint1.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
141         MuleEvent result = router.route(new OutboundRoutingTestEvent(message, (MuleSession)mockSession.proxy(), muleContext));
142         assertNotNull(result);
143         assertEquals(message, result.getMessage());
144         mockendpoint1.verify();
145     }
146 
147     /**
148      * Both targets fail during dispatch. The first endpoint should be forced into
149      * sync mode.
150      */
151     @Test
152     public void testBothFailing() throws Exception
153     {
154         Mock mockSession = MuleTestUtils.getMockSession();
155         mockSession.matchAndReturn("getFlowConstruct", getTestService());
156 
157         OutboundEndpoint endpoint1 =
158             muleContext.getEndpointFactory().getOutboundEndpoint("test://AlwaysFail");
159 
160         OutboundEndpoint endpoint2 =
161             muleContext.getEndpointFactory().getOutboundEndpoint("test://AlwaysFail");
162 
163         Mock mockendpoint1 = RouterTestUtils.getMockEndpoint(endpoint1);
164         Mock mockendpoint2 = RouterTestUtils.getMockEndpoint(endpoint2);
165 
166         ExceptionBasedRouter router = new ExceptionBasedRouter();
167         router.setMuleContext(muleContext);
168         RegExFilter filter = new RegExFilter("(.*) event");
169         router.setFilter(filter);
170         List<MessageProcessor> endpoints = new ArrayList<MessageProcessor>();
171         endpoints.add((OutboundEndpoint) mockendpoint1.proxy());
172         endpoints.add((OutboundEndpoint) mockendpoint2.proxy());
173         router.setRoutes(endpoints);
174 
175         assertEquals(filter, router.getFilter());
176 
177         MuleMessage message = new DefaultMuleMessage("test event", muleContext);
178 
179         assertTrue(router.isMatch(message));
180 
181         // exception to throw
182         MuleSession session = (MuleSession)mockSession.proxy();
183         MuleEvent eventToThrow = new DefaultMuleEvent(message, MessageExchangePattern.ONE_WAY, session);
184         MuleException rex = new RoutingException(eventToThrow, endpoint1);
185         mockendpoint1.expectAndThrow("process", RouterTestUtils.getArgListCheckerMuleEvent(), rex);
186         mockendpoint2.expectAndThrow("process", RouterTestUtils.getArgListCheckerMuleEvent(), rex);
187         MuleEvent result = null;
188         try
189         {
190             result = router.route(new OutboundRoutingTestEvent(message, session, muleContext));
191             fail("Should have thrown exception as both targets would have failed");
192         }
193         catch (CouldNotRouteOutboundMessageException e)
194         {
195             // expected
196         }
197         assertNull("Async call should've returned null.", result);
198         mockSession.verify();
199 
200         message = new DefaultMuleMessage("test event", muleContext);
201     }
202 
203     /**
204      * The first endpoint fails, second succeeds. Events are being sent
205      * synchronously.
206      */
207     @Test
208     public void testFailFirstSuccessSecondSync() throws Exception
209     {
210         Mock mockSession = MuleTestUtils.getMockSession();
211         mockSession.matchAndReturn("getFlowConstruct", getTestService());
212 
213         OutboundEndpoint endpoint1 = getTestOutboundEndpoint("TestFailEndpoint",
214             "test://Failure?exchangePattern=request-response");
215         OutboundEndpoint endpoint2 = getTestOutboundEndpoint("TestSuccessEndpoint",
216             "test://Success?exchangePattern=request-response");
217         Mock mockendpoint1 = RouterTestUtils.getMockEndpoint(endpoint1);
218         Mock mockendpoint2 = RouterTestUtils.getMockEndpoint(endpoint2);
219 
220         ExceptionBasedRouter router = new ExceptionBasedRouter();
221         router.setMuleContext(muleContext);
222         router.addRoute((OutboundEndpoint) mockendpoint1.proxy());
223         router.addRoute((OutboundEndpoint) mockendpoint2.proxy());
224 
225         MuleMessage message = new DefaultMuleMessage("test event", muleContext);
226         MuleMessage expectedResultMessage = new DefaultMuleMessage("Return event", muleContext);
227         MuleEvent event = new OutboundRoutingTestEvent(expectedResultMessage, null, muleContext);
228 
229         assertTrue(router.isMatch(message));
230 
231         final MuleSession session = (MuleSession)mockSession.proxy();
232         // exception to throw
233         MuleEvent eventToThrow = new DefaultMuleEvent(message, MessageExchangePattern.ONE_WAY, session);
234         MuleException rex = new RoutingException(eventToThrow, endpoint1);
235         // 1st failure
236         mockendpoint1.expectAndThrow("process", RouterTestUtils.getArgListCheckerMuleEvent(), rex);
237         mockendpoint2.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
238         MuleEvent actualResult = router.route(new OutboundRoutingTestEvent(message, session, muleContext));
239         mockendpoint1.verify();
240         mockendpoint2.verify();
241 
242         assertEquals("Got an invalid return message.", expectedResultMessage, actualResult.getMessage());
243     }
244 
245     /**
246      * The first endpoint fails, second succeeds. Events are being forced into a sync
247      * mode, until we reach the last one.
248      */
249     @Test
250     public void testFailFirstSuccessSecondAsync() throws Exception
251     {
252         Mock mockSession = MuleTestUtils.getMockSession();
253         mockSession.matchAndReturn("getFlowConstruct", getTestService());
254 
255         OutboundEndpoint endpoint1 = getTestOutboundEndpoint("TestFailEndpoint",
256             "test://Failure?exchangePattern=request-response");
257         OutboundEndpoint endpoint2 = getTestOutboundEndpoint("TestSuccessEndpoint",
258             "test://Success?exchangePattern=one-way");
259         Mock mockendpoint1 = RouterTestUtils.getMockEndpoint(endpoint1);
260         Mock mockendpoint2 = RouterTestUtils.getMockEndpoint(endpoint2);
261 
262         ExceptionBasedRouter router = new ExceptionBasedRouter();
263         router.setMuleContext(muleContext);
264         router.addRoute((OutboundEndpoint) mockendpoint1.proxy());
265         router.addRoute((OutboundEndpoint) mockendpoint2.proxy());
266 
267         MuleMessage message = new DefaultMuleMessage("test event", muleContext);
268         MuleMessage expectedResultMessage = new DefaultMuleMessage("Return event", muleContext);
269         MuleEvent event = new OutboundRoutingTestEvent(expectedResultMessage, null, muleContext);
270 
271         assertTrue(router.isMatch(message));
272 
273         final MuleSession session = (MuleSession)mockSession.proxy();
274         // exception to throw
275         MuleEvent eventToThrow = new DefaultMuleEvent(message, MessageExchangePattern.ONE_WAY, session);
276         MuleException rex = new RoutingException(eventToThrow, endpoint1);
277 
278         mockendpoint1.expectAndThrow("process", RouterTestUtils.getArgListCheckerMuleEvent(), rex);
279         mockendpoint2.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
280         MuleEvent actualResult = router.route(new OutboundRoutingTestEvent(message, session, muleContext));
281         assertNull("Async call should not return any results.", actualResult);
282 
283         mockendpoint1.verify();
284         mockendpoint2.verify();
285     }
286 
287     /**
288      * The first endpoint contains exception payload in return message, second
289      * succeeds. Events are being sent synchronously.
290      */
291     @Test
292     public void testFirstHadExceptionPayloadSuccessSecondSyncWithExceptionPayload() throws Exception
293     {
294         Mock mockSession = MuleTestUtils.getMockSession();
295         mockSession.matchAndReturn("getFlowConstruct", getTestService());
296 
297         OutboundEndpoint endpoint1 = getTestOutboundEndpoint("TestFailEndpoint",
298             "test://Failure?exchangePattern=request-response");
299         OutboundEndpoint endpoint2 = getTestOutboundEndpoint("TestSuccessEndpoint",
300             "test://Success?exchangePattern=request-response");
301         Mock mockendpoint1 = RouterTestUtils.getMockEndpoint(endpoint1);
302         Mock mockendpoint2 = RouterTestUtils.getMockEndpoint(endpoint2);
303         ExceptionBasedRouter router = new ExceptionBasedRouter();
304         router.setMuleContext(muleContext);
305         router.addRoute((OutboundEndpoint) mockendpoint1.proxy());
306         router.addRoute((OutboundEndpoint) mockendpoint2.proxy());
307 
308         MuleMessage message = new DefaultMuleMessage("test event", muleContext);
309         MuleMessage expectedResultMessage = new DefaultMuleMessage("Return event", muleContext);
310         MuleEvent expectedResultEvent = new OutboundRoutingTestEvent(expectedResultMessage, null, muleContext);
311 
312 
313         assertTrue(router.isMatch(message));
314 
315         // remote endpoint failed and set an exception payload on the returned
316         // message
317         MuleMessage exPayloadMessage = new DefaultMuleMessage("there was a failure", muleContext);
318         exPayloadMessage.setExceptionPayload(new DefaultExceptionPayload(new RuntimeException()));
319         MuleEvent exPayloadMessageEvent = new OutboundRoutingTestEvent(exPayloadMessage, null, muleContext);
320 
321 
322         final MuleSession session = (MuleSession)mockSession.proxy();
323         // 1st failure
324         mockendpoint1.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(),
325             exPayloadMessageEvent);
326         // next endpoint
327         mockendpoint2.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(),
328             expectedResultEvent);
329         MuleEvent actualResult = router.route(new OutboundRoutingTestEvent(message, session, muleContext));
330         mockendpoint1.verify();
331         mockendpoint2.verify();
332 
333         assertEquals("Got an invalid return message.", expectedResultMessage, actualResult.getMessage());
334     }
335 }