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 2013/08/26 11:50:09 UTC
[1/2] git commit: CAMEL-6291: Fixed to not share
the routes between the s as that can cause side-effects.
Updated Branches:
refs/heads/camel-2.11.x 9938a4de4 -> f85ca1d00
refs/heads/master 5721e40ef -> cfa3b5f53
CAMEL-6291: Fixed <routeContextRef> to not share the routes between the <camelContext>s as that can cause side-effects.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/cfa3b5f5
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cfa3b5f5
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cfa3b5f5
Branch: refs/heads/master
Commit: cfa3b5f534651d844843a3d0599ef34caf9db6f5
Parents: 5721e40
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Aug 26 11:09:06 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Aug 26 11:49:08 2013 +0200
----------------------------------------------------------------------
.../camel/model/RouteContextRefDefinition.java | 11 +-
.../model/RouteContextRefDefinitionHelper.java | 135 +++++++++++++++++++
...PlaceholderMultipleCamelContextRefsTest.java | 61 +++++++++
.../src/test/resources/mycamel-1.properties | 18 +++
.../src/test/resources/mycamel-2.properties | 18 +++
...yPlaceholderMultipleCamelContextRefsTest.xml | 42 ++++++
6 files changed, 275 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/cfa3b5f5/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java b/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java
index 12e59cf..87667a3 100644
--- a/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java
@@ -23,8 +23,6 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.camel.CamelContext;
-import org.apache.camel.util.CamelContextHelper;
-import org.apache.camel.util.ObjectHelper;
/**
* Represents an XML <routeContextRef/> element
@@ -55,14 +53,7 @@ public class RouteContextRefDefinition {
@SuppressWarnings({"unchecked", "rawtypes"})
public List<RouteDefinition> lookupRoutes(CamelContext camelContext) {
- ObjectHelper.notNull(camelContext, "camelContext", this);
- ObjectHelper.notNull(ref, "ref", this);
-
- List answer = CamelContextHelper.lookup(camelContext, ref, List.class);
- if (answer == null) {
- throw new IllegalArgumentException("Cannot find RouteContext with id " + ref);
- }
- return answer;
+ return RouteContextRefDefinitionHelper.lookupRoutes(camelContext, ref);
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/cfa3b5f5/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinitionHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinitionHelper.java b/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinitionHelper.java
new file mode 100644
index 0000000..0f69104
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinitionHelper.java
@@ -0,0 +1,135 @@
+/**
+ * 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.language.NamespaceAwareExpression;
+import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Helper for {@link RouteContextRefDefinition}.
+ */
+public final class RouteContextRefDefinitionHelper {
+
+ private static JAXBContext jaxbContext;
+
+
+ /**
+ * Lookup the routes from the {@link RouteContextRefDefinition}.
+ * <p/>
+ * This implmementation must be used to lookup the routes as it performs a deep clone of the routes
+ * as a {@link RouteContextRefDefinition} can be re-used with multiple {@link CamelContext} and each
+ * context should have their own instances of the routes. This is to ensure no side-effefts and sharing
+ * of instances between the contexts. For example such as property placeholders may be context specific
+ * so the routes should not use placeholders from another {@link CamelContext}.
+ *
+ * @param camelContext the CamelContext
+ * @param ref the id of the {@link RouteContextRefDefinition} to lookup and get the rotues.
+ * @return the routes.
+ */
+ public static synchronized List<RouteDefinition> lookupRoutes(CamelContext camelContext, String ref) {
+ ObjectHelper.notNull(camelContext, "camelContext");
+ ObjectHelper.notNull(ref, "ref");
+
+ List<RouteDefinition> answer = CamelContextHelper.lookup(camelContext, ref, List.class);
+ if (answer == null) {
+ throw new IllegalArgumentException("Cannot find RouteContext with id " + ref);
+ }
+
+ // must clone the route definitions as they can be reused with multiple CamelContexts
+ // and they would need their own instances of the definitions to not have side effects among
+ // the CamelContext - for example property placeholder resolutions etc.
+ List<RouteDefinition> clones = new ArrayList<RouteDefinition>(answer.size());
+ try {
+ JAXBContext jaxb = getOrCreateJAXBContext();
+ for (RouteDefinition def : answer) {
+ RouteDefinition clone = cloneRouteDefinition(jaxb, def);
+ if (clone != null) {
+ clones.add(clone);
+ }
+ }
+ } catch (Exception e) {
+ throw ObjectHelper.wrapRuntimeCamelException(e);
+ }
+
+ return clones;
+ }
+
+ private static synchronized JAXBContext getOrCreateJAXBContext() throws JAXBException {
+ if (jaxbContext == null) {
+ // must use classloader from CamelContext to have JAXB working
+ jaxbContext = JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES, CamelContext.class.getClassLoader());
+ }
+ return jaxbContext;
+ }
+
+ private static RouteDefinition cloneRouteDefinition(JAXBContext jaxbContext, RouteDefinition def) throws JAXBException {
+ Marshaller marshal = jaxbContext.createMarshaller();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ marshal.marshal(def, bos);
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ Object clone = unmarshaller.unmarshal(bis);
+
+ if (clone != null && clone instanceof RouteDefinition) {
+ RouteDefinition def2 = (RouteDefinition) clone;
+
+ // need to clone the namespaces also as they are not JAXB marshalled (as they are transient)
+ Iterator<ExpressionNode> it = ProcessorDefinitionHelper.filterTypeInOutputs(def.getOutputs(), ExpressionNode.class);
+ Iterator<ExpressionNode> it2 = ProcessorDefinitionHelper.filterTypeInOutputs(def2.getOutputs(), ExpressionNode.class);
+ while (it.hasNext() && it2.hasNext()) {
+ ExpressionNode node = it.next();
+ ExpressionNode node2 = it2.next();
+
+ NamespaceAwareExpression name = null;
+ NamespaceAwareExpression name2 = null;
+ if (node.getExpression() instanceof NamespaceAwareExpression) {
+ name = (NamespaceAwareExpression) node.getExpression();
+ }
+ if (node2.getExpression() instanceof NamespaceAwareExpression) {
+ name2 = (NamespaceAwareExpression) node2.getExpression();
+ }
+
+ if (name != null && name2 != null && name.getNamespaces() != null && !name.getNamespaces().isEmpty()) {
+ Map<String, String> map = new HashMap<String, String>();
+ map.putAll(name.getNamespaces());
+ name2.setNamespaces(map);
+ }
+ }
+
+ return def2;
+ }
+
+ return null;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/cfa3b5f5/components/camel-spring/src/test/java/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.java
new file mode 100644
index 0000000..4d953cb
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.java
@@ -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.spring.config;
+
+import junit.framework.TestCase;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * @version
+ */
+public class RouteRefPropertyPlaceholderMultipleCamelContextRefsTest extends TestCase {
+
+ protected AbstractXmlApplicationContext createApplicationContext() {
+ return new ClassPathXmlApplicationContext("org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml");
+ }
+
+ public void testSpringTwoCamelContextDirectEndpoint() throws Exception {
+ AbstractXmlApplicationContext ac = createApplicationContext();
+ ac.start();
+
+ CamelContext camel1 = ac.getBean("myCamel-1", CamelContext.class);
+ CamelContext camel2 = ac.getBean("myCamel-2", CamelContext.class);
+
+ Endpoint start1 = camel1.getEndpoint("direct:start");
+ Endpoint start2 = camel2.getEndpoint("direct:start");
+ assertNotSame(start1, start2);
+
+ MockEndpoint mock1 = camel1.getEndpoint("mock:end-1", MockEndpoint.class);
+ mock1.expectedBodiesReceived("Hello World");
+
+ MockEndpoint mock2 = camel2.getEndpoint("mock:end-2", MockEndpoint.class);
+ mock2.expectedBodiesReceived("Bye World");
+
+ camel1.createProducerTemplate().sendBody("direct:start", "Hello World");
+ camel2.createProducerTemplate().sendBody("direct:start", "Bye World");
+
+ mock1.assertIsSatisfied();
+ mock2.assertIsSatisfied();
+
+ ac.stop();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/cfa3b5f5/components/camel-spring/src/test/resources/mycamel-1.properties
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/mycamel-1.properties b/components/camel-spring/src/test/resources/mycamel-1.properties
new file mode 100644
index 0000000..508e0dc
--- /dev/null
+++ b/components/camel-spring/src/test/resources/mycamel-1.properties
@@ -0,0 +1,18 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+
+end=mock:end-1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/cfa3b5f5/components/camel-spring/src/test/resources/mycamel-2.properties
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/mycamel-2.properties b/components/camel-spring/src/test/resources/mycamel-2.properties
new file mode 100644
index 0000000..34fecb9
--- /dev/null
+++ b/components/camel-spring/src/test/resources/mycamel-2.properties
@@ -0,0 +1,18 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+
+end=mock:end-2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/cfa3b5f5/components/camel-spring/src/test/resources/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml
new file mode 100644
index 0000000..b690aa6
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <routeContext id="myCoolRoute" xmlns="http://camel.apache.org/schema/spring">
+ <route id="cool">
+ <from uri="direct:start"/>
+ <to uri="{{end}}"/>
+ </route>
+ </routeContext>
+
+ <camelContext id="myCamel-1" xmlns="http://camel.apache.org/schema/spring">
+ <propertyPlaceholder id="properties1" location="mycamel-1.properties"/>
+ <routeContextRef ref="myCoolRoute"/>
+ </camelContext>
+
+ <camelContext id="myCamel-2" xmlns="http://camel.apache.org/schema/spring">
+ <propertyPlaceholder id="properties2" location="mycamel-2.properties"/>
+ <routeContextRef ref="myCoolRoute"/>
+ </camelContext>
+
+</beans>
[2/2] git commit: CAMEL-6291: Fixed to not share
the routes between the s as that can cause side-effects.
Posted by da...@apache.org.
CAMEL-6291: Fixed <routeContextRef> to not share the routes between the <camelContext>s as that can cause side-effects.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f85ca1d0
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f85ca1d0
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f85ca1d0
Branch: refs/heads/camel-2.11.x
Commit: f85ca1d001ef05422e262c7b8e6a7a69ec397e67
Parents: 9938a4d
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Aug 26 11:09:06 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Aug 26 11:49:55 2013 +0200
----------------------------------------------------------------------
.../camel/model/RouteContextRefDefinition.java | 11 +-
.../model/RouteContextRefDefinitionHelper.java | 135 +++++++++++++++++++
...PlaceholderMultipleCamelContextRefsTest.java | 61 +++++++++
.../src/test/resources/mycamel-1.properties | 18 +++
.../src/test/resources/mycamel-2.properties | 18 +++
...yPlaceholderMultipleCamelContextRefsTest.xml | 42 ++++++
6 files changed, 275 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/f85ca1d0/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java b/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java
index 12e59cf..87667a3 100644
--- a/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinition.java
@@ -23,8 +23,6 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.camel.CamelContext;
-import org.apache.camel.util.CamelContextHelper;
-import org.apache.camel.util.ObjectHelper;
/**
* Represents an XML <routeContextRef/> element
@@ -55,14 +53,7 @@ public class RouteContextRefDefinition {
@SuppressWarnings({"unchecked", "rawtypes"})
public List<RouteDefinition> lookupRoutes(CamelContext camelContext) {
- ObjectHelper.notNull(camelContext, "camelContext", this);
- ObjectHelper.notNull(ref, "ref", this);
-
- List answer = CamelContextHelper.lookup(camelContext, ref, List.class);
- if (answer == null) {
- throw new IllegalArgumentException("Cannot find RouteContext with id " + ref);
- }
- return answer;
+ return RouteContextRefDefinitionHelper.lookupRoutes(camelContext, ref);
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/f85ca1d0/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinitionHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinitionHelper.java b/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinitionHelper.java
new file mode 100644
index 0000000..0f69104
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/RouteContextRefDefinitionHelper.java
@@ -0,0 +1,135 @@
+/**
+ * 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.language.NamespaceAwareExpression;
+import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Helper for {@link RouteContextRefDefinition}.
+ */
+public final class RouteContextRefDefinitionHelper {
+
+ private static JAXBContext jaxbContext;
+
+
+ /**
+ * Lookup the routes from the {@link RouteContextRefDefinition}.
+ * <p/>
+ * This implmementation must be used to lookup the routes as it performs a deep clone of the routes
+ * as a {@link RouteContextRefDefinition} can be re-used with multiple {@link CamelContext} and each
+ * context should have their own instances of the routes. This is to ensure no side-effefts and sharing
+ * of instances between the contexts. For example such as property placeholders may be context specific
+ * so the routes should not use placeholders from another {@link CamelContext}.
+ *
+ * @param camelContext the CamelContext
+ * @param ref the id of the {@link RouteContextRefDefinition} to lookup and get the rotues.
+ * @return the routes.
+ */
+ public static synchronized List<RouteDefinition> lookupRoutes(CamelContext camelContext, String ref) {
+ ObjectHelper.notNull(camelContext, "camelContext");
+ ObjectHelper.notNull(ref, "ref");
+
+ List<RouteDefinition> answer = CamelContextHelper.lookup(camelContext, ref, List.class);
+ if (answer == null) {
+ throw new IllegalArgumentException("Cannot find RouteContext with id " + ref);
+ }
+
+ // must clone the route definitions as they can be reused with multiple CamelContexts
+ // and they would need their own instances of the definitions to not have side effects among
+ // the CamelContext - for example property placeholder resolutions etc.
+ List<RouteDefinition> clones = new ArrayList<RouteDefinition>(answer.size());
+ try {
+ JAXBContext jaxb = getOrCreateJAXBContext();
+ for (RouteDefinition def : answer) {
+ RouteDefinition clone = cloneRouteDefinition(jaxb, def);
+ if (clone != null) {
+ clones.add(clone);
+ }
+ }
+ } catch (Exception e) {
+ throw ObjectHelper.wrapRuntimeCamelException(e);
+ }
+
+ return clones;
+ }
+
+ private static synchronized JAXBContext getOrCreateJAXBContext() throws JAXBException {
+ if (jaxbContext == null) {
+ // must use classloader from CamelContext to have JAXB working
+ jaxbContext = JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES, CamelContext.class.getClassLoader());
+ }
+ return jaxbContext;
+ }
+
+ private static RouteDefinition cloneRouteDefinition(JAXBContext jaxbContext, RouteDefinition def) throws JAXBException {
+ Marshaller marshal = jaxbContext.createMarshaller();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ marshal.marshal(def, bos);
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ Object clone = unmarshaller.unmarshal(bis);
+
+ if (clone != null && clone instanceof RouteDefinition) {
+ RouteDefinition def2 = (RouteDefinition) clone;
+
+ // need to clone the namespaces also as they are not JAXB marshalled (as they are transient)
+ Iterator<ExpressionNode> it = ProcessorDefinitionHelper.filterTypeInOutputs(def.getOutputs(), ExpressionNode.class);
+ Iterator<ExpressionNode> it2 = ProcessorDefinitionHelper.filterTypeInOutputs(def2.getOutputs(), ExpressionNode.class);
+ while (it.hasNext() && it2.hasNext()) {
+ ExpressionNode node = it.next();
+ ExpressionNode node2 = it2.next();
+
+ NamespaceAwareExpression name = null;
+ NamespaceAwareExpression name2 = null;
+ if (node.getExpression() instanceof NamespaceAwareExpression) {
+ name = (NamespaceAwareExpression) node.getExpression();
+ }
+ if (node2.getExpression() instanceof NamespaceAwareExpression) {
+ name2 = (NamespaceAwareExpression) node2.getExpression();
+ }
+
+ if (name != null && name2 != null && name.getNamespaces() != null && !name.getNamespaces().isEmpty()) {
+ Map<String, String> map = new HashMap<String, String>();
+ map.putAll(name.getNamespaces());
+ name2.setNamespaces(map);
+ }
+ }
+
+ return def2;
+ }
+
+ return null;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f85ca1d0/components/camel-spring/src/test/java/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.java
new file mode 100644
index 0000000..4d953cb
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.java
@@ -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.spring.config;
+
+import junit.framework.TestCase;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * @version
+ */
+public class RouteRefPropertyPlaceholderMultipleCamelContextRefsTest extends TestCase {
+
+ protected AbstractXmlApplicationContext createApplicationContext() {
+ return new ClassPathXmlApplicationContext("org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml");
+ }
+
+ public void testSpringTwoCamelContextDirectEndpoint() throws Exception {
+ AbstractXmlApplicationContext ac = createApplicationContext();
+ ac.start();
+
+ CamelContext camel1 = ac.getBean("myCamel-1", CamelContext.class);
+ CamelContext camel2 = ac.getBean("myCamel-2", CamelContext.class);
+
+ Endpoint start1 = camel1.getEndpoint("direct:start");
+ Endpoint start2 = camel2.getEndpoint("direct:start");
+ assertNotSame(start1, start2);
+
+ MockEndpoint mock1 = camel1.getEndpoint("mock:end-1", MockEndpoint.class);
+ mock1.expectedBodiesReceived("Hello World");
+
+ MockEndpoint mock2 = camel2.getEndpoint("mock:end-2", MockEndpoint.class);
+ mock2.expectedBodiesReceived("Bye World");
+
+ camel1.createProducerTemplate().sendBody("direct:start", "Hello World");
+ camel2.createProducerTemplate().sendBody("direct:start", "Bye World");
+
+ mock1.assertIsSatisfied();
+ mock2.assertIsSatisfied();
+
+ ac.stop();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/f85ca1d0/components/camel-spring/src/test/resources/mycamel-1.properties
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/mycamel-1.properties b/components/camel-spring/src/test/resources/mycamel-1.properties
new file mode 100644
index 0000000..508e0dc
--- /dev/null
+++ b/components/camel-spring/src/test/resources/mycamel-1.properties
@@ -0,0 +1,18 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+
+end=mock:end-1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/f85ca1d0/components/camel-spring/src/test/resources/mycamel-2.properties
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/mycamel-2.properties b/components/camel-spring/src/test/resources/mycamel-2.properties
new file mode 100644
index 0000000..34fecb9
--- /dev/null
+++ b/components/camel-spring/src/test/resources/mycamel-2.properties
@@ -0,0 +1,18 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+
+end=mock:end-2
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/f85ca1d0/components/camel-spring/src/test/resources/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml
new file mode 100644
index 0000000..b690aa6
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/config/RouteRefPropertyPlaceholderMultipleCamelContextRefsTest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <routeContext id="myCoolRoute" xmlns="http://camel.apache.org/schema/spring">
+ <route id="cool">
+ <from uri="direct:start"/>
+ <to uri="{{end}}"/>
+ </route>
+ </routeContext>
+
+ <camelContext id="myCamel-1" xmlns="http://camel.apache.org/schema/spring">
+ <propertyPlaceholder id="properties1" location="mycamel-1.properties"/>
+ <routeContextRef ref="myCoolRoute"/>
+ </camelContext>
+
+ <camelContext id="myCamel-2" xmlns="http://camel.apache.org/schema/spring">
+ <propertyPlaceholder id="properties2" location="mycamel-2.properties"/>
+ <routeContextRef ref="myCoolRoute"/>
+ </camelContext>
+
+</beans>