This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 1c8e0ed  CAMEL-7677: advice with - Allow to influence 
interceptor/onException/onCompletion
1c8e0ed is described below

commit 1c8e0ed24ca9242c6701b385edc641312aa26633
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Tue Jul 30 15:08:07 2019 +0200

    CAMEL-7677: advice with - Allow to influence 
interceptor/onException/onCompletion
---
 .../camel-mock/src/main/docs/mock-component.adoc   |   9 --
 .../apache/camel/builder/AdviceWithBuilder.java    |   8 +-
 .../org/apache/camel/builder/AdviceWithTasks.java  |  69 +++++++++++---
 .../apache/camel/model/AdviceWithDefinition.java   |  40 ++++++++
 .../apache/camel/model/ProcessorDefinition.java    |   5 +-
 .../issues/AdviceWithErrorHandlerRemoveTest.java   | 104 +++++++++++++++++++++
 .../issues/AdviceWithInterceptFromRemoveTest.java  |  98 +++++++++++++++++++
 .../issues/AdviceWithInterceptRemoveTest.java      |  98 +++++++++++++++++++
 ...dviceWithInterceptSendToEndpointRemoveTest.java | 100 ++++++++++++++++++++
 .../issues/AdviceWithOnCompletionRemoveTest.java   | 100 ++++++++++++++++++++
 .../issues/AdviceWithOnExceptionRemoveTest.java    |  80 +++++++++++-----
 11 files changed, 660 insertions(+), 51 deletions(-)

diff --git a/components/camel-mock/src/main/docs/mock-component.adoc 
b/components/camel-mock/src/main/docs/mock-component.adoc
index b5a8bb3..9a11ced 100644
--- a/components/camel-mock/src/main/docs/mock-component.adoc
+++ b/components/camel-mock/src/main/docs/mock-component.adoc
@@ -164,7 +164,6 @@ invoked. This can be configured by setting the
 
 == Using assertPeriod
 
-*Available as of Camel 2.7* +
 When the assertion is satisfied then Camel will stop waiting and
 continue from the `assertIsSatisfied` method. That means if a new
 message arrives on the mock endpoint, just a bit later, that arrival
@@ -250,8 +249,6 @@ processor tests].
 
 == Mocking existing endpoints
 
-*Available as of Camel 2.7*
-
 Camel now allows you to automatically mock existing endpoints in your
 Camel routes.
 
@@ -376,8 +373,6 @@ in the constructor for the bean:
 
 == Mocking endpoints and skip sending to original endpoint
 
-*Available as of Camel 2.10*
-
 Sometimes you want to easily mock and skip sending to a certain
 endpoints. So the message is detoured and send to the mock endpoint
 only. You can now use the `mockEndpointsAndSkip`
@@ -402,8 +397,6 @@ 
include::{examplesdir}/components/camel-test/src/test/java/org/apache/camel/test
 
 == Limiting the number of messages to keep
 
-*Available as of Camel 2.10*
-
 The xref:mock-component.adoc[Mock] endpoints will by default keep a copy of 
every
 Exchange that it received. So if you test with a lot
 of messages, then it will consume memory. +
@@ -437,8 +430,6 @@ expectations on the 10 retained messages.
 
 == Testing with arrival times
 
-*Available as of Camel 2.7*
-
 The xref:mock-component.adoc[Mock] endpoint stores the arrival time of the 
message
 as a property on the Exchange.
 
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java 
b/core/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java
index 26cb447..a5f3b9a 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java
@@ -16,7 +16,7 @@
  */
 package org.apache.camel.builder;
 
-import org.apache.camel.model.PipelineDefinition;
+import org.apache.camel.model.AdviceWithDefinition;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
 
@@ -130,7 +130,7 @@ public class AdviceWithBuilder<T extends 
ProcessorDefinition<?>> {
      */
     public ProcessorDefinition<?> replace() {
         RouteDefinition route = builder.getOriginalRoute();
-        PipelineDefinition answer = new PipelineDefinition();
+        AdviceWithDefinition answer = new AdviceWithDefinition();
         if (id != null) {
             
builder.getAdviceWithTasks().add(AdviceWithTasks.replaceById(route, id, answer, 
selectFirst, selectLast, selectFrom, selectTo, maxDeep));
         } else if (toString != null) {
@@ -166,7 +166,7 @@ public class AdviceWithBuilder<T extends 
ProcessorDefinition<?>> {
      */
     public ProcessorDefinition<?> before() {
         RouteDefinition route = builder.getOriginalRoute();
-        PipelineDefinition answer = new PipelineDefinition();
+        AdviceWithDefinition answer = new AdviceWithDefinition();
         if (id != null) {
             builder.getAdviceWithTasks().add(AdviceWithTasks.beforeById(route, 
id, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
         } else if (toString != null) {
@@ -186,7 +186,7 @@ public class AdviceWithBuilder<T extends 
ProcessorDefinition<?>> {
      */
     public ProcessorDefinition<?> after() {
         RouteDefinition route = builder.getOriginalRoute();
-        PipelineDefinition answer = new PipelineDefinition();
+        AdviceWithDefinition answer = new AdviceWithDefinition();
         if (id != null) {
             builder.getAdviceWithTasks().add(AdviceWithTasks.afterById(route, 
id, answer, selectFirst, selectLast, selectFrom, selectTo, maxDeep));
         } else if (toString != null) {
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java 
b/core/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
index c0c6404..5f754c8 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
@@ -21,9 +21,15 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.apache.camel.Endpoint;
+import org.apache.camel.model.AdviceWithDefinition;
 import org.apache.camel.model.ChoiceDefinition;
 import org.apache.camel.model.EndpointRequiredDefinition;
 import org.apache.camel.model.FromDefinition;
+import org.apache.camel.model.InterceptDefinition;
+import org.apache.camel.model.InterceptSendToEndpointDefinition;
+import org.apache.camel.model.OnCompletionDefinition;
+import org.apache.camel.model.OnExceptionDefinition;
+import org.apache.camel.model.PipelineDefinition;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.ProcessorDefinitionHelper;
 import org.apache.camel.model.RouteDefinition;
@@ -174,16 +180,19 @@ public final class AdviceWithTasks {
                 while (it.hasNext()) {
                     ProcessorDefinition<?> output = it.next();
                     if (matchBy.match(output)) {
-                        List<ProcessorDefinition<?>> outputs = 
getOutputs(output);
+                        List<ProcessorDefinition<?>> outputs = 
getOutputs(output, route);
                         if (outputs != null) {
                             int index = outputs.indexOf(output);
                             if (index != -1) {
                                 match = true;
-                                outputs.add(index + 1, replace);
+                                // flattern as replace uses a pipeline as 
temporary holder
+                                ProcessorDefinition<?> flattern = 
flatternOutput(replace);
+                                outputs.add(index + 1, flattern);
                                 Object old = outputs.remove(index);
                                 // must set parent on the node we added in the 
route
-                                replace.setParent(output.getParent());
-                                LOG.info("AdviceWith ({}) : [{}] --> replace 
[{}]", matchBy.getId(), old, replace);
+                                ProcessorDefinition parent = 
output.getParent() != null ? output.getParent() : route;
+                                flattern.setParent(parent);
+                                LOG.info("AdviceWith ({}) : [{}] --> replace 
[{}]", matchBy.getId(), old, flattern);
                             }
                         }
                     }
@@ -229,7 +238,7 @@ public final class AdviceWithTasks {
                 while (it.hasNext()) {
                     ProcessorDefinition<?> output = it.next();
                     if (matchBy.match(output)) {
-                        List<ProcessorDefinition<?>> outputs = 
getOutputs(output);
+                        List<ProcessorDefinition<?>> outputs = 
getOutputs(output, route);
                         if (outputs != null) {
                             int index = outputs.indexOf(output);
                             if (index != -1) {
@@ -281,16 +290,19 @@ public final class AdviceWithTasks {
                 while (it.hasNext()) {
                     ProcessorDefinition<?> output = it.next();
                     if (matchBy.match(output)) {
-                        List<ProcessorDefinition<?>> outputs = 
getOutputs(output);
+                        List<ProcessorDefinition<?>> outputs = 
getOutputs(output, route);
                         if (outputs != null) {
                             int index = outputs.indexOf(output);
                             if (index != -1) {
                                 match = true;
+                                // flattern as before uses a pipeline as 
temporary holder
+                                ProcessorDefinition<?> flattern = 
flatternOutput(before);
                                 Object existing = outputs.get(index);
-                                outputs.add(index, before);
+                                outputs.add(index, flattern);
                                 // must set parent on the node we added in the 
route
-                                before.setParent(output.getParent());
-                                LOG.info("AdviceWith ({}) : [{}] --> before 
[{}]", matchBy.getId(), existing, before);
+                                ProcessorDefinition parent = 
output.getParent() != null ? output.getParent() : route;
+                                flattern.setParent(parent);
+                                LOG.info("AdviceWith ({}) : [{}] --> before 
[{}]", matchBy.getId(), existing, flattern);
                             }
                         }
                     }
@@ -336,16 +348,19 @@ public final class AdviceWithTasks {
                 while (it.hasNext()) {
                     ProcessorDefinition<?> output = it.next();
                     if (matchBy.match(output)) {
-                        List<ProcessorDefinition<?>> outputs = 
getOutputs(output);
+                        List<ProcessorDefinition<?>> outputs = 
getOutputs(output, route);
                         if (outputs != null) {
                             int index = outputs.indexOf(output);
                             if (index != -1) {
                                 match = true;
+                                // flattern as after uses a pipeline as 
temporary holder
+                                ProcessorDefinition<?> flattern = 
flatternOutput(after);
                                 Object existing = outputs.get(index);
-                                outputs.add(index + 1, after);
+                                outputs.add(index + 1, flattern);
                                 // must set parent on the node we added in the 
route
-                                after.setParent(output.getParent());
-                                LOG.info("AdviceWith ({}) : [{}] --> after 
[{}]", matchBy.getId(), existing, after);
+                                ProcessorDefinition parent = 
output.getParent() != null ? output.getParent() : route;
+                                flattern.setParent(parent);
+                                LOG.info("AdviceWith ({}) : [{}] --> after 
[{}]", matchBy.getId(), existing, flattern);
                             }
                         }
                     }
@@ -366,10 +381,21 @@ public final class AdviceWithTasks {
      * @param node the node
      * @return <tt>null</tt> if not outputs to be used
      */
-    private static List<ProcessorDefinition<?>> 
getOutputs(ProcessorDefinition<?> node) {
+    private static List<ProcessorDefinition<?>> 
getOutputs(ProcessorDefinition<?> node, RouteDefinition route) {
         if (node == null) {
             return null;
         }
+        // for intercept/onException/onCompletion then we want to work on the 
route outputs as they are top-level
+        if (node instanceof InterceptDefinition) {
+            return route.getOutputs();
+        } else if (node instanceof InterceptSendToEndpointDefinition) {
+            return route.getOutputs();
+        } else if (node instanceof OnExceptionDefinition) {
+            return route.getOutputs();
+        } else if (node instanceof OnCompletionDefinition) {
+            return route.getOutputs();
+        }
+
         ProcessorDefinition<?> parent = node.getParent();
         if (parent == null) {
             return null;
@@ -519,4 +545,19 @@ public final class AdviceWithTasks {
         };
     }
 
+    private static ProcessorDefinition<?> 
flatternOutput(ProcessorDefinition<?> output) {
+        if (output instanceof AdviceWithDefinition) {
+            AdviceWithDefinition advice = (AdviceWithDefinition) output;
+            if (advice.getOutputs().size() == 1) {
+                return advice.getOutputs().get(0);
+            } else {
+                // it should be a pipeline
+                PipelineDefinition pipe = new PipelineDefinition();
+                pipe.setOutputs(advice.getOutputs());
+                return pipe;
+            }
+        }
+        return output;
+    }
+
 }
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/model/AdviceWithDefinition.java
 
b/core/camel-core/src/main/java/org/apache/camel/model/AdviceWithDefinition.java
new file mode 100644
index 0000000..0609a36
--- /dev/null
+++ 
b/core/camel-core/src/main/java/org/apache/camel/model/AdviceWithDefinition.java
@@ -0,0 +1,40 @@
+/*
+ * 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.model;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+/**
+ * Temporary model used internally by advice-with
+ */
+@XmlTransient
+public class AdviceWithDefinition extends 
OutputDefinition<AdviceWithDefinition> {
+
+    public AdviceWithDefinition() {
+    }
+
+    @Override
+    public String getShortName() {
+        return "adviceWith";
+    }
+
+    @Override
+    public String getLabel() {
+        return "adviceWith";
+    }
+
+}
\ No newline at end of file
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java 
b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index 52d8ccc..0ea4824 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -172,8 +172,9 @@ public abstract class ProcessorDefinition<Type extends 
ProcessorDefinition<Type>
             return;
         }
 
-        // validate that top-level is only added on the route (eg top level)
-        boolean parentIsRoute = 
RouteDefinition.class.isAssignableFrom(this.getClass());
+        // validate that top-level is only added on the route (eg top level) 
(or still allow if using advice-with)
+        boolean parentIsRoute = 
RouteDefinition.class.isAssignableFrom(this.getClass())
+                || 
AdviceWithDefinition.class.isAssignableFrom(this.getClass());
         if (output.isTopLevelOnly() && !parentIsRoute) {
             throw new IllegalArgumentException("The output must be added as 
top-level on the route. Try moving " + output + " to the top of route.");
         }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithErrorHandlerRemoveTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithErrorHandlerRemoveTest.java
new file mode 100644
index 0000000..5b0c99e
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithErrorHandlerRemoveTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.reifier.RouteReifier;
+import org.junit.Test;
+
+public class AdviceWithErrorHandlerRemoveTest extends ContextTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testAdviceErrorHandlerRemove() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedMessageCount(0);
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:dead").expectedMessageCount(0);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                getOriginalRoute().errorHandler(noErrorHandler());
+            }
+        });
+
+        context.start();
+
+        try {
+            template.sendBody("direct:foo", "Hello World");
+            fail("Should throw exception");
+        } catch (Exception e) {
+            assertEquals("Forced", e.getCause().getMessage());
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAdviceErrorHandlerReplace() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedMessageCount(0);
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:dead").expectedMessageCount(0);
+        getMockEndpoint("mock:dead2").expectedMessageCount(1);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // override errorHandler by using on exception
+                
weaveAddFirst().onException(Exception.class).handled(true).to("mock:dead2");
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:bar").routeId("bar")
+                        .to("mock:c").to("mock:d");
+
+                from("direct:foo").routeId("foo")
+                        .errorHandler(deadLetterChannel("mock:dead"))
+                        .to("mock:a")
+                        .throwException(new IllegalArgumentException("Forced"))
+                        .to("mock:b");
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptFromRemoveTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptFromRemoveTest.java
new file mode 100644
index 0000000..de45c97
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptFromRemoveTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.reifier.RouteReifier;
+import org.junit.Test;
+
+public class AdviceWithInterceptFromRemoveTest extends ContextTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testAdviceInterceptRemove() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept").expectedMessageCount(0);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                weaveById("myIntercept").remove();
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAdviceInterceptReplace() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept2").expectedMessageCount(1);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                weaveById("myIntercept").replace().to("mock:intercept2");
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                interceptFrom().id("myIntercept").transform(constant("Bye 
World")).to("mock:intercept");
+
+                from("direct:bar").routeId("bar")
+                        .to("mock:c").to("mock:d");
+
+                from("direct:foo").routeId("foo")
+                        .to("mock:a").to("mock:b");
+
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptRemoveTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptRemoveTest.java
new file mode 100644
index 0000000..fcee9ed
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptRemoveTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.reifier.RouteReifier;
+import org.junit.Test;
+
+public class AdviceWithInterceptRemoveTest extends ContextTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testAdviceInterceptRemove() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept").expectedMessageCount(0);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                weaveById("myIntercept").remove();
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAdviceInterceptReplace() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept2").expectedMessageCount(1);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                weaveById("myIntercept").replace().to("mock:intercept2");
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                intercept().id("myIntercept").transform(constant("Bye 
World")).to("mock:intercept");
+
+                from("direct:bar").routeId("bar")
+                        .to("mock:c").to("mock:d");
+
+                from("direct:foo").routeId("foo")
+                        .to("mock:a").to("mock:b");
+
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptSendToEndpointRemoveTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptSendToEndpointRemoveTest.java
new file mode 100644
index 0000000..1cd1741
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithInterceptSendToEndpointRemoveTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.reifier.RouteReifier;
+import org.junit.Test;
+
+public class AdviceWithInterceptSendToEndpointRemoveTest extends 
ContextTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testAdviceInterceptRemove() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept").expectedMessageCount(0);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                weaveById("myIntercept").remove();
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAdviceInterceptReplace() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept").expectedMessageCount(0);
+        getMockEndpoint("mock:intercept2").expectedMessageCount(1);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                weaveById("myIntercept").replace().to("mock:intercept2");
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                interceptSendToEndpoint("mock:b").id("myIntercept")
+                        .transform(constant("Bye World"))
+                        .to("mock:intercept");
+
+                from("direct:bar").routeId("bar")
+                        .to("mock:c").to("mock:d");
+
+                from("direct:foo").routeId("foo")
+                        .to("mock:a").to("mock:b");
+
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithOnCompletionRemoveTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithOnCompletionRemoveTest.java
new file mode 100644
index 0000000..59349ab
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithOnCompletionRemoveTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.reifier.RouteReifier;
+import org.junit.Test;
+
+public class AdviceWithOnCompletionRemoveTest extends ContextTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testAdviceOnCompletionRemove() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:done").expectedMessageCount(0);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                weaveById("myCompletion").remove();
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAdviceOnCompletionReplace() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:done").expectedMessageCount(0);
+        getMockEndpoint("mock:done2").expectedMessageCount(1);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                
weaveById("myCompletion").replace().onCompletion().to("mock:done2");
+            }
+        });
+
+        context.start();
+
+        template.sendBody("direct:foo", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                onCompletion().id("myCompletion")
+                    .transform(constant("Bye World")).to("mock:done");
+
+                from("direct:bar").routeId("bar")
+                        .to("mock:c").to("mock:d");
+
+                from("direct:foo").routeId("foo")
+                        .to("mock:a")
+                        .to("mock:b");
+
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithOnExceptionRemoveTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithOnExceptionRemoveTest.java
index fb9ef98..00294ca 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithOnExceptionRemoveTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithOnExceptionRemoveTest.java
@@ -17,32 +17,69 @@
 package org.apache.camel.issues;
 
 import org.apache.camel.ContextTestSupport;
-import org.apache.camel.Exchange;
-import org.apache.camel.Processor;
 import org.apache.camel.builder.AdviceWithRouteBuilder;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.reifier.RouteReifier;
 import org.junit.Test;
 
 public class AdviceWithOnExceptionRemoveTest extends ContextTestSupport {
 
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
     @Test
-    public void testAdviceWithOnException() throws Exception {
-        RouteDefinition route = context.getRouteDefinitions().get(0);
-        RouteReifier.adviceWith(route, context, new AdviceWithRouteBuilder() {
+    public void testAdviceOnExceptionRemove() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
+        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:b").expectedMessageCount(0);
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:dead").expectedMessageCount(0);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
             @Override
             public void configure() throws Exception {
-                weaveById("removeMe").remove();
+                weaveById("myException").remove();
             }
         });
+
         context.start();
 
+        try {
+            template.sendBody("direct:foo", "Hello World");
+            fail("Should throw exception");
+        } catch (Exception e) {
+            assertEquals("Forced", e.getCause().getMessage());
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testAdviceOnExceptionReplace() throws Exception {
+        context.addRoutes(createRouteBuilder());
+
         getMockEndpoint("mock:a").expectedBodiesReceived("Hello World");
         getMockEndpoint("mock:b").expectedMessageCount(0);
-        getMockEndpoint("mock:handled").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:c").expectedMessageCount(0);
+        getMockEndpoint("mock:d").expectedMessageCount(0);
+        getMockEndpoint("mock:dead").expectedMessageCount(0);
+        getMockEndpoint("mock:dead2").expectedMessageCount(1);
+
+        RouteReifier.adviceWith(context.getRouteDefinition("foo"), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                weaveById("myException").replace().onException(Exception.class)
+                        .handled(true).to("mock:dead2");
+            }
+        });
+
+        context.start();
 
-        template.sendBody("direct:start", "Hello World");
+        template.sendBody("direct:foo", "Hello World");
 
         assertMockEndpointsSatisfied();
     }
@@ -52,19 +89,18 @@ public class AdviceWithOnExceptionRemoveTest extends 
ContextTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                onException(IllegalArgumentException.class)
-                    .process(new Processor() {
-                        @Override
-                        public void process(Exchange exchange) throws 
Exception {
-                            exchange.getIn().setBody("I changed this");
-                        }
-                    }).id("removeMe")
-                    .handled(true).to("mock:handled");
-
-                from("direct:start")
-                    .to("mock:a").id("a")
-                    .throwException(new IllegalArgumentException("Forced"))
-                    .to("mock:b").id("b");
+                onException(Exception.class).id("myException")
+                        .handled(true)
+                        .transform(constant("Bye World")).to("mock:dead");
+
+                from("direct:bar").routeId("bar")
+                        .to("mock:c").to("mock:d");
+
+                from("direct:foo").routeId("foo")
+                        .to("mock:a")
+                        .throwException(new IllegalArgumentException("Forced"))
+                        .to("mock:b");
+
             }
         };
     }

Reply via email to