You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2010/07/09 10:54:32 UTC

svn commit: r962451 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/component/bean/ main/java/org/apache/camel/model/ main/java/org/apache/camel/model/language/ test/java/org/apache/camel/component/bean/ test/java/org/apache/camel/processo...

Author: davsclaus
Date: Fri Jul  9 08:54:31 2010
New Revision: 962451

URL: http://svn.apache.org/viewvc?rev=962451&view=rev
Log:
CAMEL-2920: beanRef and method call DSL now validate method name is a valid method on startup. Better to fail fast.

Added:
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefMethodNotFoundTest.java
      - copied, changed from r962430, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefNotFoundTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefMethodNotFoundTest.java
      - copied, changed from r962430, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java
Removed:
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/aggregator/AggregatorBeanThrowExceptionTest.java
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithMethodHeaderTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java?rev=962451&r1=962450&r2=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java Fri Jul  9 08:54:31 2010
@@ -23,6 +23,8 @@ import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -132,7 +134,7 @@ public class BeanInfo {
 
         String name = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, String.class);
         if (name != null) {
-            if (hasOperations(name)) {
+            if (hasMethod(name)) {
                 List<MethodInfo> methods = getOperations(name);
                 if (methods != null && methods.size() == 1) {
                     // only one method then choose it
@@ -231,7 +233,7 @@ public class BeanInfo {
             LOG.trace("Adding operation: " + opName + " for method: " + methodInfo);
         }
 
-        if (hasOperations(opName)) {
+        if (hasMethod(opName)) {
             // we have an overloaded method so add the method info to the same key
             List<MethodInfo> existing = getOperations(opName);
             existing.add(methodInfo);
@@ -672,7 +674,7 @@ public class BeanInfo {
     }
 
     /**
-     * Do we have an operation with the given name.
+     * Do we have a method with the given name.
      * <p/>
      * Shorthand method names for getters is supported, so you can pass in eg 'name' and Camel
      * will can find the real 'getName' method instead.
@@ -680,11 +682,36 @@ public class BeanInfo {
      * @param methodName the method name
      * @return <tt>true</tt> if we have such a method.
      */
-    private boolean hasOperations(String methodName) {
+    public boolean hasMethod(String methodName) {
         return getOperations(methodName) != null;
     }
 
     /**
+     * Gets the list of methods sorted by A..Z method name.
+     *
+     * @return the methods.
+     */
+    @SuppressWarnings("unchecked")
+    public List<MethodInfo> getMethods() {
+        if (operations.isEmpty()) {
+            return Collections.EMPTY_LIST;
+        }
+
+        List<MethodInfo> methods = new ArrayList<MethodInfo>();
+        for (Collection<MethodInfo> col : operations.values()) {
+            methods.addAll(col);
+        }
+
+        // sort the methods by name A..Z
+        Collections.sort(methods, new Comparator<MethodInfo>() {
+            public int compare(MethodInfo o1, MethodInfo o2) {
+                return o1.getMethod().getName().compareTo(o2.getMethod().getName());
+            }
+        });
+        return methods;
+    }
+
+    /**
      * Get the operation(s) with the given name. We can have multiple when methods is overloaded.
      * <p/>
      * Shorthand method names for getters is supported, so you can pass in eg 'name' and Camel

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java?rev=962451&r1=962450&r2=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/BeanDefinition.java Fri Jul  9 08:54:31 2010
@@ -22,9 +22,10 @@ import javax.xml.bind.annotation.XmlAttr
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
-import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.Processor;
+import org.apache.camel.component.bean.BeanInfo;
 import org.apache.camel.component.bean.BeanProcessor;
+import org.apache.camel.component.bean.MethodNotFoundException;
 import org.apache.camel.component.bean.RegistryBean;
 import org.apache.camel.spi.Required;
 import org.apache.camel.spi.RouteContext;
@@ -149,11 +150,10 @@ public class BeanDefinition extends Outp
     public Processor createProcessor(RouteContext routeContext) {
         BeanProcessor answer;
         if (ObjectHelper.isNotEmpty(ref)) {
-            // if its a ref then check that the ref exists
-            if (routeContext.getCamelContext().getRegistry().lookup(ref) == null) {
-                throw new NoSuchBeanException(ref);
-            }
-            answer = new BeanProcessor(new RegistryBean(routeContext.getCamelContext(), ref));
+            RegistryBean beanHolder = new RegistryBean(routeContext.getCamelContext(), ref);
+            // bean holder will check if the bean exists
+            bean = beanHolder.getBean();
+            answer = new BeanProcessor(beanHolder);
         } else {
             if (bean == null) {
                 ObjectHelper.notNull(beanType, "bean, ref or beanType", this);
@@ -171,6 +171,12 @@ public class BeanDefinition extends Outp
         }
         if (method != null) {
             answer.setMethod(method);
+
+            // check there is a method with the given name, and leverage BeanInfo for that
+            BeanInfo info = new BeanInfo(routeContext.getCamelContext(), bean.getClass());
+            if (!info.hasMethod(method)) {
+                throw ObjectHelper.wrapRuntimeCamelException(new MethodNotFoundException(null, bean, method));
+            }
         }
         return answer;
     }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java?rev=962451&r1=962450&r2=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java Fri Jul  9 08:54:31 2010
@@ -24,8 +24,11 @@ import javax.xml.bind.annotation.XmlTran
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
-import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.Predicate;
+import org.apache.camel.component.bean.BeanHolder;
+import org.apache.camel.component.bean.BeanInfo;
+import org.apache.camel.component.bean.MethodNotFoundException;
+import org.apache.camel.component.bean.RegistryBean;
 import org.apache.camel.language.bean.BeanExpression;
 import org.apache.camel.util.ObjectHelper;
 
@@ -98,33 +101,68 @@ public class MethodCallExpression extend
     
     @Override
     public Expression createExpression(CamelContext camelContext) {
+        Expression answer;
+
         if (beanType != null) {            
-            return new BeanExpression(ObjectHelper.newInstance(beanType), getMethod());
+            instance = ObjectHelper.newInstance(beanType);
+            return new BeanExpression(instance, getMethod());
         } else if (instance != null) {
             return new BeanExpression(instance, getMethod());
         } else {
             String ref = beanName();
             // if its a ref then check that the ref exists
-            if (camelContext.getRegistry().lookup(ref) == null) {
-                throw new NoSuchBeanException(ref);
-            }
-            return new BeanExpression(ref, getMethod());
+            BeanHolder holder = new RegistryBean(camelContext, ref);
+            // get the bean which will check that it exists
+            instance = holder.getBean();
+            answer = new BeanExpression(ref, getMethod());
         }
+
+        // validate method
+        validateHasMethod(camelContext, instance, getMethod());
+
+        return answer;
     }
 
     @Override
     public Predicate createPredicate(CamelContext camelContext) {
+        Predicate answer;
+
         if (beanType != null) {
-            return new BeanExpression(ObjectHelper.newInstance(beanType), getMethod());
+            instance = ObjectHelper.newInstance(beanType);
+            answer = new BeanExpression(instance, getMethod());
         } else if (instance != null) {
-            return new BeanExpression(instance, getMethod());
+            answer = new BeanExpression(instance, getMethod());
         } else {
             String ref = beanName();
             // if its a ref then check that the ref exists
-            if (camelContext.getRegistry().lookup(ref) == null) {
-                throw new NoSuchBeanException(ref);
-            }
-            return new BeanExpression(ref, getMethod());
+            BeanHolder holder = new RegistryBean(camelContext, ref);
+            // get the bean which will check that it exists
+            instance = holder.getBean();
+            answer = new BeanExpression(ref, getMethod());
+        }
+
+        // validate method
+        validateHasMethod(camelContext, instance, getMethod());
+
+        return answer;
+    }
+
+    /**
+     * Validates the given bean has the method
+     *
+     * @param context  camel context
+     * @param bean     the bean instance
+     * @param method   the method, can be <tt>null</tt> if no method name provided
+     * @throws org.apache.camel.RuntimeCamelException is thrown if bean does not have the method
+     */
+    protected void validateHasMethod(CamelContext context, Object bean, String method) {
+        if (method == null) {
+            return;
+        }
+
+        BeanInfo info = new BeanInfo(context, bean.getClass());
+        if (!info.hasMethod(method)) {
+            throw ObjectHelper.wrapRuntimeCamelException(new MethodNotFoundException(null, bean, method));
         }
     }
 

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java?rev=962451&r1=962450&r2=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanInfoTest.java Fri Jul  9 08:54:31 2010
@@ -17,9 +17,9 @@
 package org.apache.camel.component.bean;
 
 import java.lang.reflect.Method;
+import java.util.List;
 
 import junit.framework.TestCase;
-
 import org.apache.camel.CamelContext;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.InOnly;
@@ -37,6 +37,16 @@ public class BeanInfoTest extends TestCa
 
     protected CamelContext camelContext = new DefaultCamelContext();
 
+    public void testGetOperations() throws Exception {
+        BeanInfo info = createBeanInfo(Foo.class);
+
+        List<MethodInfo> operations = info.getMethods();
+        assertEquals(3, operations.size());
+        assertEquals("inOnlyMethod", operations.get(0).getMethod().getName());
+        assertEquals("inOutMethod", operations.get(1).getMethod().getName());
+        assertEquals("robustInOnlyMethod", operations.get(2).getMethod().getName());
+    }
+
     public void testMethodPatternUsingMethodAnnotations() throws Exception {
         BeanInfo info = createBeanInfo(Foo.class);
 

Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefMethodNotFoundTest.java (from r962430, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefNotFoundTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefMethodNotFoundTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefMethodNotFoundTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefNotFoundTest.java&r1=962430&r2=962451&rev=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefNotFoundTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanRefMethodNotFoundTest.java Fri Jul  9 08:54:31 2010
@@ -18,14 +18,13 @@ package org.apache.camel.component.bean;
 
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.FailedToCreateRouteException;
-import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.impl.JndiRegistry;
 
 /**
  * @version $Revision$
  */
-public class BeanRefNotFoundTest extends ContextTestSupport {
+public class BeanRefMethodNotFoundTest extends ContextTestSupport {
 
     @Override
     protected JndiRegistry createRegistry() throws Exception {
@@ -34,13 +33,13 @@ public class BeanRefNotFoundTest extends
         return jndi;
     }
 
-    public void testBeanRefNotFound() throws Exception {
+    public void testBeanRefMethodNotFound() throws Exception {
         context.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("direct:a").routeId("a").beanRef("foo").to("mock:a");
+                from("direct:a").routeId("a").beanRef("foo", "hello").to("mock:a");
 
-                from("direct:b").routeId("b").beanRef("bar").to("mock:b");
+                from("direct:b").routeId("b").beanRef("foo", "bye").to("mock:b");
             }
         });
         try {
@@ -48,8 +47,8 @@ public class BeanRefNotFoundTest extends
             fail("Should have thrown exception");
         } catch (FailedToCreateRouteException e) {
             assertEquals("b", e.getRouteId());
-            NoSuchBeanException cause = assertIsInstanceOf(NoSuchBeanException.class, e.getCause());
-            assertEquals("bar", cause.getName());
+            MethodNotFoundException cause = assertIsInstanceOf(MethodNotFoundException.class, e.getCause().getCause());
+            assertEquals("bye", cause.getMethodName());
         }
     }
 
@@ -57,4 +56,4 @@ public class BeanRefNotFoundTest extends
     public boolean isUseRouteBuilder() {
         return false;
     }
-}
+}
\ No newline at end of file

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithMethodHeaderTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithMethodHeaderTest.java?rev=962451&r1=962450&r2=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithMethodHeaderTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanWithMethodHeaderTest.java Fri Jul  9 08:54:31 2010
@@ -22,6 +22,7 @@ import org.apache.camel.CamelExecutionEx
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
+import org.apache.camel.FailedToCreateRouteException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.util.jndi.JndiContext;
@@ -86,11 +87,15 @@ public class BeanWithMethodHeaderTest ex
 
     public void testMethodNotExists() throws Exception {
         try {
-            template.sendBody("direct:typo", "Hello World");
+            context.addRoutes(new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    from("direct:typo").beanRef("myBean", "ups").to("mock:result");
+                }
+            });
             fail("Should throw an exception");
-        } catch (CamelExecutionException e) {
-            assertIsInstanceOf(MethodNotFoundException.class, e.getCause());
-            MethodNotFoundException mnfe = (MethodNotFoundException) e.getCause();
+        } catch (FailedToCreateRouteException e) {
+            MethodNotFoundException mnfe = assertIsInstanceOf(MethodNotFoundException.class, e.getCause().getCause());
             assertEquals("ups", mnfe.getMethodName());
             assertSame(bean, mnfe.getBean());
         }
@@ -115,8 +120,6 @@ public class BeanWithMethodHeaderTest ex
                 from("direct:mixed").beanRef("myBean", "echo").beanRef("myBean", "hi").to("mock:result");
 
                 from("direct:fail").beanRef("myBean").to("mock:result");
-
-                from("direct:typo").beanRef("myBean", "ups").to("mock:result");
             }
         };
     }

Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefMethodNotFoundTest.java (from r962430, camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefMethodNotFoundTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefMethodNotFoundTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java&r1=962430&r2=962451&rev=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefMethodNotFoundTest.java Fri Jul  9 08:54:31 2010
@@ -18,14 +18,13 @@ package org.apache.camel.component.bean;
 
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.FailedToCreateRouteException;
-import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.impl.JndiRegistry;
 
 /**
  * @version $Revision$
  */
-public class MethodCallBeanRefNotFoundTest extends ContextTestSupport {
+public class MethodCallBeanRefMethodNotFoundTest extends ContextTestSupport {
 
     @Override
     protected JndiRegistry createRegistry() throws Exception {
@@ -34,13 +33,13 @@ public class MethodCallBeanRefNotFoundTe
         return jndi;
     }
 
-    public void testMethodCallBeanRefNotFound() throws Exception {
+    public void testMethodCallBeanRefMethodNotFound() throws Exception {
         context.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("direct:b").routeId("b").split().method("foo", "myMethod").to("mock:b");
+                from("direct:b").routeId("b").split().method("foo", "hello").to("mock:b");
 
-                from("direct:b").routeId("b").split().method("bar", "myMethod").to("mock:b");
+                from("direct:b").routeId("b").split().method("foo", "bye").to("mock:b");
             }
         });
         try {
@@ -48,8 +47,8 @@ public class MethodCallBeanRefNotFoundTe
             fail("Should have thrown exception");
         } catch (FailedToCreateRouteException e) {
             assertEquals("b", e.getRouteId());
-            NoSuchBeanException cause = assertIsInstanceOf(NoSuchBeanException.class, e.getCause());
-            assertEquals("bar", cause.getName());
+            MethodNotFoundException cause = assertIsInstanceOf(MethodNotFoundException.class, e.getCause().getCause());
+            assertEquals("bye", cause.getMethodName());
         }
     }
 

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java?rev=962451&r1=962450&r2=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/MethodCallBeanRefNotFoundTest.java Fri Jul  9 08:54:31 2010
@@ -38,9 +38,9 @@ public class MethodCallBeanRefNotFoundTe
         context.addRoutes(new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("direct:b").routeId("b").split().method("foo", "myMethod").to("mock:b");
+                from("direct:b").routeId("b").split().method("foo", "hello").to("mock:b");
 
-                from("direct:b").routeId("b").split().method("bar", "myMethod").to("mock:b");
+                from("direct:b").routeId("b").split().method("bar", "hello").to("mock:b");
             }
         });
         try {

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java?rev=962451&r1=962450&r2=962451&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java Fri Jul  9 08:54:31 2010
@@ -86,7 +86,7 @@ public class DotViewTest extends Context
 
     static class FromToBeanRoute extends RouteBuilder {
         public void configure() throws Exception {
-            from("seda:foo").beanRef("myBean", "myMethod");
+            from("seda:foo").beanRef("myBean", "hello");
         }
     }