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 2021/12/04 10:54:41 UTC
[camel] 02/04: CAMEL-17272: camel-spring-xml - Classic Spring XML add support for external route configuration XML files
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 5c8713bb6cebeb53bbac8c6d1a80edcf712eab53
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Dec 4 11:29:02 2021 +0100
CAMEL-17272: camel-spring-xml - Classic Spring XML add support for external route configuration XML files
---
.../org/apache/camel/spring/xml/camelContext.json | 1 +
.../camel/spring/xml/CamelContextFactoryBean.java | 15 ++++++
.../spring/xml/handler/CamelNamespaceHandler.java | 1 +
.../SpringRoutesConfigurationExternalTest.java | 48 +++++++++++++++++
.../SpringRoutesConfigurationExternalTest.xml | 57 ++++++++++++++++++++
.../services/org/apache/camel/model.properties | 1 +
.../resources/org/apache/camel/model/jaxb.index | 1 +
.../camel/model/routeConfigurationContextRef.json | 16 ++++++
.../RouteConfigurationContextRefDefinition.java | 62 ++++++++++++++++++++++
...uteConfigurationContextRefDefinitionHelper.java | 53 ++++++++++++++++++
.../core/xml/AbstractCamelContextFactoryBean.java | 19 +++++++
.../java/org/apache/camel/xml/in/ModelParser.java | 9 ++++
12 files changed, 283 insertions(+)
diff --git a/components/camel-spring-xml/src/generated/resources/org/apache/camel/spring/xml/camelContext.json b/components/camel-spring-xml/src/generated/resources/org/apache/camel/spring/xml/camelContext.json
index 42cb0b3..72f27e7 100644
--- a/components/camel-spring-xml/src/generated/resources/org/apache/camel/spring/xml/camelContext.json
+++ b/components/camel-spring-xml/src/generated/resources/org/apache/camel/spring/xml/camelContext.json
@@ -63,6 +63,7 @@
"resilience4jConfiguration": { "kind": "element", "displayName": "Resilience4j Configuration", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.Resilience4jConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Resilience4j Circuit Breaker EIP configurations" },
"defaultFaultToleranceConfiguration": { "kind": "element", "displayName": "Default Fault Tolerance Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.model.FaultToleranceConfigurationDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "MicroProfile Fault Tolerance EIP default configuration" },
"faultToleranceConfiguration": { "kind": "element", "displayName": "Fault Tolerance Configuration", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.FaultToleranceConfigurationDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "MicroProfile Circuit Breaker EIP configurations" },
+ "routeConfigurationContextRef": { "kind": "element", "displayName": "Route Configuration Context Ref", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteConfigurationContextRefDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Refers to XML route configurations to include as route configurations in this CamelContext." },
"routeTemplateContextRef": { "kind": "element", "displayName": "Route Template Context Ref", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteTemplateContextRefDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Refers to XML route templates to include as route templates in this CamelContext." },
"routeBuilder": { "kind": "element", "displayName": "Route Builder", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteBuilderDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Refers to Java RouteBuilder instances to include as routes in this CamelContext." },
"routeContextRef": { "kind": "element", "displayName": "Route Context Ref", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.RouteContextRefDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Refers to XML routes to include as routes in this CamelContext." },
diff --git a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelContextFactoryBean.java b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelContextFactoryBean.java
index 6c2bca3..cd47887 100644
--- a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelContextFactoryBean.java
+++ b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelContextFactoryBean.java
@@ -57,6 +57,7 @@ import org.apache.camel.model.PackageScanDefinition;
import org.apache.camel.model.Resilience4jConfigurationDefinition;
import org.apache.camel.model.RestContextRefDefinition;
import org.apache.camel.model.RouteBuilderDefinition;
+import org.apache.camel.model.RouteConfigurationContextRefDefinition;
import org.apache.camel.model.RouteConfigurationDefinition;
import org.apache.camel.model.RouteContextRefDefinition;
import org.apache.camel.model.RouteDefinition;
@@ -231,6 +232,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
private FaultToleranceConfigurationDefinition defaultFaultToleranceConfiguration;
@XmlElement(name = "faultToleranceConfiguration", type = Resilience4jConfigurationDefinition.class)
private List<FaultToleranceConfigurationDefinition> faultToleranceConfigurations;
+ @XmlElement(name = "routeConfigurationContextRef")
+ private List<RouteConfigurationContextRefDefinition> routeConfigurationRefs = new ArrayList<>();
@XmlElement(name = "routeTemplateContextRef")
private List<RouteTemplateContextRefDefinition> routeTemplateRefs = new ArrayList<>();
@XmlElement(name = "routeBuilder")
@@ -1225,6 +1228,18 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
}
@Override
+ public List<RouteConfigurationContextRefDefinition> getRouteConfigurationRefs() {
+ return routeConfigurationRefs;
+ }
+
+ /**
+ * Refers to XML route configurations to include as route configurations in this CamelContext.
+ */
+ public void setRouteConfigurationRefs(List<RouteConfigurationContextRefDefinition> routeConfigurationRefs) {
+ this.routeConfigurationRefs = routeConfigurationRefs;
+ }
+
+ @Override
public List<RouteTemplateContextRefDefinition> getRouteTemplateRefs() {
return routeTemplateRefs;
}
diff --git a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/handler/CamelNamespaceHandler.java b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/handler/CamelNamespaceHandler.java
index d525e8d..13268bd 100644
--- a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/handler/CamelNamespaceHandler.java
+++ b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/handler/CamelNamespaceHandler.java
@@ -434,6 +434,7 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport {
builder.addPropertyValue("validators", factoryBean.getValidators());
builder.addPropertyValue("onCompletions", factoryBean.getOnCompletions());
builder.addPropertyValue("onExceptions", factoryBean.getOnExceptions());
+ builder.addPropertyValue("routeConfigurationRefs", factoryBean.getRouteConfigurationRefs());
builder.addPropertyValue("routeTemplateRefs", factoryBean.getRouteTemplateRefs());
builder.addPropertyValue("builderRefs", factoryBean.getBuilderRefs());
builder.addPropertyValue("routeRefs", factoryBean.getRouteRefs());
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/SpringRoutesConfigurationExternalTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/SpringRoutesConfigurationExternalTest.java
new file mode 100644
index 0000000..a372b30
--- /dev/null
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/SpringRoutesConfigurationExternalTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class SpringRoutesConfigurationExternalTest extends SpringTestSupport {
+
+ @Override
+ protected AbstractXmlApplicationContext createApplicationContext() {
+ return new ClassPathXmlApplicationContext(
+ "org/apache/camel/spring/SpringRoutesConfigurationExternalTest.xml");
+ }
+
+ @Test
+ public void testRoutesConfigurationOnException() throws Exception {
+ getMockEndpoint("mock:error").expectedBodiesReceived("Bye World");
+
+ try {
+ template.sendBody("direct:start", "Hello World");
+ fail("Should throw exception");
+ } catch (Exception e) {
+ // expected
+ }
+ template.sendBody("direct:start2", "Bye World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+}
diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/SpringRoutesConfigurationExternalTest.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/SpringRoutesConfigurationExternalTest.xml
new file mode 100644
index 0000000..c83f58e
--- /dev/null
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/SpringRoutesConfigurationExternalTest.xml
@@ -0,0 +1,57 @@
+<?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
+ ">
+
+ <!-- this can be in another XML file that spring imports, but for testing we keep it in the same file -->
+ <routeConfigurationContext id="myConf" xmlns="http://camel.apache.org/schema/spring">
+ <routeConfiguration id="handleError">
+ <onException>
+ <exception>java.lang.Exception</exception>
+ <handled>
+ <constant>true</constant>
+ </handled>
+ <to uri="mock:error"/>
+ </onException>
+ </routeConfiguration>
+ </routeConfigurationContext>
+
+ <camelContext xmlns="http://camel.apache.org/schema/spring">
+
+ <!-- refer to external snippet -->
+ <routeConfigurationContextRef ref="myConf"/>
+
+ <route>
+ <from uri="direct:start"/>
+ <throwException exceptionType="java.lang.IllegalArgumentException" message="Foo"/>
+ </route>
+
+ <route routeConfigurationId="handleError">
+ <from uri="direct:start2"/>
+ <throwException exceptionType="java.lang.IllegalArgumentException" message="Foo2"/>
+ </route>
+
+ </camelContext>
+
+</beans>
diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
index 9a05154..f08ac58 100644
--- a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
+++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
@@ -138,6 +138,7 @@ roundRobin
route
routeBuilder
routeConfiguration
+routeConfigurationContextRef
routeConfigurations
routeContextRef
routeTemplate
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index b/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
index c9a58d7..d1cf5b7 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
@@ -63,6 +63,7 @@ Resilience4jConfigurationDefinition
RestContextRefDefinition
RollbackDefinition
RouteBuilderDefinition
+RouteConfigurationContextRefDefinition
RouteConfigurationDefinition
RouteConfigurationsDefinition
RouteContextRefDefinition
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/routeConfigurationContextRef.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/routeConfigurationContextRef.json
new file mode 100644
index 0000000..0e7b143
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/routeConfigurationContextRef.json
@@ -0,0 +1,16 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "routeConfigurationContextRef",
+ "title": "Route Configuration Context Ref",
+ "description": "To refer to an XML file with route configuration defined using the xml-dsl",
+ "deprecated": false,
+ "label": "configuration",
+ "javaType": "org.apache.camel.model.RouteConfigurationContextRefDefinition",
+ "input": false,
+ "output": false
+ },
+ "properties": {
+ "ref": { "kind": "attribute", "displayName": "Ref", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Reference to the route templates in the xml dsl" }
+ }
+}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationContextRefDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationContextRefDefinition.java
new file mode 100644
index 0000000..6ebabdd
--- /dev/null
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationContextRefDefinition.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.Metadata;
+
+/**
+ * To refer to an XML file with route configuration defined using the xml-dsl
+ */
+@Metadata(label = "configuration")
+@XmlRootElement(name = "routeConfigurationContextRef")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RouteConfigurationContextRefDefinition {
+ @XmlAttribute(required = true)
+ private String ref;
+
+ public RouteConfigurationContextRefDefinition() {
+ }
+
+ @Override
+ public String toString() {
+ return "RouteConfigurationContextRef[" + getRef() + "]";
+ }
+
+ public String getRef() {
+ return ref;
+ }
+
+ /**
+ * Reference to the route templates in the xml dsl
+ */
+ public void setRef(String ref) {
+ this.ref = ref;
+ }
+
+ public List<RouteConfigurationDefinition> lookupRouteConfigurations(CamelContext camelContext) {
+ return RouteConfigurationContextRefDefinitionHelper.lookupRouteConfigurations(camelContext, ref);
+ }
+
+}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationContextRefDefinitionHelper.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationContextRefDefinitionHelper.java
new file mode 100644
index 0000000..b0d878e
--- /dev/null
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationContextRefDefinitionHelper.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.support.CamelContextHelper;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Helper for {@link RouteConfigurationContextRefDefinition}.
+ */
+public final class RouteConfigurationContextRefDefinitionHelper {
+
+ private RouteConfigurationContextRefDefinitionHelper() {
+ }
+
+ /**
+ * Lookup the route configurations from the {@link RouteConfigurationContextRefDefinition}.
+ *
+ * @param camelContext the CamelContext
+ * @param ref the id of the {@link RouteConfigurationContextRefDefinition} to lookup and get the route
+ * configurations.
+ * @return the route configurations.
+ */
+ @SuppressWarnings("unchecked")
+ public static List<RouteConfigurationDefinition> lookupRouteConfigurations(CamelContext camelContext, String ref) {
+ ObjectHelper.notNull(camelContext, "camelContext");
+ ObjectHelper.notNull(ref, "ref");
+
+ List<RouteConfigurationDefinition> answer = CamelContextHelper.lookup(camelContext, ref, List.class);
+ if (answer == null) {
+ throw new IllegalArgumentException("Cannot find RouteConfigurationContext with id " + ref);
+ }
+ return answer;
+ }
+
+}
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index 5cbb090..79d77b4 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -73,6 +73,7 @@ import org.apache.camel.model.Resilience4jConfigurationDefinition;
import org.apache.camel.model.RestContextRefDefinition;
import org.apache.camel.model.RouteBuilderDefinition;
import org.apache.camel.model.RouteConfigurationContainer;
+import org.apache.camel.model.RouteConfigurationContextRefDefinition;
import org.apache.camel.model.RouteConfigurationDefinition;
import org.apache.camel.model.RouteContainer;
import org.apache.camel.model.RouteContextRefDefinition;
@@ -456,6 +457,9 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
// add route configurations
getContext().addRouteConfigurations(getRouteConfigurations());
+ // init route configurations
+ initRouteConfigurationRefs();
+
// init route templates
initRouteTemplateRefs();
@@ -868,6 +872,19 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
}
}
+ protected void initRouteConfigurationRefs() throws Exception {
+ // add route configuration refs to existing route configurations
+ if (getRouteConfigurationRefs() != null) {
+ for (RouteConfigurationContextRefDefinition ref : getRouteConfigurationRefs()) {
+ List<RouteConfigurationDefinition> defs = ref.lookupRouteConfigurations(getContext());
+ for (RouteConfigurationDefinition def : defs) {
+ LOG.debug("Adding route configuration from {} -> {}", ref, def);
+ getRouteConfigurations().add(def);
+ }
+ }
+ }
+ }
+
protected void initRouteTemplateRefs() throws Exception {
// add route template refs to existing route templates
if (getRouteTemplateRefs() != null) {
@@ -1013,6 +1030,8 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
public abstract CamelRouteControllerDefinition getCamelRouteController();
+ public abstract List<RouteConfigurationContextRefDefinition> getRouteConfigurationRefs();
+
public abstract List<RouteBuilderDefinition> getBuilderRefs();
public abstract List<RouteContextRefDefinition> getRouteRefs();
diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 8be755e..60eb730 100644
--- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -936,6 +936,15 @@ public class ModelParser extends BaseParser {
return identifiedTypeAttributeHandler().accept(def, key, val);
}, noElementHandler(), noValueHandler());
}
+ protected RouteConfigurationContextRefDefinition doParseRouteConfigurationContextRefDefinition() throws IOException, XmlPullParserException {
+ return doParse(new RouteConfigurationContextRefDefinition(), (def, key, val) -> {
+ if ("ref".equals(key)) {
+ def.setRef(val);
+ return true;
+ }
+ return false;
+ }, noElementHandler(), noValueHandler());
+ }
protected RouteConfigurationDefinition doParseRouteConfigurationDefinition() throws IOException, XmlPullParserException {
return doParse(new RouteConfigurationDefinition(),
optionalIdentifiedDefinitionAttributeHandler(), (def, key) -> {