CAMEL-5402: Camel proxy allows to bind to method interface using @Body @Header 
and @ExchangeProperty to bind arguments to the exchange


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/abdef618
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/abdef618
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/abdef618

Branch: refs/heads/master
Commit: abdef61881e845df5c6a8077d0732e73175295be
Parents: c2396c3
Author: Claus Ibsen <[email protected]>
Authored: Mon Aug 10 19:01:23 2015 +0200
Committer: Claus Ibsen <[email protected]>
Committed: Mon Aug 10 19:01:23 2015 +0200

----------------------------------------------------------------------
 .../org/apache/camel/builder/ProxyBuilder.java  |   4 +-
 .../bean/AbstractCamelInvocationHandler.java    |  33 +--
 .../camel/component/bean/ProxyHelper.java       |  18 +-
 .../component/bean/BeanProxyNoBindingTest.java  | 211 +++++++++++++++++++
 .../camel/blueprint/CamelProxyFactoryBean.java  |   3 +-
 .../spring/remoting/CamelProxyFactoryBean.java  |   3 +-
 6 files changed, 246 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/abdef618/camel-core/src/main/java/org/apache/camel/builder/ProxyBuilder.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/builder/ProxyBuilder.java 
b/camel-core/src/main/java/org/apache/camel/builder/ProxyBuilder.java
index 523f420..6bee379 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/ProxyBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/ProxyBuilder.java
@@ -30,7 +30,7 @@ public final class ProxyBuilder {
 
     private final CamelContext camelContext;
     private Endpoint endpoint;
-    private boolean binding;
+    private boolean binding = true;
 
     public ProxyBuilder(CamelContext camelContext) {
         this.camelContext = camelContext;
@@ -61,6 +61,8 @@ public final class ProxyBuilder {
     /**
      * Whether to use binding or not.
      * <p/>
+     * Binding is enabled by default. Set this to <tt>false</tt> to use old 
behavior without binding.
+     * <p/>
      * If binding is enabled then Camel will bind the method parameters to the 
input {@link org.apache.camel.Message}
      * on the {@link org.apache.camel.Exchange} when invoking the proxy.
      *

http://git-wip-us.apache.org/repos/asf/camel/blob/abdef618/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java
 
b/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java
index 69e9f8c..c346690 100644
--- 
a/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java
+++ 
b/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java
@@ -107,20 +107,25 @@ public abstract class AbstractCamelInvocationHandler 
implements InvocationHandle
             int index = 0;
             for (Annotation[] row : method.getParameterAnnotations()) {
                 Object value = args[index];
-                for (Annotation ann : row) {
-                    if (ann.annotationType().isAssignableFrom(Header.class)) {
-                        Header header = (Header) ann;
-                        String name = header.value();
-                        exchange.getIn().setHeader(name, value);
-                    } else if 
(ann.annotationType().isAssignableFrom(ExchangeProperty.class)) {
-                        ExchangeProperty ep = (ExchangeProperty) ann;
-                        String name = ep.value();
-                        exchange.setProperty(name, value);
-                    } else if 
(ann.annotationType().isAssignableFrom(Body.class)) {
-                        exchange.getIn().setBody(value);
-                    } else {
-                        // assume its message body when there is no annotations
-                        exchange.getIn().setBody(value);
+                if (row == null || row.length == 0) {
+                    // assume its message body when there is no annotations
+                    exchange.getIn().setBody(value);
+                } else {
+                    for (Annotation ann : row) {
+                        if 
(ann.annotationType().isAssignableFrom(Header.class)) {
+                            Header header = (Header) ann;
+                            String name = header.value();
+                            exchange.getIn().setHeader(name, value);
+                        } else if 
(ann.annotationType().isAssignableFrom(ExchangeProperty.class)) {
+                            ExchangeProperty ep = (ExchangeProperty) ann;
+                            String name = ep.value();
+                            exchange.setProperty(name, value);
+                        } else if 
(ann.annotationType().isAssignableFrom(Body.class)) {
+                            exchange.getIn().setBody(value);
+                        } else {
+                            // assume its message body when there is no 
annotations
+                            exchange.getIn().setBody(value);
+                        }
                     }
                 }
                 index++;

http://git-wip-us.apache.org/repos/asf/camel/blob/abdef618/camel-core/src/main/java/org/apache/camel/component/bean/ProxyHelper.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/component/bean/ProxyHelper.java 
b/camel-core/src/main/java/org/apache/camel/component/bean/ProxyHelper.java
index 95e6524..541e07a 100644
--- a/camel-core/src/main/java/org/apache/camel/component/bean/ProxyHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/component/bean/ProxyHelper.java
@@ -43,7 +43,7 @@ public final class ProxyHelper {
     @SuppressWarnings("unchecked")
     @Deprecated
     public static <T> T createProxyObject(Endpoint endpoint, Producer 
producer, ClassLoader classLoader, Class<T>[] interfaces, MethodInfoCache 
methodCache) {
-        return createProxyObject(endpoint, false, producer, classLoader, 
interfaces, methodCache);
+        return createProxyObject(endpoint, true, producer, classLoader, 
interfaces, methodCache);
     }
 
     /**
@@ -61,7 +61,7 @@ public final class ProxyHelper {
      */
     @Deprecated
     public static <T> T createProxy(Endpoint endpoint, ClassLoader cl, 
Class<T> interfaceClass, MethodInfoCache methodCache) throws Exception {
-        return createProxy(endpoint, false, cl, toArray(interfaceClass), 
methodCache);
+        return createProxy(endpoint, true, cl, toArray(interfaceClass), 
methodCache);
     }
 
     /**
@@ -78,7 +78,7 @@ public final class ProxyHelper {
      */
     @Deprecated
     public static <T> T createProxy(Endpoint endpoint, ClassLoader cl, 
Class<T>[] interfaceClasses, MethodInfoCache methodCache) throws Exception {
-        return createProxy(endpoint, false, cl, interfaceClasses, methodCache);
+        return createProxy(endpoint, true, cl, interfaceClasses, methodCache);
     }
 
     /**
@@ -94,7 +94,7 @@ public final class ProxyHelper {
      * Creates a Proxy which sends the exchange to the endpoint.
      */
     public static <T> T createProxy(Endpoint endpoint, ClassLoader cl, 
Class<T> interfaceClass) throws Exception {
-        return createProxy(endpoint, false, cl, toArray(interfaceClass));
+        return createProxy(endpoint, true, cl, toArray(interfaceClass));
     }
 
     /**
@@ -104,7 +104,7 @@ public final class ProxyHelper {
      */
     @Deprecated
     public static <T> T createProxy(Endpoint endpoint, ClassLoader cl, 
Class<T>... interfaceClasses) throws Exception {
-        return createProxy(endpoint, false, cl, interfaceClasses);
+        return createProxy(endpoint, true, cl, interfaceClasses);
     }
 
     /**
@@ -118,7 +118,7 @@ public final class ProxyHelper {
      * Creates a Proxy which sends the exchange to the endpoint.
      */
     public static <T> T createProxy(Endpoint endpoint, Class<T> 
interfaceClass) throws Exception {
-        return createProxy(endpoint, false, toArray(interfaceClass));
+        return createProxy(endpoint, true, toArray(interfaceClass));
     }
 
     /**
@@ -128,7 +128,7 @@ public final class ProxyHelper {
      */
     @Deprecated
     public static <T> T createProxy(Endpoint endpoint, Class<T>... 
interfaceClasses) throws Exception {
-        return createProxy(endpoint, false, interfaceClasses);
+        return createProxy(endpoint, true, interfaceClasses);
     }
 
     /**
@@ -142,7 +142,7 @@ public final class ProxyHelper {
      * Creates a Proxy which sends the exchange to the endpoint.
      */
     public static <T> T createProxy(Endpoint endpoint, Producer producer, 
Class<T> interfaceClass) throws Exception {
-        return createProxy(endpoint, false, producer, toArray(interfaceClass));
+        return createProxy(endpoint, true, producer, toArray(interfaceClass));
     }
 
     /**
@@ -152,7 +152,7 @@ public final class ProxyHelper {
      */
     @Deprecated
     public static <T> T createProxy(Endpoint endpoint, Producer producer, 
Class<T>... interfaceClasses) throws Exception {
-        return createProxyObject(endpoint, false, producer, 
getClassLoader(interfaceClasses), interfaceClasses, 
createMethodInfoCache(endpoint));
+        return createProxyObject(endpoint, true, producer, 
getClassLoader(interfaceClasses), interfaceClasses, 
createMethodInfoCache(endpoint));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/camel/blob/abdef618/camel-core/src/test/java/org/apache/camel/component/bean/BeanProxyNoBindingTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/component/bean/BeanProxyNoBindingTest.java
 
b/camel-core/src/test/java/org/apache/camel/component/bean/BeanProxyNoBindingTest.java
new file mode 100644
index 0000000..0f94a5d
--- /dev/null
+++ 
b/camel-core/src/test/java/org/apache/camel/component/bean/BeanProxyNoBindingTest.java
@@ -0,0 +1,211 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.bean;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Endpoint;
+import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.builder.ProxyBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.w3c.dom.Document;
+
+
+/**
+ * @version 
+ */
+public class BeanProxyNoBindingTest extends ContextTestSupport {
+
+    public void testBeanProxyStringReturnString() throws Exception {
+        // START SNIPPET: e2
+        Endpoint endpoint = context.getEndpoint("direct:start");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        String reply = service.submitOrderStringReturnString("<order 
type=\"book\">Camel in action</order>");
+        assertEquals("<order id=\"123\">OK</order>", reply);
+        // END SNIPPET: e2
+    }
+
+    public void testBeanProxyStringReturnDocument() throws Exception {
+        Endpoint endpoint = context.getEndpoint("direct:start");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        Document reply = service.submitOrderStringReturnDocument("<order 
type=\"book\">Camel in action</order>");
+        assertNotNull(reply);
+        String s = context.getTypeConverter().convertTo(String.class, reply);
+        assertEquals("<order id=\"123\">OK</order>", s);
+    }
+
+    public void testBeanProxyDocumentReturnString() throws Exception {
+        Endpoint endpoint = context.getEndpoint("direct:start");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        Document doc = context.getTypeConverter().convertTo(Document.class, 
"<order type=\"book\">Camel in action</order>");
+
+        String reply = service.submitOrderDocumentReturnString(doc);
+        assertEquals("<order id=\"123\">OK</order>", reply);
+    }
+
+    public void testBeanProxyDocumentReturnDocument() throws Exception {
+        // START SNIPPET: e3
+        Endpoint endpoint = context.getEndpoint("direct:start");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        Document doc = context.getTypeConverter().convertTo(Document.class, 
"<order type=\"book\">Camel in action</order>");
+
+        Document reply = service.submitOrderDocumentReturnDocument(doc);
+        assertNotNull(reply);
+        String s = context.getTypeConverter().convertTo(String.class, reply);
+        assertEquals("<order id=\"123\">OK</order>", s);
+        // END SNIPPET: e3
+    }
+
+    public void testBeanProxyFailure() throws Exception {
+        Endpoint endpoint = context.getEndpoint("direct:start");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        String reply = service.submitOrderStringReturnString("<order 
type=\"beer\">Carlsberg</order>");
+        assertEquals("<order>FAIL</order>", reply);
+    }
+
+    public void testBeanProxyFailureNotXMLBody() throws Exception {
+        Endpoint endpoint = context.getEndpoint("direct:start");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        try {
+            service.submitOrderStringReturnString("Hello World");
+            fail("Should have thrown exception");
+        } catch (Exception e) {
+            // expected
+        }
+    }
+
+    public void testBeanProxyVoidReturnType() throws Exception {
+        Endpoint endpoint = context.getEndpoint("direct:start");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        service.doNothing("<order>ping</order>");
+    }
+
+    public void testBeanProxyFailureInvalidReturnType() throws Exception {
+        Endpoint endpoint = context.getEndpoint("direct:start");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        try {
+            service.invalidReturnType("<order 
type=\"beer\">Carlsberg</order>");
+            fail("Should have thrown exception");
+        } catch (Exception e) {
+            // expected
+            InvalidPayloadException cause = 
assertIsInstanceOf(InvalidPayloadException.class, e.getCause());
+            assertEquals(Integer.class, cause.getType());
+        }
+    }
+
+    public void testBeanProxyCallAnotherBean() throws Exception {
+        Endpoint endpoint = context.getEndpoint("direct:bean");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        String reply = service.submitOrderStringReturnString("World");
+        assertEquals("Hello World", reply);
+    }
+
+    // START SNIPPET: e4
+    public void testProxyBuilderProxyCallAnotherBean() throws Exception {
+        // use ProxyBuilder to easily create the proxy
+        OrderService service = new 
ProxyBuilder(context).endpoint("direct:bean").binding(false).build(OrderService.class);
+
+        String reply = service.submitOrderStringReturnString("World");
+        assertEquals("Hello World", reply);
+    }
+    // END SNIPPET: e4
+
+    public void testBeanProxyCallAnotherBeanWithNoArgs() throws Exception {
+        Endpoint endpoint = context.getEndpoint("direct:bean");
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        String reply = service.doAbsolutelyNothing();
+        assertEquals("Hi nobody", reply);
+    }
+
+    public void testProxyBuilderProxyCallAnotherBeanWithNoArgs() throws 
Exception {
+        Endpoint endpoint = context.getEndpoint("direct:bean");
+        OrderService service = new 
ProxyBuilder(context).endpoint(endpoint).binding(false).build(OrderService.class);
+
+        String reply = service.doAbsolutelyNothing();
+        assertEquals("Hi nobody", reply);
+    }
+
+    public void testBeanProxyVoidAsInOut() throws Exception {
+        Endpoint endpoint = context.getEndpoint("seda:delay");
+        // will by default let all exchanges be InOut
+        OrderService service = ProxyHelper.createProxy(endpoint, false, 
OrderService.class);
+
+        getMockEndpoint("mock:delay").expectedBodiesReceived("Hello World", 
"Bye World");
+        service.doNothing("Hello World");
+        template.sendBody("mock:delay", "Bye World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public void testProxyBuilderVoidAsInOut() throws Exception {
+        // will by default let all exchanges be InOut
+        OrderService service = new 
ProxyBuilder(context).endpoint("seda:delay").binding(false).build(OrderService.class);
+
+        getMockEndpoint("mock:delay").expectedBodiesReceived("Hello World", 
"Bye World");
+        service.doNothing("Hello World");
+        template.sendBody("mock:delay", "Bye World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // START SNIPPET: e1
+                from("direct:start")
+                        .choice()
+                        .when(xpath("/order/@type = 'book'")).to("direct:book")
+                        .otherwise().to("direct:other")
+                        .end();
+
+                from("direct:book").transform(constant("<order 
id=\"123\">OK</order>"));
+
+                
from("direct:other").transform(constant("<order>FAIL</order>"));
+                // END SNIPPET: e1
+
+                from("direct:bean")
+                        .bean(MyFooBean.class, "hello");
+
+                from("seda:delay")
+                        .delay(1000)
+                        .to("mock:delay");
+            }
+        };
+    }
+
+    public static class MyFooBean {
+
+        public String hello(String name) {
+            if (name != null) {
+                return "Hello " + name;
+            } else {
+                return "Hi nobody";
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/abdef618/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProxyFactoryBean.java
----------------------------------------------------------------------
diff --git 
a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProxyFactoryBean.java
 
b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProxyFactoryBean.java
index c22fa38..6491bbc 100644
--- 
a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProxyFactoryBean.java
+++ 
b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProxyFactoryBean.java
@@ -105,7 +105,8 @@ public class CamelProxyFactoryBean extends 
AbstractCamelFactoryBean<Object> {
             }
         }
 
-        boolean bind = getBinding() != null ? getBinding() : false;
+        // binding is enabled by default
+        boolean bind = getBinding() != null ? getBinding() : true;
 
         try {
             producer = endpoint.createProducer();

http://git-wip-us.apache.org/repos/asf/camel/blob/abdef618/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelProxyFactoryBean.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelProxyFactoryBean.java
 
b/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelProxyFactoryBean.java
index ecd3d56..d2d7132 100644
--- 
a/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelProxyFactoryBean.java
+++ 
b/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelProxyFactoryBean.java
@@ -71,7 +71,8 @@ public class CamelProxyFactoryBean extends 
UrlBasedRemoteAccessor implements Fac
             }
         }
 
-        boolean bind = getBinding() != null ? getBinding() : false;
+        // binding is enabled by default
+        boolean bind = getBinding() != null ? getBinding() : true;
 
         try {
             producer = endpoint.createProducer();

Reply via email to