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"); + } }; }