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/01/14 11:21:26 UTC

svn commit: r899147 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/builder/ExchangeNotifierBuilder.java test/java/org/apache/camel/builder/ExchangeNotifierBuilderTest.java

Author: davsclaus
Date: Thu Jan 14 10:21:26 2010
New Revision: 899147

URL: http://svn.apache.org/viewvc?rev=899147&view=rev
Log:
CAMEL-2357: Added additional methods for builder, including a neat whenSatisfied which leverages a Mock so you can set fine grained expectations on that mock.

Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExchangeNotifierBuilder.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ExchangeNotifierBuilderTest.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExchangeNotifierBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExchangeNotifierBuilder.java?rev=899147&r1=899146&r2=899147&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExchangeNotifierBuilder.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/ExchangeNotifierBuilder.java Thu Jan 14 10:21:26 2010
@@ -26,6 +26,9 @@
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.Predicate;
+import org.apache.camel.Producer;
+import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.management.EventNotifierSupport;
 import org.apache.camel.management.event.ExchangeCompletedEvent;
 import org.apache.camel.management.event.ExchangeCreatedEvent;
@@ -347,6 +350,123 @@
     }
 
     /**
+     * Sets a condition that <b>any</b> received {@link Exchange} should match the {@link Predicate}
+     *
+     * @param predicate the predicate
+     * @return the builder
+     */
+    public ExchangeNotifierBuilder whenAnyReceivedMatches(final Predicate predicate) {
+        stack.push(new EventPredicateSupport() {
+            private boolean matches;
+
+            @Override
+            public boolean onExchangeCreated(Exchange exchange) {
+                if (!matches) {
+                    matches = predicate.matches(exchange);
+                }
+                return true;
+            }
+
+            public boolean matches() {
+                return matches;
+            }
+
+            @Override
+            public String toString() {
+                return "whenAntReceivedMatches(" + predicate + ")";
+            }
+        });
+        return this;
+    }
+
+    /**
+     * Sets a condition that <b>all</b> received {@link Exchange} should match the {@link Predicate}
+     *
+     * @param predicate the predicate
+     * @return the builder
+     */
+    public ExchangeNotifierBuilder whenAllReceivedMatches(final Predicate predicate) {
+        stack.push(new EventPredicateSupport() {
+            private boolean matches = true;
+
+            @Override
+            public boolean onExchangeCreated(Exchange exchange) {
+                if (matches) {
+                    matches = predicate.matches(exchange);
+                }
+                return true;
+            }
+
+            public boolean matches() {
+                return matches;
+            }
+
+            @Override
+            public String toString() {
+                return "whenAllReceivedMatches(" + predicate + ")";
+            }
+        });
+        return this;
+    }
+
+    /**
+     * Sets a condition when the provided mock is satisfied.
+     * <p/>
+     * The idea is that you can use Mock for setting fine grained expectations
+     * and then use that together with this builder. The mock provided does <b>NOT</b>
+     * have to already exist in the route. You can just create a new pseudo mock
+     * and this builder will send the done {@link Exchange} to it. So its like
+     * adding the mock to the end of your route(s).
+     *
+     * @param mock the mock
+     * @return the builder
+     */
+    public ExchangeNotifierBuilder whenSatisfied(final MockEndpoint mock) {
+        stack.push(new EventPredicateSupport() {
+
+            private Producer producer;
+
+            @Override
+            public boolean onExchangeFailure(Exchange exchange) {
+                return sendToMock(exchange);
+            }
+
+            @Override
+            public boolean onExchangeCompleted(Exchange exchange) {
+                return sendToMock(exchange);
+            }
+
+            private boolean sendToMock(Exchange exchange) {
+                // send the exchange when its completed to the mock
+                try {
+                    if (producer == null) {
+                        producer = mock.createProducer();
+                    }
+                    producer.process(exchange);
+                } catch (Exception e) {
+                    throw ObjectHelper.wrapRuntimeCamelException(e);
+                }
+                return true;
+            }
+
+            public boolean matches() {
+                try {
+                    return mock.await(0, TimeUnit.SECONDS);
+                } catch (InterruptedException e) {
+                    throw ObjectHelper.wrapRuntimeCamelException(e);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return "whenMock(" + mock + ")";
+            }
+        });
+        return this;
+    }
+
+
+    /**
      * Prepares to append an additional expression using the <i>and</i> operator.
      *
      * @return the builder
@@ -547,26 +667,53 @@
 
     private interface EventPredicate {
 
+        /**
+         * Evaluates whether the predicate matched or not.
+         *
+         * @return <tt>true</tt> if matched, <tt>false</tt> otherwise
+         */
         boolean matches();
 
+        /**
+         * Callback for {@link Exchange} lifecycle
+         *
+         * @param exchange the exchange
+         * @return <tt>true</tt> to allow continue evaluating, <tt>false</tt> to stop immediately
+         */
         boolean onExchangeCreated(Exchange exchange);
 
+        /**
+         * Callback for {@link Exchange} lifecycle
+         *
+         * @param exchange the exchange
+         * @return <tt>true</tt> to allow continue evaluating, <tt>false</tt> to stop immediately
+         */
         boolean onExchangeCompleted(Exchange exchange);
 
+        /**
+         * Callback for {@link Exchange} lifecycle
+         *
+         * @param exchange the exchange
+         * @return <tt>true</tt> to allow continue evaluating, <tt>false</tt> to stop immediately
+         */
         boolean onExchangeFailure(Exchange exchange);
     }
 
     private abstract class EventPredicateSupport implements EventPredicate {
 
         public boolean onExchangeCreated(Exchange exchange) {
-            return true;
+            return onExchange(exchange);
         }
 
         public boolean onExchangeCompleted(Exchange exchange) {
-            return true;
+            return onExchange(exchange);
         }
 
         public boolean onExchangeFailure(Exchange exchange) {
+            return onExchange(exchange);
+        }
+
+        public boolean onExchange(Exchange exchange) {
             return true;
         }
     }

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ExchangeNotifierBuilderTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ExchangeNotifierBuilderTest.java?rev=899147&r1=899146&r2=899147&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ExchangeNotifierBuilderTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ExchangeNotifierBuilderTest.java Thu Jan 14 10:21:26 2010
@@ -19,6 +19,7 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.ContextTestSupport;
+import org.apache.camel.component.mock.MockEndpoint;
 
 /**
  * @version $Revision$
@@ -366,6 +367,99 @@
         assertEquals(false, builder.matches());
     }
 
+    public void testWhenAnyReceivedMatches() throws Exception {
+        ExchangeNotifierBuilder builder = new ExchangeNotifierBuilder(context)
+                .whenAnyReceivedMatches(body().contains("Camel"))
+                .create();
+
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Hello World");
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Bye World");
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:bar", "Hello Camel");
+        assertEquals(true, builder.matches());
+    }
+
+    public void testWhenAllReceivedMatches() throws Exception {
+        ExchangeNotifierBuilder builder = new ExchangeNotifierBuilder(context)
+                .whenAllReceivedMatches(body().contains("Camel"))
+                .create();
+
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Hello Camel");
+        assertEquals(true, builder.matches());
+
+        template.sendBody("direct:foo", "Bye Camel");
+        assertEquals(true, builder.matches());
+
+        template.sendBody("direct:bar", "Hello World");
+        assertEquals(false, builder.matches());
+    }
+
+    public void testWhenSatisfied() throws Exception {
+        // lets use a mock to set the expressions as it got many great assertions for that
+        // notice we use mock:assert which does NOT exist in the route, its just a pseudo name
+        MockEndpoint mock = getMockEndpoint("mock:assert");
+        mock.expectedBodiesReceivedInAnyOrder("Hello World", "Bye World", "Hi World");
+
+        ExchangeNotifierBuilder builder = new ExchangeNotifierBuilder(context)
+                .from("direct:foo").whenSatisfied(mock)
+                .create();
+
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Bye World");
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Hello World");
+        assertEquals(false, builder.matches());
+
+        // the builder is based on direct:foo so sending to bar should not trigger match
+        template.sendBody("direct:bar", "Hi World");
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Hi World");
+        assertEquals(true, builder.matches());
+    }
+
+    public void testComplexOrCamel() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:assert");
+        mock.expectedBodiesReceivedInAnyOrder("Hello World", "Bye World", "Hi World");
+
+        ExchangeNotifierBuilder builder = new ExchangeNotifierBuilder(context)
+                .from("direct:foo").whenSatisfied(mock)
+                .and().from("direct:bar").whenExactlyDone(5).whenAnyReceivedMatches(body().contains("Camel"))
+                .create();
+
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Bye World");
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Hello World");
+        assertEquals(false, builder.matches());
+
+        // the builder is based on direct:foo so sending to bar should not trigger match
+        template.sendBody("direct:bar", "Hi World");
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:foo", "Hi World");
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:bar", "Hi Camel");
+        assertEquals(false, builder.matches());
+
+        template.sendBody("direct:bar", "A");
+        template.sendBody("direct:bar", "B");
+        template.sendBody("direct:bar", "C");
+        assertEquals(true, builder.matches());
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {