You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2010/08/04 17:31:37 UTC
svn commit: r982303 - in /camel/trunk:
camel-core/src/main/java/org/apache/camel/builder/
camel-core/src/main/java/org/apache/camel/impl/
camel-core/src/main/java/org/apache/camel/model/
camel-core/src/test/java/org/apache/camel/impl/ camel-core/src/te...
Author: davsclaus
Date: Wed Aug 4 15:31:37 2010
New Revision: 982303
URL: http://svn.apache.org/viewvc?rev=982303&view=rev
Log:
CAMEL-3024: Routes added from JAXB need to be prepared before being add to CamelContext. camel-spring etc. does custom preparation.
Added:
camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java
camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route3.xml
- copied, changed from r982232, camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route1.xml
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
camel/trunk/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRouteDefinitionsFromXmlTest.java
camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
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=982303&r1=982302&r2=982303&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 Wed Aug 4 15:31:37 2010
@@ -293,6 +293,11 @@ public abstract class RouteBuilder exten
setErrorHandlerBuilder(camelContext.getErrorHandlerBuilder());
}
configure();
+ // mark all route definitions as custom prepared because
+ // a route builder prepares the route definitions correctly already
+ for (RouteDefinition route : getRouteCollection().getRoutes()) {
+ route.customPrepared();
+ }
}
}
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java?rev=982303&r1=982302&r2=982303&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java Wed Aug 4 15:31:37 2010
@@ -595,6 +595,8 @@ public class DefaultCamelContext extends
List<Route> routes = new ArrayList<Route>();
List<RouteContext> routeContexts = route.addRoutes(this, routes);
RouteService routeService = new RouteService(this, route, routeContexts, routes);
+ // must ensure route is prepared, before we can start it
+ route.prepare();
startRouteService(routeService, true);
}
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=982303&r1=982302&r2=982303&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 Wed Aug 4 15:31:37 2010
@@ -19,6 +19,7 @@ package org.apache.camel.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
@@ -57,6 +58,7 @@ import org.apache.camel.util.ObjectHelpe
@XmlType(propOrder = {"inputs", "outputs" })
@XmlAccessorType(XmlAccessType.PROPERTY)
public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
+ private final AtomicBoolean prepared = new AtomicBoolean(false);
private List<FromDefinition> inputs = new ArrayList<FromDefinition>();
private List<ProcessorDefinition> outputs = new ArrayList<ProcessorDefinition>();
private String group;
@@ -82,6 +84,40 @@ public class RouteDefinition extends Pro
from(endpoint);
}
+ /**
+ * Prepares the route definition to be ready to be added to {@link CamelContext}
+ */
+ public void prepare() {
+ if (prepared.compareAndSet(false, true)) {
+ // at first init the parent
+ RouteDefinitionHelper.initParent(this);
+
+ // abstracts is the cross cutting concerns
+ List<ProcessorDefinition> abstracts = new ArrayList<ProcessorDefinition>();
+
+ // upper is the cross cutting concerns such as interceptors, error handlers etc
+ List<ProcessorDefinition> upper = new ArrayList<ProcessorDefinition>();
+
+ // lower is the regular route
+ List<ProcessorDefinition> lower = new ArrayList<ProcessorDefinition>();
+
+ RouteDefinitionHelper.prepareRouteForInit(this, abstracts, lower);
+
+ // rebuild route as upper + lower
+ this.clearOutput();
+ this.getOutputs().addAll(lower);
+ this.getOutputs().addAll(0, upper);
+ }
+ }
+
+ /**
+ * Marks the route definition as already prepared, for example using custom logic
+ * such as a {@link RouteBuilder} or from <tt>camel-core-xml</tt> component.
+ */
+ public void customPrepared() {
+ prepared.set(true);
+ }
+
@Override
public String toString() {
return "Route[" + inputs + " -> " + outputs + "]";
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java?rev=982303&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/model/RouteDefinitionHelper.java Wed Aug 4 15:31:37 2010
@@ -0,0 +1,68 @@
+/**
+ * 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 java.util.List;
+
+/**
+ * Helper for {@link org.apache.camel.model.RouteDefinition}
+ * <p/>
+ * Utility methods to help preparing {@link org.apache.camel.model.RouteDefinition} before they are added to
+ * {@link org.apache.camel.CamelContext}.
+ *
+ * @version $Revision$
+ */
+public final class RouteDefinitionHelper {
+
+ private RouteDefinitionHelper() {
+ }
+
+ public static void initParent(RouteDefinition route) {
+ for (ProcessorDefinition output : route.getOutputs()) {
+ output.setParent(route);
+ if (output.getOutputs() != null) {
+ // recursive the outputs
+ initParent(output);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void initParent(ProcessorDefinition parent) {
+ List<ProcessorDefinition> children = parent.getOutputs();
+ for (ProcessorDefinition child : children) {
+ child.setParent(parent);
+ if (child.getOutputs() != null) {
+ // recursive the children
+ initParent(child);
+ }
+ }
+ }
+
+ public static void prepareRouteForInit(RouteDefinition route, List<ProcessorDefinition> abstracts,
+ List<ProcessorDefinition> lower) {
+ // filter the route into abstracts and lower
+ for (ProcessorDefinition output : route.getOutputs()) {
+ if (output.isAbstract()) {
+ abstracts.add(output);
+ } else {
+ lower.add(output);
+ }
+ }
+ }
+
+}
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRouteDefinitionsFromXmlTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRouteDefinitionsFromXmlTest.java?rev=982303&r1=982302&r2=982303&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRouteDefinitionsFromXmlTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/impl/CamelContextAddRouteDefinitionsFromXmlTest.java Wed Aug 4 15:31:37 2010
@@ -22,7 +22,10 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
import org.apache.camel.model.Constants;
+import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.model.RouteDefinition;
/**
@@ -106,4 +109,50 @@ public class CamelContextAddRouteDefinit
assertMockEndpointsSatisfied();
}
+ public void testAddRouteDefinitionsFromXmlIsPrepared() throws Exception {
+ RouteDefinition route = loadRoute("route1.xml");
+ assertNotNull(route);
+
+ assertEquals("foo", route.getId());
+ assertEquals(0, context.getRoutes().size());
+
+ context.addRouteDefinition(route);
+ assertEquals(1, context.getRoutes().size());
+ assertTrue("Route should be started", context.getRouteStatus("foo").isStarted());
+
+ // should be prepared, check parents has been set
+ assertNotNull("Parent should be set on outputs");
+ route = context.getRouteDefinition("foo");
+ for (ProcessorDefinition output : route.getOutputs()) {
+ assertNotNull("Parent should be set on output", output.getParent());
+ assertEquals(route, output.getParent());
+ }
+ }
+
+ public void testAddRouteDefinitionsFromXml3() throws Exception {
+ RouteDefinition route = loadRoute("route3.xml");
+ assertNotNull(route);
+
+ assertEquals("foo", route.getId());
+ assertEquals(0, context.getRoutes().size());
+
+ context.addRouteDefinition(route);
+ assertEquals(1, context.getRoutes().size());
+ assertTrue("Route should be started", context.getRouteStatus("foo").isStarted());
+
+ getMockEndpoint("mock:foo").whenExchangeReceived(2, new Processor() {
+ public void process(Exchange exchange) throws Exception {
+ exchange.setException(new IllegalArgumentException("Damn"));
+ }
+ });
+
+ getMockEndpoint("mock:result").expectedBodiesReceived("Hello World");
+ getMockEndpoint("mock:handled").expectedBodiesReceived("Bye World");
+
+ template.sendBody("direct:start", "Hello World");
+ template.sendBody("direct:start", "Bye World");
+
+ assertMockEndpointsSatisfied();
+ }
+
}
Copied: camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route3.xml (from r982232, camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route1.xml)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route3.xml?p2=camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route3.xml&p1=camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route1.xml&r1=982232&r2=982303&rev=982303&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route1.xml (original)
+++ camel/trunk/camel-core/src/test/resources/org/apache/camel/impl/route3.xml Wed Aug 4 15:31:37 2010
@@ -17,5 +17,11 @@
-->
<route id="foo" xmlns="http://camel.apache.org/schema/spring">
<from uri="direct:start"/>
+ <onException>
+ <exception>java.lang.IllegalArgumentException</exception>
+ <handled><constant>true</constant></handled>
+ <to uri="mock:handled"/>
+ </onException>
+ <to uri="mock:foo"/>
<to uri="mock:result"/>
</route>
Modified: camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java?rev=982303&r1=982302&r2=982303&view=diff
==============================================================================
--- camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java (original)
+++ camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java Wed Aug 4 15:31:37 2010
@@ -53,6 +53,7 @@ import org.apache.camel.model.RouteBuild
import org.apache.camel.model.RouteContainer;
import org.apache.camel.model.RouteContextRefDefinition;
import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RouteDefinitionHelper;
import org.apache.camel.model.ThreadPoolProfileDefinition;
import org.apache.camel.model.TransactedDefinition;
import org.apache.camel.model.config.PropertiesDefinition;
@@ -274,7 +275,7 @@ public abstract class AbstractCamelConte
for (RouteDefinition route : getRoutes()) {
// at first init the parent
- initParent(route);
+ RouteDefinitionHelper.initParent(route);
// abstracts is the cross cutting concerns
List<ProcessorDefinition> abstracts = new ArrayList<ProcessorDefinition>();
@@ -285,7 +286,7 @@ public abstract class AbstractCamelConte
// lower is the regular route
List<ProcessorDefinition> lower = new ArrayList<ProcessorDefinition>();
- prepareRouteForInit(route, abstracts, lower);
+ RouteDefinitionHelper.prepareRouteForInit(route, abstracts, lower);
// interceptors should be first for the cross cutting concerns
initInterceptors(route, upper);
@@ -300,6 +301,9 @@ public abstract class AbstractCamelConte
route.clearOutput();
route.getOutputs().addAll(lower);
route.getOutputs().addAll(0, upper);
+
+ // mark as custom prepared
+ route.customPrepared();
}
if (getDataFormats() != null) {
@@ -318,47 +322,13 @@ public abstract class AbstractCamelConte
protected abstract void initCustomRegistry(T context);
- private void prepareRouteForInit(RouteDefinition route, List<ProcessorDefinition> abstracts,
- List<ProcessorDefinition> lower) {
- // filter the route into abstracts and lower
- for (ProcessorDefinition output : route.getOutputs()) {
- if (output.isAbstract()) {
- abstracts.add(output);
- } else {
- lower.add(output);
- }
- }
- }
-
- private void initParent(RouteDefinition route) {
- for (ProcessorDefinition output : route.getOutputs()) {
- output.setParent(route);
- if (output.getOutputs() != null) {
- // recursive the outputs
- initParent(output);
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private void initParent(ProcessorDefinition parent) {
- List<ProcessorDefinition> children = parent.getOutputs();
- for (ProcessorDefinition child : children) {
- child.setParent(parent);
- if (child.getOutputs() != null) {
- // recursive the children
- initParent(child);
- }
- }
- }
-
private void initOnExceptions(List<ProcessorDefinition> abstracts, List<ProcessorDefinition> upper) {
// add global on exceptions if any
List<OnExceptionDefinition> onExceptions = getOnExceptions();
if (onExceptions != null && !onExceptions.isEmpty()) {
// init the parent
for (OnExceptionDefinition global : onExceptions) {
- initParent(global);
+ RouteDefinitionHelper.initParent(global);
}
abstracts.addAll(onExceptions);
}
@@ -378,7 +348,7 @@ public abstract class AbstractCamelConte
for (InterceptDefinition intercept : getIntercepts()) {
intercept.afterPropertiesSet();
// init the parent
- initParent(intercept);
+ RouteDefinitionHelper.initParent(intercept);
// add as first output so intercept is handled before the actual route and that gives
// us the needed head start to init and be able to intercept all the remaining processing steps
upper.add(0, intercept);
@@ -402,7 +372,7 @@ public abstract class AbstractCamelConte
if (match) {
intercept.afterPropertiesSet();
// init the parent
- initParent(intercept);
+ RouteDefinitionHelper.initParent(intercept);
// add as first output so intercept is handled before the actual route and that gives
// us the needed head start to init and be able to intercept all the remaining processing steps
upper.add(0, intercept);
@@ -413,7 +383,7 @@ public abstract class AbstractCamelConte
for (InterceptSendToEndpointDefinition intercept : getInterceptSendToEndpoints()) {
intercept.afterPropertiesSet();
// init the parent
- initParent(intercept);
+ RouteDefinitionHelper.initParent(intercept);
// add as first output so intercept is handled before the actual route and that gives
// us the needed head start to init and be able to intercept all the remaining processing steps
upper.add(0, intercept);
@@ -435,7 +405,7 @@ public abstract class AbstractCamelConte
completions = getOnCompletions();
// init the parent
for (OnCompletionDefinition global : completions) {
- initParent(global);
+ RouteDefinitionHelper.initParent(global);
}
}