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 2009/03/25 07:02:30 UTC

svn commit: r758152 - in /camel/trunk: camel-core/src/main/java/org/apache/camel/model/ camel-core/src/main/java/org/apache/camel/processor/ camel-core/src/test/java/org/apache/camel/processor/ components/camel-spring/src/main/java/org/apache/camel/spr...

Author: davsclaus
Date: Wed Mar 25 06:02:28 2009
New Revision: 758152

URL: http://svn.apache.org/viewvc?rev=758152&view=rev
Log:
CAMEL-908: WireTap now also supports sending a new Exchange, that is populated before its send. Allows you to spin off fire and forget messages at will during routing.

Added:
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/WireTapUsingFireAndForgetTest.java   (with props)
    camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.java
      - copied, changed from r758140, camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapTest.java
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.xml
      - copied, changed from r758140, camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapTest.xml
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/WireTapDefinition.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/processor/WireTapProcessor.java
    camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java
    camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionInterceptor.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java?rev=758152&r1=758151&r2=758152&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java Wed Mar 25 06:02:28 2009
@@ -45,7 +45,6 @@
 import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.builder.ErrorHandlerBuilderRef;
 import org.apache.camel.builder.ExpressionClause;
-import org.apache.camel.builder.NoErrorHandlerBuilder;
 import org.apache.camel.builder.ProcessorBuilder;
 import org.apache.camel.model.dataformat.DataFormatDefinition;
 import org.apache.camel.model.language.ConstantExpression;
@@ -1114,6 +1113,42 @@
     }
 
     /**
+     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
+     * Sends a new {@link org.apache.camel.Exchange} to the destination
+     * using {@link ExchangePattern#InOnly}.
+     *
+     * @param uri  the destination
+     * @param body expression that creates the body to send
+     * @return the builder
+     */
+    @SuppressWarnings("unchecked")
+    public Type wireTap(String uri, Expression body) {
+        WireTapDefinition answer = new WireTapDefinition();
+        answer.setUri(uri);
+        answer.setNewExchangeExpression(body);
+        addOutput(answer);
+        return (Type) this;
+    }
+
+    /**
+     * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a>
+     * Sends a new {@link org.apache.camel.Exchange} to the destination
+     * using {@link ExchangePattern#InOnly}.
+     *
+     * @param uri  the destination
+     * @param processor  processor preparing the new exchange to send
+     * @return the builder
+     */
+    @SuppressWarnings("unchecked")
+    public Type wireTap(String uri, Processor processor) {
+        WireTapDefinition answer = new WireTapDefinition();
+        answer.setUri(uri);
+        answer.setNewExchangeProcessor(processor);
+        addOutput(answer);
+        return (Type) this;
+    }
+
+    /**
      * Intercepts outputs added to this node in the future (i.e. intercepts outputs added after this statement)
      *
      * @param ref  a reference in the registry to lookup the interceptor that must be of type {@link DelegateProcessor}

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/WireTapDefinition.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/WireTapDefinition.java?rev=758152&r1=758151&r2=758152&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/WireTapDefinition.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/WireTapDefinition.java Wed Mar 25 06:02:28 2009
@@ -18,10 +18,14 @@
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 
 import org.apache.camel.Endpoint;
 import org.apache.camel.ExchangePattern;
+import org.apache.camel.Expression;
 import org.apache.camel.Processor;
 import org.apache.camel.processor.WireTapProcessor;
 import org.apache.camel.spi.RouteContext;
@@ -35,6 +39,15 @@
 @XmlAccessorType(XmlAccessType.FIELD)
 public class WireTapDefinition extends SendDefinition<WireTapDefinition> {
 
+    @XmlTransient
+    private Processor newExchangeProcessor;
+
+    @XmlAttribute(name = "processorRef", required = false)
+    private String newExchangeProcessorRef;
+
+    @XmlElement(name = "body", required = false)
+    private ExpressionSubElementDefinition newExchangeExpression;
+
     public WireTapDefinition() {
     }
 
@@ -49,7 +62,17 @@
     @Override
     public Processor createProcessor(RouteContext routeContext) throws Exception {
         Endpoint endpoint = resolveEndpoint(routeContext);
-        return new WireTapProcessor(endpoint, getPattern());
+        WireTapProcessor answer = new WireTapProcessor(endpoint, getPattern());
+
+        if (newExchangeProcessorRef != null) {
+            newExchangeProcessor = routeContext.lookup(newExchangeProcessorRef, Processor.class);
+        }
+        answer.setNewExchangeProcessor(newExchangeProcessor);
+        if (newExchangeExpression != null) {
+            answer.setNewExchangeExpression(newExchangeExpression.createExpression(routeContext));
+        }
+
+        return answer;
     }
 
     public ExchangePattern getPattern() {
@@ -66,4 +89,32 @@
         return "wireTap";
     }
 
+    public Processor getNewExchangeProcessor() {
+        return newExchangeProcessor;
+    }
+
+    public void setNewExchangeProcessor(Processor processor) {
+        this.newExchangeProcessor = processor;
+    }
+
+    public String getNewExchangeProcessorRef() {
+        return newExchangeProcessorRef;
+    }
+
+    public void setNewExchangeProcessorRef(String ref) {
+        this.newExchangeProcessorRef = ref;
+    }
+
+    public ExpressionSubElementDefinition getNewExchangeExpression() {
+        return newExchangeExpression;
+    }
+
+    public void setNewExchangeExpression(ExpressionSubElementDefinition expression) {
+        this.newExchangeExpression = expression;
+    }
+
+    public void setNewExchangeExpression(Expression expression) {
+        this.newExchangeExpression = new ExpressionSubElementDefinition(expression);
+    }
+
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/WireTapProcessor.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/WireTapProcessor.java?rev=758152&r1=758151&r2=758152&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/WireTapProcessor.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/WireTapProcessor.java Wed Mar 25 06:02:28 2009
@@ -25,6 +25,10 @@
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePattern;
+import org.apache.camel.Expression;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.util.ObjectHelper;
 
 /**
  * Processor for wire tapping exchanges to an endpoint destination.
@@ -36,6 +40,11 @@
     private int defaultThreadPoolSize = 5;
     private ExecutorService executorService;
 
+    // expression or processor used for populating a new exchange to send
+    // as opposed to traditional wiretap that sends a copy of the original exchange
+    private Expression newExchangeExpression;
+    private Processor newExchangeProcessor;
+
     public WireTapProcessor(Endpoint destination) {
         super(destination);
     }
@@ -122,6 +131,16 @@
 
     @Override
     protected Exchange configureExchange(Exchange exchange) {
+        if (newExchangeProcessor == null && newExchangeExpression == null) {
+            // use a copy of the original exchange
+            return configureCopyExchange(exchange);
+        } else {
+            // use a new exchange
+            return configureNewExchange(exchange);
+        }
+    }
+
+    private Exchange configureCopyExchange(Exchange exchange) {
         // must use a copy as we dont want it to cause side effects of the original exchange
         Exchange copy = exchange.copy();
         // set MEP to InOnly as this wire tap is a fire and forget
@@ -129,6 +148,28 @@
         return copy;
     }
 
+    private Exchange configureNewExchange(Exchange exchange) {
+        Exchange answer = new DefaultExchange(exchange.getContext(), ExchangePattern.InOnly);
+        // use destination os origin of this new exchange
+        answer.setFromEndpoint(getDestination());
+
+        // prepare the exchange
+        if (newExchangeProcessor != null) {
+            try {
+                newExchangeProcessor.process(answer);
+            } catch (Exception e) {
+                throw ObjectHelper.wrapRuntimeCamelException(e);
+            }
+        } else {
+            Object body = newExchangeExpression.evaluate(answer);
+            if (body != null) {
+                answer.getIn().setBody(body);
+            }
+        }
+
+        return answer;
+    }
+
     public ExecutorService getExecutorService() {
         if (executorService == null) {
             executorService = createExecutorService();
@@ -151,5 +192,20 @@
     public void setExecutorService(ExecutorService executorService) {
         this.executorService = executorService;
     }
-    
+
+    public Processor getNewExchangeProcessor() {
+        return newExchangeProcessor;
+    }
+
+    public void setNewExchangeProcessor(Processor newExchangeProcessor) {
+        this.newExchangeProcessor = newExchangeProcessor;
+    }
+
+    public Expression getNewExchangeExpression() {
+        return newExchangeExpression;
+    }
+
+    public void setNewExchangeExpression(Expression newExchangeExpression) {
+        this.newExchangeExpression = newExchangeExpression;
+    }
 }

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/WireTapUsingFireAndForgetTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/WireTapUsingFireAndForgetTest.java?rev=758152&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/WireTapUsingFireAndForgetTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/WireTapUsingFireAndForgetTest.java Wed Mar 25 06:02:28 2009
@@ -0,0 +1,111 @@
+/**
+ * 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 org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+
+/**
+ * @version $Revision$
+ */
+public class WireTapUsingFireAndForgetTest extends ContextTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    public void testFireAndForgetUsingProcessor() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // START SNIPPET: e1
+                from("direct:start")
+                    .wireTap("direct:foo", new Processor() {
+                        public void process(Exchange exchange) throws Exception {
+                            exchange.getIn().setBody("Bye World");
+                            exchange.getIn().setHeader("foo", "bar");
+                        }
+                    }).to("mock:result");
+
+
+                from("direct:foo").to("mock:foo");
+                // END SNIPPET: e1
+            }
+        });
+        context.start();
+
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedBodiesReceived("Hello World");
+
+        MockEndpoint foo = getMockEndpoint("mock:foo");
+        foo.expectedBodiesReceived("Bye World");
+        foo.expectedHeaderReceived("foo", "bar");
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        // should be different exchange instances
+        Exchange e1 = result.getReceivedExchanges().get(0);
+        Exchange e2 = foo.getReceivedExchanges().get(0);
+        assertNotSame("Should not be same Exchange", e1, e2);
+
+        // should have different from endpoint
+        assertEquals("direct:start", e1.getFromEndpoint().getEndpointUri());
+        assertEquals("direct:foo", e2.getFromEndpoint().getEndpointUri());
+    }
+
+    public void testFireAndForgetUsingExpression() throws Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // START SNIPPET: e2
+                from("direct:start")
+                    .wireTap("direct:foo", constant("Bye World"))
+                    .to("mock:result");
+
+                from("direct:foo").to("mock:foo");
+                // END SNIPPET: e2
+            }
+        });
+        context.start();
+
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedBodiesReceived("Hello World");
+
+        MockEndpoint foo = getMockEndpoint("mock:foo");
+        foo.expectedBodiesReceived("Bye World");
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        // should be different exchange instances
+        Exchange e1 = result.getReceivedExchanges().get(0);
+        Exchange e2 = foo.getReceivedExchanges().get(0);
+        assertNotSame("Should not be same Exchange", e1, e2);
+
+        // should have different from endpoint
+        assertEquals("direct:start", e1.getFromEndpoint().getEndpointUri());
+        assertEquals("direct:foo", e2.getFromEndpoint().getEndpointUri());
+    }
+
+}

Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/WireTapUsingFireAndForgetTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/WireTapUsingFireAndForgetTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java?rev=758152&r1=758151&r2=758152&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java (original)
+++ camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/SpringRouteBuilder.java Wed Mar 25 06:02:28 2009
@@ -109,8 +109,18 @@
      * @return the created error handler
      */
     public TransactionErrorHandlerBuilder transactionErrorHandler(SpringTransactionPolicy policy) {
+        return transactionErrorHandler(policy.getTransactionTemplate());
+    }
+
+    /**
+     * Creates a transaction error handler.
+     *
+     * @param template the spring transaction template
+     * @return the created error handler
+     */
+    public TransactionErrorHandlerBuilder transactionErrorHandler(TransactionTemplate template) {
         TransactionErrorHandlerBuilder answer = new TransactionErrorHandlerBuilder();
-        answer.setTransactionTemplate(policy.getTransactionTemplate());
+        answer.setTransactionTemplate(template);
         return answer;
     }
 

Modified: camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionInterceptor.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionInterceptor.java?rev=758152&r1=758151&r2=758152&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionInterceptor.java (original)
+++ camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionInterceptor.java Wed Mar 25 06:02:28 2009
@@ -42,7 +42,6 @@
 public class TransactionInterceptor extends DelegateProcessor {
     private static final transient Log LOG = LogFactory.getLog(TransactionInterceptor.class);
     private final TransactionTemplate transactionTemplate;
-    private RedeliveryPolicy redeliveryPolicy;
     private DelayPolicy delayPolicy;
 
     public TransactionInterceptor(TransactionTemplate transactionTemplate) {
@@ -136,9 +135,7 @@
      */
     protected void delayBeforeRedelivery() {
         long delay = 0;
-        if (redeliveryPolicy != null) {
-            delay = redeliveryPolicy.getDelay();
-        } else if (delayPolicy != null) {
+        if (delayPolicy != null) {
             delay = delayPolicy.getDelay();
         }
 
@@ -149,7 +146,7 @@
                 }
                 Thread.sleep(delay);
             } catch (InterruptedException e) {
-                // TODO: As DLC we need a timer task, eg something in Util to help us
+                LOG.debug("Sleep interrupted");
                 Thread.currentThread().interrupt();
             }
         }

Copied: camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.java (from r758140, camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.java?p2=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.java&p1=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapTest.java&r1=758140&r2=758152&rev=758152&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapTest.java (original)
+++ camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.java Wed Mar 25 06:02:28 2009
@@ -17,13 +17,71 @@
 package org.apache.camel.spring.processor;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.processor.WireTapTest;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.component.mock.MockEndpoint;
 import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
 
-public class SpringWireTapTest extends WireTapTest {
+public class SpringWireTapUsingFireAndForgetTest extends ContextTestSupport {
 
     protected CamelContext createCamelContext() throws Exception {
-        return createSpringCamelContext(this, "org/apache/camel/spring/processor/SpringWireTapTest.xml");
+        return createSpringCamelContext(this, "org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.xml");
     }
 
+    public void testFireAndForgetUsingExpression() throws Exception {
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedBodiesReceived("Hello World");
+
+        MockEndpoint foo = getMockEndpoint("mock:foo");
+        foo.expectedBodiesReceived("Bye World");
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        // should be different exchange instances
+        Exchange e1 = result.getReceivedExchanges().get(0);
+        Exchange e2 = foo.getReceivedExchanges().get(0);
+        assertNotSame("Should not be same Exchange", e1, e2);
+
+        // should have different from endpoint
+        assertEquals("direct:start", e1.getFromEndpoint().getEndpointUri());
+        assertEquals("direct:foo", e2.getFromEndpoint().getEndpointUri());
+    }
+
+    public void testFireAndForgetUsingProcessor() throws Exception {
+        MockEndpoint result = getMockEndpoint("mock:result");
+        result.expectedBodiesReceived("Hello World");
+
+        MockEndpoint foo = getMockEndpoint("mock:foo");
+        foo.expectedBodiesReceived("Bye World");
+        foo.expectedHeaderReceived("foo", "bar");
+
+        template.sendBody("direct:start2", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        // should be different exchange instances
+        Exchange e1 = result.getReceivedExchanges().get(0);
+        Exchange e2 = foo.getReceivedExchanges().get(0);
+        assertNotSame("Should not be same Exchange", e1, e2);
+
+        // should have different from endpoint
+        assertEquals("direct:start2", e1.getFromEndpoint().getEndpointUri());
+        assertEquals("direct:foo", e2.getFromEndpoint().getEndpointUri());
+    }
+
+    // START SNIPPET: e1
+    public static class MyProcessor implements Processor {
+
+        public void process(Exchange exchange) throws Exception {
+            // here we prepare the new exchange by setting the payload on the exchange
+            // on the IN messege.
+            exchange.getIn().setBody("Bye World");
+            exchange.getIn().setHeader("foo", "bar");
+        }
+    }
+    // END SNIPPET: e1
+
 }
\ No newline at end of file

Copied: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.xml (from r758140, camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapTest.xml)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.xml?p2=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.xml&p1=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapTest.xml&r1=758140&r2=758152&rev=758152&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapTest.xml (original)
+++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringWireTapUsingFireAndForgetTest.xml Wed Mar 25 06:02:28 2009
@@ -27,19 +27,28 @@
         <!-- START SNIPPET: e1 -->
         <route>
             <from uri="direct:start"/>
-            <to uri="log:foo"/>
-            <wireTap uri="direct:tap"/>
+            <wireTap uri="direct:foo">
+                <body><constant>Bye World</constant></body>
+            </wireTap>
             <to uri="mock:result"/>
         </route>
         <!-- END SNIPPET: e1 -->
 
+        <!-- START SNIPPET: e2 -->
         <route>
-            <from uri="direct:tap"/>
-            <delay delayTime="1000"><constant/></delay>
-            <setBody><constant>Tapped</constant></setBody>
+            <from uri="direct:start2"/>
+            <wireTap uri="direct:foo" processorRef="myProcessor"/>
             <to uri="mock:result"/>
-            <to uri="mock:tap"/>
         </route>
+        <!-- END SNIPPET: e2 -->
+
+        <route>
+            <from uri="direct:foo"/>
+            <to uri="mock:foo"/>
+        </route>
+
     </camelContext>
 
+    <bean id="myProcessor" class="org.apache.camel.spring.processor.SpringWireTapUsingFireAndForgetTest$MyProcessor"/>
+
 </beans>