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/08/03 12:33:32 UTC
[camel] 02/22: CAMEL-16757: routes configuration for intercept,
on completion
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch CAMEL-16757b
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 90824ad1050077dca392489f49bc522ee47a2951
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 2 07:36:50 2021 +0200
CAMEL-16757: routes configuration for intercept, on completion
---
.../org/apache/camel/catalog/models.properties | 5 +-
...sConfiguration.json => routeConfiguration.json} | 8 +-
.../camel/catalog/models/routeConfigurations.json | 16 ++
.../camel/catalog/models/routesConfigurations.json | 17 --
.../camel/catalog/models/templateBeanFactory.json | 17 --
.../apache/camel/catalog/schemas/camel-spring.xsd | 82 ++++----
.../camel/model/RouteConfigurationDefinition.java | 60 ++++++
.../model/RoutesConfigurationBuilderTest.java | 225 ++++++++++++++++++++-
8 files changed, 345 insertions(+), 85 deletions(-)
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
index fd5fa5c..e0d7e06 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
@@ -145,6 +145,8 @@ rollback
roundRobin
route
routeBuilder
+routeConfiguration
+routeConfigurations
routeContext
routeContextRef
routeTemplate
@@ -152,8 +154,6 @@ routeTemplateContext
routeTemplateContextRef
routeTemplates
routes
-routesConfiguration
-routesConfigurations
routingSlip
rss
saga
@@ -189,7 +189,6 @@ syslog
tarfile
template
templateBean
-templateBeanFactory
templateParameter
templateScript
threadPool
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routesConfiguration.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeConfiguration.json
similarity index 76%
rename from catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routesConfiguration.json
rename to catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeConfiguration.json
index c4a5307..515c123 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routesConfiguration.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeConfiguration.json
@@ -1,12 +1,12 @@
{
"model": {
"kind": "model",
- "name": "routesConfiguration",
- "title": "Routes Configuration",
- "description": "Global configuration for Camel routes",
+ "name": "routeConfiguration",
+ "title": "Route Configuration",
+ "description": "Reusable configuration for Camel route(s).",
"deprecated": false,
"label": "configuration",
- "javaType": "org.apache.camel.model.RoutesConfigurationDefinition",
+ "javaType": "org.apache.camel.model.RouteConfigurationDefinition",
"input": false,
"output": false
},
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeConfigurations.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeConfigurations.json
new file mode 100644
index 0000000..d9d128f
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeConfigurations.json
@@ -0,0 +1,16 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "routeConfigurations",
+ "title": "Route Configurations",
+ "description": "A series of route configurations",
+ "deprecated": false,
+ "label": "configuration",
+ "javaType": "org.apache.camel.model.RouteConfigurationsDefinition",
+ "input": false,
+ "output": false
+ },
+ "properties": {
+
+ }
+}
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routesConfigurations.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routesConfigurations.json
deleted file mode 100644
index 8bd9060..0000000
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routesConfigurations.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "model": {
- "kind": "model",
- "name": "routesConfigurations",
- "title": "Routes Configurations",
- "description": "A series of global configuration for Camel routes",
- "deprecated": false,
- "label": "configuration",
- "javaType": "org.apache.camel.model.RoutesConfigurationsDefinition",
- "input": false,
- "output": false
- },
- "properties": {
- "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the id of this node" },
- "description": { "kind": "element", "displayName": "Description", "required": false, "type": "object", "javaType": "org.apache.camel.model.DescriptionDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the description of this node" }
- }
-}
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateBeanFactory.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateBeanFactory.json
deleted file mode 100644
index 538a54b..0000000
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateBeanFactory.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "model": {
- "kind": "model",
- "name": "templateBeanFactory",
- "title": "Template Bean Factory",
- "description": "A route template bean factory (local bean)",
- "deprecated": false,
- "label": "configuration",
- "javaType": "org.apache.camel.model.RouteTemplateBeanFactoryDefinition",
- "input": false,
- "output": false
- },
- "properties": {
- "language": { "kind": "attribute", "displayName": "Language", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "bean", "groovy", "joor", "language", "mvel", "ognl" ], "deprecated": false, "autowired": false, "secret": false, "description": "The language to use for creating the bean (such as groovy, joor)" },
- "script": { "kind": "value", "displayName": "Script", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The script to execute that creates the bean. If the script use the prefix resource: such as resource:classpath:com\/foo\/myscript.groovy, resource:file:\/var\/myscript.groovy, then its loaded from the external resource." }
- }
-}
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index 1000a99..a9e8def 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -1265,6 +1265,22 @@ To refer to a Java org.apache.camel.builder.RouteBuilder instance to use.
</xs:annotation>
</xs:element>
+ <xs:element name="routeConfiguration" type="tns:routeConfigurationDefinition">
+ <xs:annotation>
+ <xs:documentation xml:lang="en"><![CDATA[
+Reusable configuration for Camel route(s).
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+
+ <xs:element name="routeConfigurations" type="tns:routeConfigurationsDefinition">
+ <xs:annotation>
+ <xs:documentation xml:lang="en"><![CDATA[
+A series of route configurations
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:element>
+
<xs:element name="routeContext" type="tns:camelRouteContextFactoryBean">
<xs:annotation>
<xs:documentation xml:lang="en"><![CDATA[
@@ -1329,22 +1345,6 @@ A series of Camel routes
</xs:annotation>
</xs:element>
- <xs:element name="routesConfiguration" type="tns:routesConfigurationDefinition">
- <xs:annotation>
- <xs:documentation xml:lang="en"><![CDATA[
-Global configuration for Camel routes
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
-
- <xs:element name="routesConfigurations" type="tns:routesConfigurationsDefinition">
- <xs:annotation>
- <xs:documentation xml:lang="en"><![CDATA[
-A series of global configuration for Camel routes
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
-
<xs:element name="routingSlip" type="tns:routingSlipDefinition">
<xs:annotation>
<xs:documentation xml:lang="en"><![CDATA[
@@ -10627,6 +10627,29 @@ Reference to the route builder instance.
</xs:complexContent>
</xs:complexType>
+ <xs:complexType name="routeConfigurationDefinition">
+ <xs:complexContent>
+ <xs:extension base="tns:optionalIdentifiedDefinition">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:onException"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:onCompletion"/>
+ <xs:choice maxOccurs="unbounded" minOccurs="0">
+ <xs:element ref="tns:intercept"/>
+ <xs:element ref="tns:interceptFrom"/>
+ </xs:choice>
+ <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:interceptFrom"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:interceptSendToEndpoint"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="routeConfigurationsDefinition">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:routeConfiguration"/>
+ </xs:sequence>
+ </xs:complexType>
+
<xs:complexType name="routeContextRefDefinition">
<xs:sequence/>
<xs:attribute name="ref" type="xs:string" use="required">
@@ -10922,33 +10945,6 @@ Description of the parameter.
</xs:complexContent>
</xs:complexType>
- <xs:complexType name="routesConfigurationDefinition">
- <xs:complexContent>
- <xs:extension base="tns:optionalIdentifiedDefinition">
- <xs:sequence>
- <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:onException"/>
- <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:onCompletion"/>
- <xs:choice maxOccurs="unbounded" minOccurs="0">
- <xs:element ref="tns:intercept"/>
- <xs:element ref="tns:interceptFrom"/>
- </xs:choice>
- <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:interceptFrom"/>
- <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:interceptSendToEndpoint"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:complexType name="routesConfigurationsDefinition">
- <xs:complexContent>
- <xs:extension base="tns:optionalIdentifiedDefinition">
- <xs:sequence>
- <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:routesConfiguration"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
<xs:complexType name="routesDefinition">
<xs:complexContent>
<xs:extension base="tns:optionalIdentifiedDefinition">
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationDefinition.java
index e4b4090..3ffb1f1 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteConfigurationDefinition.java
@@ -135,4 +135,64 @@ public class RouteConfigurationDefinition extends OptionalIdentifiedDefinition<R
return answer;
}
+ /**
+ * <a href="http://camel.apache.org/oncompletion.html">On completion</a> callback for doing custom routing when the
+ * {@link org.apache.camel.Exchange} is complete.
+ *
+ * @return the on completion builder to configure
+ */
+ public OnCompletionDefinition onCompletion() {
+ OnCompletionDefinition answer = new OnCompletionDefinition();
+ // is global scoped by default
+ answer.setRouteScoped(false);
+ onCompletions.add(answer);
+ return answer;
+ }
+
+ /**
+ * Adds a route for an interceptor that intercepts every processing step.
+ *
+ * @return the builder
+ */
+ public InterceptDefinition intercept() {
+ InterceptDefinition answer = new InterceptDefinition();
+ intercepts.add(answer);
+ return answer;
+ }
+
+ /**
+ * Adds a route for an interceptor that intercepts incoming messages on any inputs in this route
+ *
+ * @return the builder
+ */
+ public InterceptFromDefinition interceptFrom() {
+ InterceptFromDefinition answer = new InterceptFromDefinition();
+ interceptFroms.add(answer);
+ return answer;
+ }
+
+ /**
+ * Adds a route for an interceptor that intercepts incoming messages on the given endpoint.
+ *
+ * @param uri endpoint uri
+ * @return the builder
+ */
+ public InterceptFromDefinition interceptFrom(String uri) {
+ InterceptFromDefinition answer = new InterceptFromDefinition(uri);
+ interceptFroms.add(answer);
+ return answer;
+ }
+
+ /**
+ * Applies a route for an interceptor if an exchange is send to the given endpoint
+ *
+ * @param uri endpoint uri
+ * @return the builder
+ */
+ public InterceptSendToEndpointDefinition interceptSendToEndpoint(String uri) {
+ InterceptSendToEndpointDefinition answer = new InterceptSendToEndpointDefinition(uri);
+ interceptSendTos.add(answer);
+ return answer;
+ }
+
}
diff --git a/core/camel-core/src/test/java/org/apache/camel/model/RoutesConfigurationBuilderTest.java b/core/camel-core/src/test/java/org/apache/camel/model/RoutesConfigurationBuilderTest.java
index 38e31b0..5e70d18 100644
--- a/core/camel-core/src/test/java/org/apache/camel/model/RoutesConfigurationBuilderTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/model/RoutesConfigurationBuilderTest.java
@@ -35,7 +35,7 @@ public class RoutesConfigurationBuilderTest extends ContextTestSupport {
}
@Test
- public void testRoutesConfiguration() throws Exception {
+ public void testRoutesConfigurationOnException() throws Exception {
List<RoutesBuilder> routes = new ArrayList<>();
routes.add(new RouteBuilder() {
@@ -84,4 +84,227 @@ public class RoutesConfigurationBuilderTest extends ContextTestSupport {
assertMockEndpointsSatisfied();
}
+ @Test
+ public void testRoutesConfigurationOnCompletion() throws Exception {
+ List<RoutesBuilder> routes = new ArrayList<>();
+
+ routes.add(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .to("mock:result");
+ }
+ });
+ routes.add(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start2")
+ // route scoped that overrides the global scoped
+ .onCompletion().to("mock:done2").end()
+ .to("mock:result");
+ }
+ });
+ routes.add(new RouteConfigurationBuilder() {
+ @Override
+ public void configuration() throws Exception {
+ // global routes configuration
+ routeConfiguration().onCompletion().to("mock:done");
+ }
+ });
+ context.start();
+
+ // sort routes according to ordered
+ routes.sort(OrderedComparator.get());
+
+ // first add the routes configurations as they are globally for all routes
+ for (RoutesBuilder builder : routes) {
+ if (builder instanceof RouteConfigurationsBuilder) {
+ RouteConfigurationsBuilder rcb = (RouteConfigurationsBuilder) builder;
+ context.addRoutesConfigurations(rcb);
+ }
+ }
+ // then add the routes
+ for (RoutesBuilder builder : routes) {
+ context.addRoutes(builder);
+ }
+
+ getMockEndpoint("mock:result").expectedMessageCount(2);
+ getMockEndpoint("mock:done").expectedBodiesReceived("Hello World");
+ getMockEndpoint("mock:done2").expectedBodiesReceived("Bye World");
+
+ template.sendBody("direct:start", "Hello World");
+ template.sendBody("direct:start2", "Bye World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testRoutesConfigurationIntercept() throws Exception {
+ List<RoutesBuilder> routes = new ArrayList<>();
+
+ routes.add(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .setBody(constant("A"))
+ .setBody(constant("B"))
+ .to("mock:result");
+ }
+ });
+ routes.add(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start2")
+ .setBody(constant("C"))
+ .setBody(constant("D"))
+ .to("mock:result");
+ }
+ });
+ routes.add(new RouteConfigurationBuilder() {
+ @Override
+ public void configuration() throws Exception {
+ // global routes configuration
+ routeConfiguration().intercept().to("mock:step");
+ }
+ });
+ context.start();
+
+ // sort routes according to ordered
+ routes.sort(OrderedComparator.get());
+
+ // first add the routes configurations as they are globally for all routes
+ for (RoutesBuilder builder : routes) {
+ if (builder instanceof RouteConfigurationsBuilder) {
+ RouteConfigurationsBuilder rcb = (RouteConfigurationsBuilder) builder;
+ context.addRoutesConfigurations(rcb);
+ }
+ }
+ // then add the routes
+ for (RoutesBuilder builder : routes) {
+ context.addRoutes(builder);
+ }
+
+ getMockEndpoint("mock:result").expectedMessageCount(2);
+ getMockEndpoint("mock:step").expectedBodiesReceived("Hello World", "A", "B", "Bye World", "C", "D");
+
+ template.sendBody("direct:start", "Hello World");
+ template.sendBody("direct:start2", "Bye World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testRoutesConfigurationInterceptFrom() throws Exception {
+ List<RoutesBuilder> routes = new ArrayList<>();
+
+ routes.add(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("seda:start")
+ .setBody(constant("A"))
+ .setBody(constant("B"))
+ .to("mock:result");
+ }
+ });
+ routes.add(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start2")
+ .setBody(constant("C"))
+ .setBody(constant("D"))
+ .to("mock:result");
+ }
+ });
+ routes.add(new RouteConfigurationBuilder() {
+ @Override
+ public void configuration() throws Exception {
+ // global routes configuration
+ routeConfiguration().interceptFrom("direct*").to("mock:step");
+ }
+ });
+ context.start();
+
+ // sort routes according to ordered
+ routes.sort(OrderedComparator.get());
+
+ // first add the routes configurations as they are globally for all routes
+ for (RoutesBuilder builder : routes) {
+ if (builder instanceof RouteConfigurationsBuilder) {
+ RouteConfigurationsBuilder rcb = (RouteConfigurationsBuilder) builder;
+ context.addRoutesConfigurations(rcb);
+ }
+ }
+ // then add the routes
+ for (RoutesBuilder builder : routes) {
+ context.addRoutes(builder);
+ }
+
+ getMockEndpoint("mock:result").expectedMessageCount(2);
+ getMockEndpoint("mock:step").expectedBodiesReceived("Bye World");
+
+ template.sendBody("seda:start", "Hello World");
+ template.sendBody("direct:start2", "Bye World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testRoutesConfigurationInterceptSendTo() throws Exception {
+ List<RoutesBuilder> routes = new ArrayList<>();
+
+ routes.add(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start")
+ .setBody(constant("A"))
+ .to("mock:foo")
+ .setBody(constant("B"))
+ .to("mock:bar")
+ .to("mock:result");
+ }
+ });
+ routes.add(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:start2")
+ .setBody(constant("C"))
+ .to("mock:foo")
+ .setBody(constant("D"))
+ .to("mock:bar")
+ .to("mock:result");
+ }
+ });
+ routes.add(new RouteConfigurationBuilder() {
+ @Override
+ public void configuration() throws Exception {
+ // global routes configuration
+ routeConfiguration().interceptSendToEndpoint("mock:foo").to("mock:step");
+ }
+ });
+ context.start();
+
+ // sort routes according to ordered
+ routes.sort(OrderedComparator.get());
+
+ // first add the routes configurations as they are globally for all routes
+ for (RoutesBuilder builder : routes) {
+ if (builder instanceof RouteConfigurationsBuilder) {
+ RouteConfigurationsBuilder rcb = (RouteConfigurationsBuilder) builder;
+ context.addRoutesConfigurations(rcb);
+ }
+ }
+ // then add the routes
+ for (RoutesBuilder builder : routes) {
+ context.addRoutes(builder);
+ }
+
+ getMockEndpoint("mock:result").expectedMessageCount(2);
+ getMockEndpoint("mock:step").expectedBodiesReceived("A", "C");
+
+ template.sendBody("direct:start", "Hello World");
+ template.sendBody("direct:start2", "Bye World");
+
+ assertMockEndpointsSatisfied();
+ }
+
}