Author: davsclaus Date: Sun Feb 20 10:22:21 2011 New Revision: 1072545 URL: http://svn.apache.org/viewvc?rev=1072545&view=rev Log: CAMEL-3689: AdviceWith can now manipulate routes. This allows you for example to replace parts of routes during testing.
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTask.java camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksMatchTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksTest.java (contents, props changed) - copied, changed from r1072268, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithRouteIdTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksToStringPatternTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/OutputDefinition.java camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java Added: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java?rev=1072545&view=auto ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java (added) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithBuilder.java Sun Feb 20 10:22:21 2011 @@ -0,0 +1,97 @@ +/** + * 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.builder; + +import org.apache.camel.model.PipelineDefinition; +import org.apache.camel.model.ProcessorDefinition; + +/** + * A builder when using the <a href="http://camel.apache.org/advicewith.html">advice with</a> feature. + */ +public class AdviceWithBuilder { + + private final AdviceWithRouteBuilder builder; + private final String id; + private final String toString; + + public AdviceWithBuilder(AdviceWithRouteBuilder builder, String id, String toString) { + this.builder = builder; + this.id = id; + this.toString = toString; + + if (id == null && toString == null) { + throw new IllegalArgumentException("Either id or toString must be specified"); + } + } + + /** + * Replaces the matched node(s) with the following nodes. + * + * @return the builder to build the nodes. + */ + public ProcessorDefinition replace() { + PipelineDefinition answer = new PipelineDefinition(); + if (id != null) { + builder.getAdviceWithTasks().add(AdviceWithTasks.replaceById(builder.getOriginalRoute(), id, answer)); + } else if (toString != null) { + builder.getAdviceWithTasks().add(AdviceWithTasks.replaceByToString(builder.getOriginalRoute(), toString, answer)); + } + return answer; + } + + /** + * Removes the matched node(s) + */ + public void remove() { + if (id != null) { + builder.getAdviceWithTasks().add(AdviceWithTasks.removeById(builder.getOriginalRoute(), id)); + } else if (toString != null) { + builder.getAdviceWithTasks().add(AdviceWithTasks.removeByToString(builder.getOriginalRoute(), toString)); + } + } + + /** + * Insert the following node(s) <b>before</b> the matched node(s) + * + * @return the builder to build the nodes. + */ + public ProcessorDefinition before() { + PipelineDefinition answer = new PipelineDefinition(); + if (id != null) { + builder.getAdviceWithTasks().add(AdviceWithTasks.beforeById(builder.getOriginalRoute(), id, answer)); + } else if (toString != null) { + builder.getAdviceWithTasks().add(AdviceWithTasks.beforeByToString(builder.getOriginalRoute(), toString, answer)); + } + return answer; + } + + /** + * Insert the following node(s) <b>after</b> the matched node(s) + * + * @return the builder to build the nodes. + */ + public ProcessorDefinition after() { + PipelineDefinition answer = new PipelineDefinition(); + if (id != null) { + builder.getAdviceWithTasks().add(AdviceWithTasks.afterById(builder.getOriginalRoute(), id, answer)); + } else if (toString != null) { + builder.getAdviceWithTasks().add(AdviceWithTasks.afterByToString(builder.getOriginalRoute(), toString, answer)); + } + return answer; + } + +} Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java?rev=1072545&r1=1072544&r2=1072545&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java Sun Feb 20 10:22:21 2011 @@ -16,18 +16,56 @@ */ package org.apache.camel.builder; +import java.util.ArrayList; +import java.util.List; + import org.apache.camel.impl.InterceptSendToMockEndpointStrategy; +import org.apache.camel.model.RouteDefinition; +import org.apache.camel.util.ObjectHelper; /** - * A {@link RouteBuilder} which has extended features when using - * {@link org.apache.camel.model.RouteDefinition#adviceWith(org.apache.camel.CamelContext, RouteBuilder) adviceWith}. + * A {@link RouteBuilder} which has extended capabilities when using + * the <a href="http://camel.apache.org/advicewith.html">advice with</a> feature. * - * @version + * @see org.apache.camel.model.RouteDefinition#adviceWith(org.apache.camel.CamelContext, RouteBuilder) */ public abstract class AdviceWithRouteBuilder extends RouteBuilder { + private RouteDefinition originalRoute; + private final List<AdviceWithTask> adviceWithTasks = new ArrayList<AdviceWithTask>(); + + /** + * Sets the original route which we advice. + * + * @param originalRoute the original route we advice. + */ + public void setOriginalRoute(RouteDefinition originalRoute) { + this.originalRoute = originalRoute; + } + + /** + * Gets the original route we advice. + * + * @return the original route. + */ + public RouteDefinition getOriginalRoute() { + return originalRoute; + } + + /** + * Gets a list of additional tasks to execute after the {@link #configure()} method has been executed + * during the advice process. + * + * @return a list of additional {@link AdviceWithTask} tasks to be executed during the advice process. + */ + public List<AdviceWithTask> getAdviceWithTasks() { + return adviceWithTasks; + } + /** * Mock all endpoints in the route. + * + * @throws Exception can be thrown if error occurred */ public void mockEndpoints() throws Exception { getContext().removeEndpoints("*"); @@ -37,7 +75,8 @@ public abstract class AdviceWithRouteBui /** * Mock all endpoints matching the given pattern. * - * @param pattern the pattern. + * @param pattern the pattern. + * @throws Exception can be thrown if error occurred * @see org.apache.camel.util.EndpointHelper#matchEndpoint(String, String) */ public void mockEndpoints(String pattern) throws Exception { @@ -45,4 +84,34 @@ public abstract class AdviceWithRouteBui getContext().addRegisterEndpointCallback(new InterceptSendToMockEndpointStrategy(pattern)); } + /** + * Advices by matching id of the nodes in the route. + * <p/> + * Uses the {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)} matching algorithm. + * + * @param pattern the pattern + * @return the builder + * @see org.apache.camel.util.EndpointHelper#matchPattern(String, String) + */ + public AdviceWithBuilder adviceById(String pattern) { + ObjectHelper.notNull(originalRoute, "originalRoute", this); + + return new AdviceWithBuilder(this, pattern, null); + } + + /** + * Advices by matching the to string representation of the nodes in the route. + * <p/> + * Uses the {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)} matching algorithm. + * + * @param pattern the pattern + * @return the builder + * @see org.apache.camel.util.EndpointHelper#matchPattern(String, String) + */ + public AdviceWithBuilder adviceByToString(String pattern) { + ObjectHelper.notNull(originalRoute, "originalRoute", this); + + return new AdviceWithBuilder(this, null, pattern); + } + } Added: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTask.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTask.java?rev=1072545&view=auto ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTask.java (added) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTask.java Sun Feb 20 10:22:21 2011 @@ -0,0 +1,31 @@ +/** + * 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.builder; + +/** + * Task or command being executed when using the advice with feature. + */ +public interface AdviceWithTask { + + /** + * The task to execute + * + * @throws Exception is thrown if error during executing the task, or invalid input. + */ + void task() throws Exception; + +} Added: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java?rev=1072545&view=auto ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java (added) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/AdviceWithTasks.java Sun Feb 20 10:22:21 2011 @@ -0,0 +1,238 @@ +/** + * 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.builder; + +import java.util.Iterator; + +import org.apache.camel.model.ProcessorDefinition; +import org.apache.camel.model.ProcessorDefinitionHelper; +import org.apache.camel.model.RouteDefinition; +import org.apache.camel.util.EndpointHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * {@link AdviceWithTask} tasks which are used by the {@link AdviceWithRouteBuilder}. + */ +public final class AdviceWithTasks { + + private static final Logger LOG = LoggerFactory.getLogger(AdviceWithTasks.class); + + private AdviceWithTasks() { + // utility class + } + + /** + * Match by is used for pluggable match by logic. + */ + private interface MatchBy { + + String getId(); + + boolean match(ProcessorDefinition processor); + } + + /** + * Will match by id of the processor. + */ + private static final class MatchById implements MatchBy { + + private final String id; + + private MatchById(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public boolean match(ProcessorDefinition processor) { + return EndpointHelper.matchPattern(processor.getId(), id); + } + } + + /** + * Will match by the to string representation of the processor. + */ + private static final class MatchByToString implements MatchBy { + + private final String toString; + + private MatchByToString(String toString) { + this.toString = toString; + } + + public String getId() { + return toString; + } + + public boolean match(ProcessorDefinition processor) { + return EndpointHelper.matchPattern(processor.toString(), toString); + } + } + + + public static AdviceWithTask replaceByToString(final RouteDefinition route, final String toString, final ProcessorDefinition replace) { + return doReplace(route, new MatchByToString(toString), replace); + } + + public static AdviceWithTask replaceById(final RouteDefinition route, final String id, final ProcessorDefinition replace) { + return doReplace(route, new MatchById(id), replace); + } + + @SuppressWarnings("unchecked") + private static AdviceWithTask doReplace(final RouteDefinition route, final MatchBy matchBy, final ProcessorDefinition replace) { + return new AdviceWithTask() { + public void task() throws Exception { + boolean match = false; + Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class); + while (it.hasNext()) { + ProcessorDefinition output = it.next(); + if (matchBy.match(output)) { + ProcessorDefinition parent = output.getParent(); + if (parent != null) { + int index = parent.getOutputs().indexOf(output); + if (index != -1) { + match = true; + parent.getOutputs().add(index + 1, replace); + Object old = parent.getOutputs().remove(index); + LOG.info("AdviceWith (" + matchBy.getId() + ") : [" + old + "] --> replace [" + replace + "]"); + } + } + } + } + + if (!match) { + throw new IllegalArgumentException("There are no outputs which matches: " + matchBy.getId() + " in the route: " + route); + } + } + }; + } + + public static AdviceWithTask removeByToString(final RouteDefinition route, final String toString) { + return doRemove(route, new MatchByToString(toString)); + } + + public static AdviceWithTask removeById(final RouteDefinition route, final String id) { + return doRemove(route, new MatchById(id)); + } + + @SuppressWarnings("unchecked") + private static AdviceWithTask doRemove(final RouteDefinition route, final MatchBy matchBy) { + return new AdviceWithTask() { + public void task() throws Exception { + boolean match = false; + Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class); + while (it.hasNext()) { + ProcessorDefinition output = it.next(); + if (matchBy.match(output)) { + ProcessorDefinition parent = output.getParent(); + if (parent != null) { + int index = parent.getOutputs().indexOf(output); + if (index != -1) { + match = true; + Object old = parent.getOutputs().remove(index); + LOG.info("AdviceWith (" + matchBy.getId() + ") : [" + old + "] --> remove"); + } + } + } + } + + if (!match) { + throw new IllegalArgumentException("There are no outputs which matches: " + matchBy.getId() + " in the route: " + route); + } + } + }; + } + + public static AdviceWithTask beforeByToString(final RouteDefinition route, final String toString, final ProcessorDefinition before) { + return doBefore(route, new MatchByToString(toString), before); + } + + public static AdviceWithTask beforeById(final RouteDefinition route, final String id, final ProcessorDefinition before) { + return doBefore(route, new MatchById(id), before); + } + + @SuppressWarnings("unchecked") + private static AdviceWithTask doBefore(final RouteDefinition route, final MatchBy matchBy, final ProcessorDefinition before) { + return new AdviceWithTask() { + public void task() throws Exception { + boolean match = false; + Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class); + while (it.hasNext()) { + ProcessorDefinition output = it.next(); + if (matchBy.match(output)) { + ProcessorDefinition parent = output.getParent(); + if (parent != null) { + int index = parent.getOutputs().indexOf(output); + if (index != -1) { + match = true; + Object existing = parent.getOutputs().get(index); + parent.getOutputs().add(index, before); + LOG.info("AdviceWith (" + matchBy.getId() + ") : [" + existing + "] --> before [" + before + "]"); + } + } + } + } + + if (!match) { + throw new IllegalArgumentException("There are no outputs which matches: " + matchBy.getId() + " in the route: " + route); + } + } + }; + } + + public static AdviceWithTask afterByToString(final RouteDefinition route, final String toString, final ProcessorDefinition after) { + return doAfter(route, new MatchByToString(toString), after); + } + + public static AdviceWithTask afterById(final RouteDefinition route, final String id, final ProcessorDefinition after) { + return doAfter(route, new MatchById(id), after); + } + + @SuppressWarnings("unchecked") + private static AdviceWithTask doAfter(final RouteDefinition route, final MatchBy matchBy, final ProcessorDefinition after) { + return new AdviceWithTask() { + public void task() throws Exception { + boolean match = false; + Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class); + while (it.hasNext()) { + ProcessorDefinition output = it.next(); + if (matchBy.match(output)) { + + ProcessorDefinition parent = output.getParent(); + if (parent != null) { + int index = parent.getOutputs().indexOf(output); + if (index != -1) { + match = true; + Object existing = parent.getOutputs().get(index); + parent.getOutputs().add(index + 1, after); + LOG.info("AdviceWith (" + matchBy.getId() + ") : [" + existing + "] --> after [" + after + "]"); + } + } + } + } + + if (!match) { + throw new IllegalArgumentException("There are no outputs which matches: " + matchBy.getId() + " in the route: " + route); + } + } + }; + } + +} Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java?rev=1072545&r1=1072544&r2=1072545&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java Sun Feb 20 10:22:21 2011 @@ -30,6 +30,9 @@ import org.apache.camel.model.OnExceptio import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.RoutesDefinition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * A <a href="http://camel.apache.org/dsl.html">Java DSL</a> which is * used to build {@link org.apache.camel.impl.DefaultRoute} instances in a {@link CamelContext} for smart routing. @@ -37,6 +40,7 @@ import org.apache.camel.model.RoutesDefi * @version */ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuilder { + protected Logger log = LoggerFactory.getLogger(getClass()); private AtomicBoolean initialized = new AtomicBoolean(false); private RoutesDefinition routeCollection = new RoutesDefinition(); @@ -343,6 +347,7 @@ public abstract class RouteBuilder exten /** * Factory method + * * @return the CamelContext */ protected CamelContext createContainer() { @@ -356,7 +361,7 @@ public abstract class RouteBuilder exten /** * Adds a collection of routes to this context * - * @param routes + * @param routes the routes * @throws Exception if the routes could not be created for whatever reason * @deprecated use {@link #includeRoutes(org.apache.camel.RoutesBuilder) includeRoutes} instead. */ Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/OutputDefinition.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/OutputDefinition.java?rev=1072545&r1=1072544&r2=1072545&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/OutputDefinition.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/OutputDefinition.java Sun Feb 20 10:22:21 2011 @@ -47,4 +47,14 @@ public class OutputDefinition<Type exten } } } + + @Override + public String getShortName() { + return "output"; + } + + @Override + public String toString() { + return getShortName() + " -> [" + outputs + "]"; + } } Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java?rev=1072545&r1=1072544&r2=1072545&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java Sun Feb 20 10:22:21 2011 @@ -37,6 +37,8 @@ import org.apache.camel.Route; import org.apache.camel.ServiceStatus; import org.apache.camel.ShutdownRoute; import org.apache.camel.ShutdownRunningTask; +import org.apache.camel.builder.AdviceWithRouteBuilder; +import org.apache.camel.builder.AdviceWithTask; import org.apache.camel.builder.ErrorHandlerBuilder; import org.apache.camel.builder.ErrorHandlerBuilderRef; import org.apache.camel.builder.RouteBuilder; @@ -179,6 +181,10 @@ public class RouteDefinition extends Pro /** * Advices this route with the route builder. * <p/> + * You can use a regular {@link RouteBuilder} but the specialized {@link org.apache.camel.builder.AdviceWithRouteBuilder} + * has additional features when using the <a href="http://camel.apache.org/advicewith.html">advice with</a> feature. + * We therefore suggest you to use the {@link org.apache.camel.builder.AdviceWithRouteBuilder}. + * <p/> * The advice process will add the interceptors, on exceptions, on completions etc. configured * from the route builder to this route. * <p/> @@ -190,14 +196,29 @@ public class RouteDefinition extends Pro * @param builder the route builder * @return a new route which is this route merged with the route builder * @throws Exception can be thrown from the route builder + * @see AdviceWithRouteBuilder */ public RouteDefinition adviceWith(CamelContext camelContext, RouteBuilder builder) throws Exception { ObjectHelper.notNull(camelContext, "CamelContext"); ObjectHelper.notNull(builder, "RouteBuilder"); + if (log.isDebugEnabled()) { + log.debug("AdviceWith route before: " + this); + } + + // inject this route into the advice route builder so it can access this route + // and offer features to manipulate the route directly + if (builder instanceof AdviceWithRouteBuilder) { + ((AdviceWithRouteBuilder) builder).setOriginalRoute(this); + } + // configure and prepare the routes from the builder RoutesDefinition routes = builder.configureRoutes(camelContext); + if (log.isDebugEnabled()) { + log.debug("AdviceWith routes: " + routes); + } + // we can only advice with a route builder without any routes if (!routes.getRoutes().isEmpty()) { throw new IllegalArgumentException("You can only advice from a RouteBuilder which has no existing routes." @@ -211,12 +232,23 @@ public class RouteDefinition extends Pro // stop and remove this existing route camelContext.removeRouteDefinition(this); + // any advice with tasks we should execute first? + if (builder instanceof AdviceWithRouteBuilder) { + List<AdviceWithTask> tasks = ((AdviceWithRouteBuilder) builder).getAdviceWithTasks(); + for (AdviceWithTask task : tasks) { + task.task(); + } + } + // now merge which also ensures that interceptors and the likes get mixed in correctly as well RouteDefinition merged = routes.route(this); // add the new merged route camelContext.getRouteDefinitions().add(0, merged); + // log the merged route at info level to make it easier to end users to spot any mistakes they may have made + log.info("AdviceWith route after: " + merged); + // and start it camelContext.startRoute(merged); return merged; Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksMatchTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksMatchTest.java?rev=1072545&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksMatchTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksMatchTest.java Sun Feb 20 10:22:21 2011 @@ -0,0 +1,61 @@ +/** + * 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.interceptor; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.AdviceWithRouteBuilder; +import org.apache.camel.builder.RouteBuilder; + +/** + * Advice with match multiple ids test + */ +public class AdviceWithTasksMatchTest extends ContextTestSupport { + + public void testReplaceMultipleIds() throws Exception { + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + // replace all gold id's with the following route path + adviceById("gold*").replace().multicast().to("mock:a").to("mock:b"); + } + }); + + getMockEndpoint("mock:foo").expectedMessageCount(0); + getMockEndpoint("mock:bar").expectedMessageCount(0); + getMockEndpoint("mock:a").expectedMessageCount(2); + getMockEndpoint("mock:b").expectedMessageCount(2); + getMockEndpoint("mock:result").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .to("mock:foo").id("gold-1") + .to("mock:bar").id("gold-2") + .to("mock:result").id("silver-1"); + } + }; + } +} \ No newline at end of file Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksTest.java (from r1072268, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithRouteIdTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithRouteIdTest.java&r1=1072268&r2=1072545&rev=1072545&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithRouteIdTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksTest.java Sun Feb 20 10:22:21 2011 @@ -16,26 +16,45 @@ */ package org.apache.camel.processor.interceptor; +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.AdviceWithRouteBuilder; import org.apache.camel.builder.RouteBuilder; /** - * @version + * Advice with tests */ -public class AdviceWithRouteIdTest extends AdviceWithTest { +public class AdviceWithTasksTest extends ContextTestSupport { - public void testAdvised() throws Exception { - context.getRouteDefinition("myRoute").adviceWith(context, new RouteBuilder() { + public void testUnknownId() throws Exception { + try { + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + adviceById("xxx").replace().to("mock:xxx"); + } + }); + fail("Should hve thrown exception"); + } catch (IllegalArgumentException e) { + assertTrue(e.getMessage(), e.getMessage().startsWith("There are no outputs which matches: xxx in the route")); + } + } + + public void testReplace() throws Exception { + // START SNIPPET: e1 + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { - interceptSendToEndpoint("mock:foo") - .skipSendToOriginalEndpoint() - .to("log:foo") - .to("mock:advised"); + // advice the node in the route which has id = bar + // and replace it with the following route path + adviceById("bar").replace().multicast().to("mock:a").to("mock:b"); } }); + // END SNIPPET: e1 - getMockEndpoint("mock:foo").expectedMessageCount(0); - getMockEndpoint("mock:advised").expectedMessageCount(1); + getMockEndpoint("mock:foo").expectedMessageCount(1); + getMockEndpoint("mock:bar").expectedMessageCount(0); + getMockEndpoint("mock:a").expectedMessageCount(1); + getMockEndpoint("mock:b").expectedMessageCount(1); getMockEndpoint("mock:result").expectedMessageCount(1); template.sendBody("direct:start", "Hello World"); @@ -43,14 +62,80 @@ public class AdviceWithRouteIdTest exten assertMockEndpointsSatisfied(); } + public void testRemove() throws Exception { + // START SNIPPET: e2 + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + // advice the node in the route which has id = bar and remove it + adviceById("bar").remove(); + } + }); + // END SNIPPET: e2 + + getMockEndpoint("mock:foo").expectedMessageCount(1); + getMockEndpoint("mock:result").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + + assertFalse("Should not have removed id", context.hasEndpoint("mock:bar") == null); + } + + public void testBefore() throws Exception { + // START SNIPPET: e3 + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + // advice the node in the route which has id = bar + // and insert the following route path before the adviced node + adviceById("bar").before().to("mock:a").transform(constant("Bye World")); + } + }); + // END SNIPPET: e3 + + getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:a").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:bar").expectedBodiesReceived("Bye World"); + getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + public void testAfter() throws Exception { + // START SNIPPET: e4 + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + // advice the node in the route which has id = bar + // and insert the following route path after the advice node + adviceById("bar").after().to("mock:a").transform(constant("Bye World")); + } + }); + // END SNIPPET: e4 + + getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:a").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:bar").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { - from("direct:start").routeId("myRoute").to("mock:foo").to("mock:result"); - - from("direct:bar").to("mock:bar"); + from("direct:start") + .to("mock:foo") + .to("mock:bar").id("bar") + .to("mock:result"); } }; } Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksToStringPatternTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksToStringPatternTest.java?rev=1072545&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksToStringPatternTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithTasksToStringPatternTest.java Sun Feb 20 10:22:21 2011 @@ -0,0 +1,131 @@ +/** + * 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.interceptor; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.builder.AdviceWithRouteBuilder; +import org.apache.camel.builder.RouteBuilder; + +/** + * Advice with using to string matching + */ +public class AdviceWithTasksToStringPatternTest extends ContextTestSupport { + + public void testUnknownId() throws Exception { + try { + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + adviceByToString("xxx").replace().to("mock:xxx"); + } + }); + fail("Should hve thrown exception"); + } catch (IllegalArgumentException e) { + assertTrue(e.getMessage(), e.getMessage().startsWith("There are no outputs which matches: xxx in the route")); + } + } + + public void testReplace() throws Exception { + // START SNIPPET: e1 + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + // advice nodes in the route which has foo anywhere in their to string representation + // and replace them with the following route path + adviceByToString(".*foo.*").replace().multicast().to("mock:a").to("mock:b"); + } + }); + // END SNIPPET: e1 + + getMockEndpoint("mock:foo").expectedMessageCount(0); + getMockEndpoint("mock:a").expectedMessageCount(1); + getMockEndpoint("mock:b").expectedMessageCount(1); + getMockEndpoint("mock:bar").expectedMessageCount(1); + getMockEndpoint("mock:result").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + public void testRemove() throws Exception { + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + adviceByToString(".*bar.*").remove(); + } + }); + + getMockEndpoint("mock:foo").expectedMessageCount(1); + getMockEndpoint("mock:result").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + + assertFalse("Should not have removed id", context.hasEndpoint("mock:bar") == null); + } + + public void testBefore() throws Exception { + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + adviceByToString(".*bar.*").before().to("mock:a").transform(constant("Bye World")); + } + }); + + getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:a").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:bar").expectedBodiesReceived("Bye World"); + getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + public void testAfter() throws Exception { + context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { + @Override + public void configure() throws Exception { + adviceByToString(".*bar.*").after().to("mock:a").transform(constant("Bye World")); + } + }); + + getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:a").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:bar").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .to("mock:foo") + .to("mock:bar") + .to("mock:result"); + } + }; + } +} \ No newline at end of file