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 2012/04/18 14:55:03 UTC

svn commit: r1327493 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/language/bean/ test/java/org/apache/camel/processor/

Author: davsclaus
Date: Wed Apr 18 12:55:02 2012
New Revision: 1327493

URL: http://svn.apache.org/viewvc?rev=1327493&view=rev
Log:
CAMEL-5189: method call expression should propagate exchange properties and message headers, so we can support stateful EIPs such as dynamic router etc. This is also consistent what we do in with other EIPs and components.

Added:
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangeHeadersTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangePropertiesTest.java
      - copied, changed from r1327435, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterTest.java
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java?rev=1327493&r1=1327492&r2=1327493&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java Wed Apr 18 12:55:02 2012
@@ -162,6 +162,14 @@ public class BeanExpression implements E
                 processor.process(resultExchange);
                 result = resultExchange.getOut().getBody();
 
+                // propagate properties and headers from result
+                if (resultExchange.hasProperties()) {
+                    exchange.getProperties().putAll(resultExchange.getProperties());
+                }
+                if (resultExchange.getOut().hasHeaders()) {
+                    exchange.getIn().getHeaders().putAll(resultExchange.getOut().getHeaders());
+                }
+
                 // propagate exceptions
                 if (resultExchange.getException() != null) {
                     exchange.setException(resultExchange.getException());

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangeHeadersTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangeHeadersTest.java?rev=1327493&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangeHeadersTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangeHeadersTest.java Wed Apr 18 12:55:02 2012
@@ -0,0 +1,109 @@
+/**
+ * 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.processor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Headers;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class DynamicRouterExchangeHeadersTest extends ContextTestSupport {
+
+    private static List<String> bodies = new ArrayList<String>();
+
+    public void testDynamicRouter() throws Exception {
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:a").expectedHeaderReceived("invoked", 1);
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedHeaderReceived("invoked", 2);
+        getMockEndpoint("mock:c").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedHeaderReceived("invoked", 2);
+        getMockEndpoint("mock:foo").expectedBodiesReceived("Bye World");
+        getMockEndpoint("mock:foo").expectedHeaderReceived("invoked", 3);
+        getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
+        getMockEndpoint("mock:result").expectedHeaderReceived("invoked", 4);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        assertEquals(5, bodies.size());
+        assertEquals("Hello World", bodies.get(0));
+        assertEquals("Hello World", bodies.get(1));
+        assertEquals("Hello World", bodies.get(2));
+        assertEquals("Bye World", bodies.get(3));
+        assertEquals("Bye World", bodies.get(4));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    // use a bean as the dynamic router
+                    .dynamicRouter(method(DynamicRouterExchangeHeadersTest.class, "slip"));
+
+                from("direct:foo").transform(constant("Bye World")).to("mock:foo");
+            }
+        };
+    }
+
+    // START SNIPPET: e2
+    /**
+     * Use this method to compute dynamic where we should route next.
+     *
+     * @param body the message body
+     * @param headers the message headers where we can store state between invocations
+     * @return endpoints to go, or <tt>null</tt> to indicate the end
+     */
+    public String slip(String body, @Headers Map<String, Object> headers) {
+        bodies.add(body);
+
+        // get the state from the message headers and keep track how many times
+        // we have been invoked
+        int invoked = 0;
+        Object current = headers.get("invoked");
+        if (current != null) {
+            invoked = Integer.valueOf(current.toString());
+        }
+        invoked++;
+        // and store the state back on the headers
+        headers.put("invoked", invoked);
+
+        if (invoked == 1) {
+            return "mock:a";
+        } else if (invoked == 2) {
+            return "mock:b,mock:c";
+        } else if (invoked == 3) {
+            return "direct:foo";
+        } else if (invoked == 4) {
+            return "mock:result";
+        }
+
+        // no more so return null
+        return null;
+    }
+    // END SNIPPET: e2
+
+}

Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangePropertiesTest.java (from r1327435, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangePropertiesTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangePropertiesTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterTest.java&r1=1327435&r2=1327493&rev=1327493&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DynamicRouterExchangePropertiesTest.java Wed Apr 18 12:55:02 2012
@@ -18,30 +18,35 @@ package org.apache.camel.processor;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Properties;
 import org.apache.camel.builder.RouteBuilder;
 
 /**
  * @version 
  */
-public class DynamicRouterTest extends ContextTestSupport {
+public class DynamicRouterExchangePropertiesTest extends ContextTestSupport {
 
-    private static int invoked;
     private static List<String> bodies = new ArrayList<String>();
 
     public void testDynamicRouter() throws Exception {
         getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:a").expectedPropertyReceived("invoked", 1);
         getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedPropertyReceived("invoked", 2);
         getMockEndpoint("mock:c").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedPropertyReceived("invoked", 2);
         getMockEndpoint("mock:foo").expectedBodiesReceived("Bye World");
+        getMockEndpoint("mock:foo").expectedPropertyReceived("invoked", 3);
         getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
+        getMockEndpoint("mock:result").expectedPropertyReceived("invoked", 4);
 
         template.sendBody("direct:start", "Hello World");
 
         assertMockEndpointsSatisfied();
 
-        assertEquals(5, invoked);
         assertEquals(5, bodies.size());
         assertEquals("Hello World", bodies.get(0));
         assertEquals("Hello World", bodies.get(1));
@@ -55,11 +60,9 @@ public class DynamicRouterTest extends C
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                // START SNIPPET: e1
                 from("direct:start")
                     // use a bean as the dynamic router
-                    .dynamicRouter(method(DynamicRouterTest.class, "slip"));
-                // END SNIPPET: e1
+                    .dynamicRouter(method(DynamicRouterExchangePropertiesTest.class, "slip"));
 
                 from("direct:foo").transform(constant("Bye World")).to("mock:foo");
             }
@@ -71,11 +74,22 @@ public class DynamicRouterTest extends C
      * Use this method to compute dynamic where we should route next.
      *
      * @param body the message body
+     * @param properties the exchange properties where we can store state between invocations
      * @return endpoints to go, or <tt>null</tt> to indicate the end
      */
-    public String slip(String body) {
+    public String slip(String body, @Properties Map<String, Object> properties) {
         bodies.add(body);
+
+        // get the state from the exchange properties and keep track how many times
+        // we have been invoked
+        int invoked = 0;
+        Object current = properties.get("invoked");
+        if (current != null) {
+            invoked = Integer.valueOf(current.toString());
+        }
         invoked++;
+        // and store the state back on the properties
+        properties.put("invoked", invoked);
 
         if (invoked == 1) {
             return "mock:a";