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.test.integration.routing.outbound;
8   
9   import org.mule.api.MuleException;
10  import org.mule.api.MuleMessage;
11  import org.mule.api.construct.FlowConstruct;
12  import org.mule.api.endpoint.OutboundEndpoint;
13  import org.mule.api.processor.MessageProcessor;
14  import org.mule.api.processor.MessageProcessorChain;
15  import org.mule.api.routing.RoutePathNotFoundException;
16  import org.mule.api.routing.filter.Filter;
17  import org.mule.construct.SimpleFlowConstruct;
18  import org.mule.routing.ChoiceRouter;
19  import org.mule.routing.MessageProcessorFilterPair;
20  import org.mule.routing.filters.ExpressionFilter;
21  import org.mule.routing.filters.RegExFilter;
22  import org.mule.tck.junit4.FunctionalTestCase;
23  
24  import org.junit.Test;
25  
26  import static org.junit.Assert.assertEquals;
27  import static org.junit.Assert.assertNotNull;
28  import static org.junit.Assert.assertTrue;
29  
30  public class ChoiceRouterTestCase extends FunctionalTestCase
31  {
32      private static final String WITH_DEFAULT_ROUTE_CHANNEL = "vm://with-default-route.in";
33      private static final String WITHOUT_DEFAULT_ROUTE_CHANNEL = "vm://without-default-route.in";
34  
35      public ChoiceRouterTestCase()
36      {
37          setDisposeContextPerClass(true);
38      }
39  
40      @Override
41      protected String getConfigResources()
42      {
43          return "org/mule/test/integration/routing/outbound/choice-router-test.xml";
44      }
45  
46      /**
47       * Check that the choice router was assembled correctly by the BDP machinery
48       */
49      @Test
50      public void filterReferenceShouldCreateFilterWithRegexFilterAndOutboundEndpointChain()
51      {
52          ChoiceRouter router = findChoiceRouterInFlow("without-default-route");
53          MessageProcessorFilterPair pair = router.getConditionalMessageProcessors().get(0);
54          assertIsRegExFilterWithPattern(pair.getFilter(), "apple");
55          assertMessageChainIsOutboundEndpoint(pair.getMessageProcessor(), "vm://fruit-channel.in");
56      }
57  
58      /**
59       * Check that the choice router was assembled correctly by the BDP machinery
60       */
61      @Test
62      public void embeddedFilterShouldCreatePairWithFilterAndOtherConfiguredMPsAsChain()
63      {
64          ChoiceRouter router = findChoiceRouterInFlow("with-default-route");
65  
66          MessageProcessorFilterPair firstPair = router.getConditionalMessageProcessors().get(0);
67          assertIsRegExFilterWithPattern(firstPair.getFilter(), "apple");
68          assertMessageChainIsOutboundEndpoint(firstPair.getMessageProcessor(), "vm://fruit-channel.in");
69  
70          MessageProcessorFilterPair secondPair = router.getConditionalMessageProcessors().get(1);
71          assertIsRegExFilterWithPattern(secondPair.getFilter(), "turnip");
72          assertMessageChainIsOutboundEndpoint(secondPair.getMessageProcessor(), "vm://veggie-channel.in");
73  
74          MessageProcessorFilterPair thirdPair = router.getConditionalMessageProcessors().get(2);
75          assertIsExpressionFilterWithExpressionAndEvaluator(thirdPair.getFilter(), ".*berry", "regex");
76          assertMessageChainIsOutboundEndpoint(thirdPair.getMessageProcessor(), "vm://fruit-channel.in");
77      }
78  
79      @Test
80      public void sendToInvalidRouteWithoutDefaultRouteShouldThrowException() throws Exception
81      {
82          MuleMessage result = muleContext.getClient().send(WITHOUT_DEFAULT_ROUTE_CHANNEL, "bad", null);
83          assertNotNull(result);
84          assertNotNull("should have got a MuleException", result.getExceptionPayload());
85          assertNotNull(result.getExceptionPayload().getException() instanceof MuleException);
86          assertNotNull(result.getExceptionPayload().getRootException() instanceof RoutePathNotFoundException);
87      }
88  
89      @Test
90      public void sendToValidRouteShouldReturnValidResult() throws Exception
91      {
92          MuleMessage result = muleContext.getClient().send(WITHOUT_DEFAULT_ROUTE_CHANNEL, "apple", null);
93          assertEquals("apple:fruit:fruit", result.getPayloadAsString());
94      }
95  
96      @Test
97      public void sendToAppleRouteShouldHitFruitService() throws Exception
98      {
99          MuleMessage result = muleContext.getClient().send(WITH_DEFAULT_ROUTE_CHANNEL, "apple", null);
100         assertEquals("apple:fruit:fruit", result.getPayloadAsString());
101     }
102 
103     @Test
104     public void sendToTurnipRouteShouldHitVeggieService() throws Exception
105     {
106         MuleMessage result = muleContext.getClient().send(WITH_DEFAULT_ROUTE_CHANNEL, "turnip", null);
107         assertEquals("turnip:veggie:veggie", result.getPayloadAsString());
108     }
109 
110     @Test
111     public void sendToBlueberryRouteShouldHitFruitService() throws Exception
112     {
113         MuleMessage result = muleContext.getClient().send(WITH_DEFAULT_ROUTE_CHANNEL, "blueberry", null);
114         assertEquals("blueberry:fruit:fruit", result.getPayloadAsString());
115     }
116 
117     @Test
118     public void sendToInvalidRouteShouldHitDefaultRoute() throws Exception
119     {
120         MuleMessage result = muleContext.getClient().send(WITH_DEFAULT_ROUTE_CHANNEL, "car", null);
121         assertEquals("car:default:default", result.getPayloadAsString());
122     }
123 
124     private ChoiceRouter findChoiceRouterInFlow(String flowName)
125     {
126         SimpleFlowConstruct flow = lookupSimpleFlowConstruct(flowName);
127         return getChoiceRouter(flow);
128     }
129 
130     private SimpleFlowConstruct lookupSimpleFlowConstruct(String flowConstructName)
131     {
132         FlowConstruct flow = muleContext.getRegistry().lookupFlowConstruct(flowConstructName);
133         assertNotNull(flow);
134         assertTrue(flow instanceof SimpleFlowConstruct);
135         return (SimpleFlowConstruct) flow;
136     }
137 
138     private ChoiceRouter getChoiceRouter(SimpleFlowConstruct flowConstruct)
139     {
140         MessageProcessor routerMessageProcessor = flowConstruct.getMessageProcessors().get(0);
141         assertTrue(routerMessageProcessor instanceof ChoiceRouter);
142         return (ChoiceRouter) routerMessageProcessor;
143     }
144 
145     private void assertIsRegExFilterWithPattern(Filter filter, String pattern)
146     {
147         assertTrue(filter instanceof RegExFilter);
148 
149         RegExFilter regExFilter = (RegExFilter) filter;
150         assertEquals(regExFilter.getPattern(), pattern);
151     }
152 
153     private void assertIsExpressionFilterWithExpressionAndEvaluator(Filter filter, String expression, String evaluator)
154     {
155         assertTrue(filter instanceof ExpressionFilter);
156 
157         ExpressionFilter expressionFilter = (ExpressionFilter) filter;
158         assertEquals(expression, expressionFilter.getExpression());
159         assertEquals(evaluator, expressionFilter.getEvaluator());
160     }
161 
162     private void assertMessageChainIsOutboundEndpoint(MessageProcessor processor, String expectedAddress)
163     {
164         assertTrue(processor instanceof MessageProcessorChain);
165         MessageProcessorChain chain = (MessageProcessorChain) processor;
166 
167         MessageProcessor firstInChain = chain.getMessageProcessors().get(0);
168         assertTrue(firstInChain instanceof OutboundEndpoint);
169         OutboundEndpoint endpoint = (OutboundEndpoint) firstInChain;
170 
171         String address = endpoint.getAddress();
172         assertEquals(expectedAddress, address);
173     }
174 }