View Javadoc

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