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.mule.model;
8   
9   import org.mule.RequestContext;
10  import org.mule.api.MuleException;
11  import org.mule.api.config.MuleProperties;
12  import org.mule.api.model.EntryPointResolverSet;
13  import org.mule.model.resolvers.ArrayEntryPointResolver;
14  import org.mule.model.resolvers.EntryPointNotFoundException;
15  import org.mule.model.resolvers.LegacyEntryPointResolverSet;
16  import org.mule.tck.junit4.AbstractMuleContextTestCase;
17  import org.mule.tck.testmodels.fruit.Apple;
18  import org.mule.tck.testmodels.fruit.Banana;
19  import org.mule.tck.testmodels.fruit.Fruit;
20  import org.mule.tck.testmodels.fruit.FruitBowl;
21  import org.mule.tck.testmodels.fruit.FruitCleaner;
22  import org.mule.tck.testmodels.fruit.FruitLover;
23  import org.mule.tck.testmodels.fruit.Kiwi;
24  import org.mule.tck.testmodels.fruit.Orange;
25  import org.mule.tck.testmodels.fruit.WaterMelon;
26  
27  import java.util.Arrays;
28  
29  import org.junit.Test;
30  
31  import static org.junit.Assert.assertFalse;
32  import static org.junit.Assert.assertTrue;
33  import static org.junit.Assert.fail;
34  
35  public class LegacyEntryPointResolverTestCase extends AbstractMuleContextTestCase
36  {
37  
38      /** Name of the method override property on the event. */
39      private static final String METHOD_PROPERTY_NAME = MuleProperties.MULE_METHOD_PROPERTY;
40  
41      /** Name of the non-existent method. */
42      private static final String INVALID_METHOD_NAME = "nosuchmethod";
43  
44      @Test
45      public void testExplicitMethodMatch() throws Exception
46      {
47          try
48          {
49              LegacyEntryPointResolverSet resolver = new LegacyEntryPointResolverSet();
50              resolver.invoke(new WaterMelon(), getTestEventContext("blah"));
51          }
52          catch (MuleException e)
53          {
54              fail("Test should have passed: " + e);
55          }
56      }
57  
58      @Test
59      public void testExplicitMethodMatchComplexObject() throws Exception
60      {
61          try
62          {
63              LegacyEntryPointResolverSet resolver = new LegacyEntryPointResolverSet();
64              resolver.invoke(new FruitBowl(), getTestEventContext(new FruitLover("Mmmm")));
65          }
66          catch (MuleException e)
67          {
68              fail("Test should have passed: " + e);
69          }
70      }
71  
72      @Test
73      public void testExplicitMethodMatchSetArrayFail() throws Exception
74      {
75          try
76          {
77              LegacyEntryPointResolverSet resolver = new LegacyEntryPointResolverSet();
78              resolver.invoke(new FruitBowl(), getTestEventContext(new Fruit[]{new Apple(), new Orange()}));
79              fail("Test should have failed because the arguments were not wrapped properly: ");
80          }
81          catch (MuleException e)
82          {
83              //expected
84          }
85      }
86  
87      @Test
88      public void testExplicitMethodMatchSetArrayPass() throws Exception
89      {
90          try
91          {
92              LegacyEntryPointResolverSet resolver = new LegacyEntryPointResolverSet();
93              resolver.invoke(new FruitBowl(), getTestEventContext(new Object[]{new Fruit[]{new Apple(), new Orange()}}));
94          }
95          catch (MuleException e)
96          {
97              fail("Test should have passed: " + e);
98          }
99      }
100 
101     /* this tests the same as above except it uses the {@link ArrayEntryPointResolver} and does not wrap the args with an array
102      */
103     @Test
104     public void testExplicitMethodMatchSetArrayPassUsingExplicitResolver() throws Exception
105     {
106         try
107         {
108             LegacyEntryPointResolverSet resolver = new LegacyEntryPointResolverSet();
109             resolver.addEntryPointResolver(new ArrayEntryPointResolver());
110             resolver.invoke(new FruitBowl(), getTestEventContext(new Fruit[]{new Apple(), new Orange()}));
111         }
112         catch (MuleException e)
113         {
114             fail("Test should have passed: " + e);
115         }
116     }
117 
118 //    public ComponentMethodMapping[] getComponentMappings()
119 //    {
120 //        ComponentMethodMapping[] mappings = new ComponentMethodMapping[5];
121 //        mappings[0] = new ComponentMethodMapping(WaterMelon.class, "myEventHandler", MuleEvent.class);
122 //        mappings[1] = new ComponentMethodMapping(FruitBowl.class, "consumeFruit", FruitLover.class);
123 //        // see testArrayArgumentResolution
124 //        mappings[2] = new ComponentMethodMapping(FruitBowl.class, "setFruit", Fruit[].class);
125 //        // see testListArgumentResolution
126 //        mappings[3] = new ComponentMethodMapping(FruitBowl.class, "setFruit", Collection.class);
127 //        mappings[4] = new ComponentMethodMapping(Banana.class, "peelEvent", EventObject.class);
128 //
129 //        // TODO This fails because "implementation" can no longer be a container reference, it must be
130 //        // an actual object and InvocationHandler does not have a default constructor.
131 //
132 //        // test proxy objects
133 //        //mappings[5] = new ComponentMethodMapping(InvocationHandler.class, "invoke", FruitLover.class, true);
134 //
135 //        return mappings;
136 //    }
137 
138 //    @Override
139 //    public UMODescriptor getDescriptorToResolve(String className) throws Exception
140 //    {
141 //        UMODescriptor descriptor = super.getDescriptorToResolve(className);
142 //        descriptor.setInboundRouter(new DefaultInboundRouterCollection());
143 //        Endpoint endpoint = new MuleEndpoint("test://foo", true);
144 //
145 //        if (className.equals(FruitBowl.class.getName()))
146 //        {
147 //            endpoint.setTransformers(CollectionUtils.singletonList(new ObjectToFruitLover()));
148 //            descriptor.getInboundRouter().addEndpoint(endpoint);
149 //        }
150 //        else if (className.equals(InvocationHandler.class.getName()))
151 //        {
152 //            endpoint.setTransformers(CollectionUtils.singletonList(new ObjectToFruitLover()));
153 //            descriptor.getInboundRouter().addEndpoint(endpoint);
154 //        }
155 //        return descriptor;
156 //    }
157 
158     /**
159      * Tests entrypoint discovery when there is more than one discoverable method
160      * with MuleEventContext parameter.
161      */
162     @Test
163     public void testFailEntryPointMultiplePayloadMatches() throws Exception
164     {
165         EntryPointResolverSet resolverSet = new LegacyEntryPointResolverSet();
166 
167         try
168         {
169             RequestContext.setEvent(getTestEvent("Hello"));
170             resolverSet.invoke(new MultiplePayloadsTestObject(), RequestContext.getEventContext());
171             fail("Should have failed to find entrypoint.");
172         }
173         catch (EntryPointNotFoundException itex)
174         {
175             // expected
176         }
177     }
178 
179     /**
180      * If there was a method parameter specified to override the discovery mechanism
181      * and no such method exists, an exception should be thrown, and no fallback to
182      * the default discovery should take place.
183      */
184     @Test
185     public void testMethodOverrideDoesNotFallback() throws Exception
186     {
187         EntryPointResolverSet resolverSet = new LegacyEntryPointResolverSet();
188         RequestContext.setEvent(getTestEvent(new FruitLover("Yummy!")));
189 
190         // those are usually set on the endpoint and copied over to the message
191         final String methodName = "nosuchmethod";
192         final String propertyName = MuleProperties.MULE_METHOD_PROPERTY;
193         RequestContext.getEventContext().getMessage().setOutboundProperty(propertyName, methodName);
194 
195         resolverSet.invoke(new FruitBowl(), RequestContext.getEventContext());
196         // fail("Should have failed to find an entrypoint.");
197     }
198 
199     /**
200      * If there was a method parameter specified to override the discovery mechanism
201      * and a Callable instance is serving the request, call the Callable, ignore the
202      * method override parameter.
203      */
204     @Test
205     public void testMethodOverrideIgnoredWithCallable() throws Exception
206     {
207         EntryPointResolverSet resolver = new LegacyEntryPointResolverSet();
208 
209         RequestContext.setEvent(getTestEvent(new FruitLover("Yummy!")));
210 
211         // those are usually set on the endpoint and copied over to the message
212         RequestContext.getEventContext().getMessage().setOutboundProperty(METHOD_PROPERTY_NAME,
213                                                                           INVALID_METHOD_NAME);
214 
215         Apple apple = new Apple();
216         apple.setAppleCleaner(new FruitCleaner()
217         {
218             public void wash(Fruit fruit)
219             {
220                 // dummy
221             }
222 
223             public void polish(Fruit fruit)
224             {
225                 // dummy
226             }
227         });
228         resolver.invoke(apple, RequestContext.getEventContext());
229     }
230 
231     /**
232      * If there was a method parameter specified to override the discovery mechanism
233      * and a target instance has a method accepting MuleEventContext, proceed to call
234      * this method, ignore the method override parameter.
235      */
236     @Test
237     public void testMethodOverrideIgnoredWithEventContext() throws Exception
238     {
239         EntryPointResolverSet resolverSet = new LegacyEntryPointResolverSet();
240 
241         RequestContext.setEvent(getTestEvent(new FruitLover("Yummy!")));
242 
243         // those are usually set on the endpoint and copied over to the message
244         final String methodName = "nosuchmethod";
245         final String propertyName = MuleProperties.MULE_METHOD_PROPERTY;
246         RequestContext.getEventContext().getMessage().setOutboundProperty(propertyName, methodName);
247 
248         try
249         {
250             resolverSet.invoke(new Kiwi(), RequestContext.getEventContext());
251             fail("no such method on service");
252         }
253         catch (EntryPointNotFoundException e)
254         {
255             // expected
256         }
257     }
258 
259     /** Test for proper resolution of a method that takes an array as argument. */
260     // TODO MULE-1088: currently fails, therefore disabled
261     @Test
262     public void testArrayArgumentResolution() throws Exception
263     {
264         EntryPointResolverSet resolverSet = new LegacyEntryPointResolverSet();
265 
266         Object payload = new Object[]{new Fruit[]{new Apple(), new Banana()}};
267         RequestContext.setEvent(getTestEvent(payload));
268 
269         FruitBowl bowl = new FruitBowl();
270         assertFalse(bowl.hasApple());
271         assertFalse(bowl.hasBanana());
272 
273         resolverSet.invoke(bowl, RequestContext.getEventContext());
274 
275         assertTrue(bowl.hasApple());
276         assertTrue(bowl.hasBanana());
277     }
278 
279     /** Test for proper resolution of a method that takes a List as argument. */
280     @Test
281     public void testListArgumentResolution() throws Exception
282     {
283         EntryPointResolverSet resolverSet = new LegacyEntryPointResolverSet();
284         Object payload = Arrays.asList(new Fruit[]{new Apple(), new Banana()});
285         RequestContext.setEvent(getTestEvent(payload));
286 
287         FruitBowl bowl = new FruitBowl();
288         assertFalse(bowl.hasApple());
289         assertFalse(bowl.hasBanana());
290 
291         resolverSet.invoke(bowl, RequestContext.getEventContext());
292 
293         assertTrue(bowl.hasApple());
294         assertTrue(bowl.hasBanana());
295     }
296 
297     /** Test for proper resolution of an existing method specified as override */
298     @Test
299     public void testExplicitOverride() throws Exception
300     {
301         EntryPointResolverSet resolverSet = new LegacyEntryPointResolverSet();
302 
303         Object payload = Arrays.asList(new Fruit[]{new Apple(), new Banana()});
304         RequestContext.setEvent(getTestEvent(payload));
305 
306         final String methodName = "setFruit";
307         final String propertyName = MuleProperties.MULE_METHOD_PROPERTY;
308         RequestContext.getEventContext().getMessage().setOutboundProperty(propertyName, methodName);
309 
310         FruitBowl bowl = new FruitBowl();
311         assertFalse(bowl.hasApple());
312         assertFalse(bowl.hasBanana());
313 
314         resolverSet.invoke(bowl, RequestContext.getEventContext());
315 
316         assertTrue(bowl.hasApple());
317         assertTrue(bowl.hasBanana());
318     }
319 }