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 2024/03/15 08:21:50 UTC
(camel) branch main updated: CAMEL-20568: Set error handler on route level in YAML DSL (#13489)
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
The following commit(s) were added to refs/heads/main by this push:
new c0228d4f12c CAMEL-20568: Set error handler on route level in YAML DSL (#13489)
c0228d4f12c is described below
commit c0228d4f12c6a34859e69337bd0017a855fe195c
Author: Christoph Deppisch <cd...@redhat.com>
AuthorDate: Fri Mar 15 09:21:43 2024 +0100
CAMEL-20568: Set error handler on route level in YAML DSL (#13489)
Allow to set error handler on route level in Camel YAML DSL
---
.../dsl/yaml/deserializers/CustomResolver.java | 2 +
.../ErrorHandlerBuilderDeserializer.java | 33 ++------
...rializer.java => ErrorHandlerDeserializer.java} | 50 +-----------
.../deserializers/RouteDefinitionDeserializer.java | 9 +++
.../generated/resources/schema/camelYamlDsl.json | 89 +++++++++++++++++++++-
.../org/apache/camel/dsl/yaml/RoutesTest.groovy | 88 ++++++++++++++++++++-
6 files changed, 197 insertions(+), 74 deletions(-)
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/CustomResolver.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/CustomResolver.java
index c0ccc80eac7..ab9415ece5d 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/CustomResolver.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/CustomResolver.java
@@ -87,6 +87,8 @@ public class CustomResolver implements YamlDeserializerResolver {
case "beans":
return beansDeserializer;
case "errorHandler":
+ return new ErrorHandlerDeserializer();
+ case "org.apache.camel.ErrorHandlerFactory":
return new ErrorHandlerBuilderDeserializer();
case "org.apache.camel.model.ProcessorDefinition":
return new ProcessorDefinitionDeserializer();
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerBuilderDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerBuilderDeserializer.java
index 545fc9e300e..daf18aa1d3a 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerBuilderDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerBuilderDeserializer.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.yaml.deserializers;
-import org.apache.camel.CamelContext;
import org.apache.camel.ErrorHandlerFactory;
import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver;
@@ -27,7 +26,6 @@ import org.apache.camel.model.errorhandler.DefaultErrorHandlerDefinition;
import org.apache.camel.model.errorhandler.JtaTransactionErrorHandlerDefinition;
import org.apache.camel.model.errorhandler.NoErrorHandlerDefinition;
import org.apache.camel.model.errorhandler.RefErrorHandlerDefinition;
-import org.apache.camel.spi.CamelContextCustomizer;
import org.apache.camel.spi.annotations.YamlIn;
import org.apache.camel.spi.annotations.YamlProperty;
import org.apache.camel.spi.annotations.YamlType;
@@ -36,16 +34,11 @@ import org.snakeyaml.engine.v2.nodes.MappingNode;
import org.snakeyaml.engine.v2.nodes.Node;
import org.snakeyaml.engine.v2.nodes.NodeTuple;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asMappingNode;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asText;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asType;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.getDeserializationContext;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.setDeserializationContext;
+import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.*;
@YamlIn
@YamlType(
- inline = false,
- nodes = { "error-handler", "errorHandler" },
+ types = ErrorHandlerFactory.class,
order = YamlDeserializerResolver.ORDER_DEFAULT,
properties = {
@YamlProperty(name = "deadLetterChannel",
@@ -69,15 +62,6 @@ import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.setDeseri
})
public class ErrorHandlerBuilderDeserializer implements ConstructNode {
- private static CamelContextCustomizer customizer(ErrorHandlerFactory builder) {
- return new CamelContextCustomizer() {
- @Override
- public void configure(CamelContext camelContext) {
- camelContext.getCamelContextExtension().setErrorHandlerFactory(builder);
- }
- };
- }
-
@Override
public Object construct(Node node) {
final MappingNode bn = asMappingNode(node);
@@ -92,17 +76,16 @@ public class ErrorHandlerBuilderDeserializer implements ConstructNode {
key = org.apache.camel.util.StringHelper.dashToCamelCase(key);
switch (key) {
case "deadLetterChannel":
- return customizer(asType(val, DeadLetterChannelDefinition.class));
+ return asType(val, DeadLetterChannelDefinition.class);
case "defaultErrorHandler":
- return customizer(asType(val, DefaultErrorHandlerDefinition.class));
+ return asType(val, DefaultErrorHandlerDefinition.class);
case "jtaTransactionErrorHandler":
- return customizer(asType(val, JtaTransactionErrorHandlerDefinition.class));
+ case "springTransactionErrorHandler":
+ return asType(val, JtaTransactionErrorHandlerDefinition.class);
case "noErrorHandler":
- return customizer(asType(val, NoErrorHandlerDefinition.class));
+ return asType(val, NoErrorHandlerDefinition.class);
case "refErrorHandler":
- return customizer(asType(val, RefErrorHandlerDefinition.class));
- case "springTransactionErrorHandler":
- return customizer(asType(val, JtaTransactionErrorHandlerDefinition.class));
+ return asType(val, RefErrorHandlerDefinition.class);
default:
throw new UnsupportedFieldException(val, key);
}
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerBuilderDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerDeserializer.java
similarity index 55%
copy from dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerBuilderDeserializer.java
copy to dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerDeserializer.java
index 545fc9e300e..d9a89cd5f5f 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerBuilderDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerDeserializer.java
@@ -18,29 +18,13 @@ package org.apache.camel.dsl.yaml.deserializers;
import org.apache.camel.CamelContext;
import org.apache.camel.ErrorHandlerFactory;
-import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver;
-import org.apache.camel.dsl.yaml.common.exception.UnsupportedFieldException;
-import org.apache.camel.dsl.yaml.common.exception.YamlDeserializationException;
-import org.apache.camel.model.errorhandler.DeadLetterChannelDefinition;
-import org.apache.camel.model.errorhandler.DefaultErrorHandlerDefinition;
-import org.apache.camel.model.errorhandler.JtaTransactionErrorHandlerDefinition;
-import org.apache.camel.model.errorhandler.NoErrorHandlerDefinition;
-import org.apache.camel.model.errorhandler.RefErrorHandlerDefinition;
import org.apache.camel.spi.CamelContextCustomizer;
import org.apache.camel.spi.annotations.YamlIn;
import org.apache.camel.spi.annotations.YamlProperty;
import org.apache.camel.spi.annotations.YamlType;
import org.snakeyaml.engine.v2.api.ConstructNode;
-import org.snakeyaml.engine.v2.nodes.MappingNode;
import org.snakeyaml.engine.v2.nodes.Node;
-import org.snakeyaml.engine.v2.nodes.NodeTuple;
-
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asMappingNode;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asText;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asType;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.getDeserializationContext;
-import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.setDeserializationContext;
@YamlIn
@YamlType(
@@ -67,7 +51,9 @@ import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.setDeseri
type = "object:org.apache.camel.model.errorhandler.SpringTransactionErrorHandlerDefinition",
oneOf = "errorHandler"),
})
-public class ErrorHandlerBuilderDeserializer implements ConstructNode {
+public class ErrorHandlerDeserializer implements ConstructNode {
+
+ private final ErrorHandlerBuilderDeserializer delegate = new ErrorHandlerBuilderDeserializer();
private static CamelContextCustomizer customizer(ErrorHandlerFactory builder) {
return new CamelContextCustomizer() {
@@ -80,34 +66,6 @@ public class ErrorHandlerBuilderDeserializer implements ConstructNode {
@Override
public Object construct(Node node) {
- final MappingNode bn = asMappingNode(node);
- final YamlDeserializationContext dc = getDeserializationContext(node);
-
- for (NodeTuple tuple : bn.getValue()) {
- String key = asText(tuple.getKeyNode());
- Node val = tuple.getValueNode();
-
- setDeserializationContext(val, dc);
-
- key = org.apache.camel.util.StringHelper.dashToCamelCase(key);
- switch (key) {
- case "deadLetterChannel":
- return customizer(asType(val, DeadLetterChannelDefinition.class));
- case "defaultErrorHandler":
- return customizer(asType(val, DefaultErrorHandlerDefinition.class));
- case "jtaTransactionErrorHandler":
- return customizer(asType(val, JtaTransactionErrorHandlerDefinition.class));
- case "noErrorHandler":
- return customizer(asType(val, NoErrorHandlerDefinition.class));
- case "refErrorHandler":
- return customizer(asType(val, RefErrorHandlerDefinition.class));
- case "springTransactionErrorHandler":
- return customizer(asType(val, JtaTransactionErrorHandlerDefinition.class));
- default:
- throw new UnsupportedFieldException(val, key);
- }
- }
-
- throw new YamlDeserializationException(node, "Unable to determine the error handler type for the node");
+ return customizer((ErrorHandlerFactory) delegate.construct(node));
}
}
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteDefinitionDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteDefinitionDeserializer.java
index eed0d6a2e08..413065acf39 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteDefinitionDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteDefinitionDeserializer.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.dsl.yaml.deserializers;
+import org.apache.camel.ErrorHandlerFactory;
import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
import org.apache.camel.dsl.yaml.common.YamlDeserializerBase;
import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver;
@@ -50,6 +51,8 @@ import org.snakeyaml.engine.v2.nodes.NodeTuple;
@YamlProperty(name = "messageHistory", type = "boolean"),
@YamlProperty(name = "logMask", type = "boolean"),
@YamlProperty(name = "trace", type = "boolean"),
+ @YamlProperty(name = "errorHandlerRef", type = "string"),
+ @YamlProperty(name = "errorHandler", type = "object:org.apache.camel.ErrorHandlerFactory"),
@YamlProperty(name = "shutdownRoute", type = "enum:Default,Defer",
defaultValue = "Default",
description = "To control how to shut down the route."),
@@ -128,6 +131,12 @@ public class RouteDefinitionDeserializer extends YamlDeserializerBase<RouteDefin
case "trace":
target.setTrace(asText(val));
break;
+ case "errorHandlerRef":
+ target.setErrorHandlerRef(asText(val));
+ break;
+ case "errorHandler":
+ target.setErrorHandlerFactory(asType(val, ErrorHandlerFactory.class));
+ break;
case "inputType":
target.setInputType(asType(val, InputTypeDefinition.class));
break;
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index ed68cdb8278..7f5cb528931 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -207,6 +207,85 @@
}
}
},
+ "org.apache.camel.ErrorHandlerFactory" : {
+ "type" : "object",
+ "additionalProperties" : false,
+ "anyOf" : [ {
+ "oneOf" : [ {
+ "type" : "object",
+ "required" : [ "deadLetterChannel" ],
+ "properties" : {
+ "deadLetterChannel" : {
+ "$ref" : "#/items/definitions/org.apache.camel.model.errorhandler.DeadLetterChannelDefinition"
+ }
+ }
+ }, {
+ "not" : {
+ "anyOf" : [ {
+ "required" : [ "deadLetterChannel" ]
+ }, {
+ "required" : [ "defaultErrorHandler" ]
+ }, {
+ "required" : [ "jtaTransactionErrorHandler" ]
+ }, {
+ "required" : [ "noErrorHandler" ]
+ }, {
+ "required" : [ "refErrorHandler" ]
+ }, {
+ "required" : [ "springTransactionErrorHandler" ]
+ } ]
+ }
+ }, {
+ "type" : "object",
+ "required" : [ "defaultErrorHandler" ],
+ "properties" : {
+ "defaultErrorHandler" : {
+ "$ref" : "#/items/definitions/org.apache.camel.model.errorhandler.DefaultErrorHandlerDefinition"
+ }
+ }
+ }, {
+ "type" : "object",
+ "required" : [ "jtaTransactionErrorHandler" ],
+ "properties" : {
+ "jtaTransactionErrorHandler" : {
+ "$ref" : "#/items/definitions/org.apache.camel.model.errorhandler.JtaTransactionErrorHandlerDefinition"
+ }
+ }
+ }, {
+ "type" : "object",
+ "required" : [ "noErrorHandler" ],
+ "properties" : {
+ "noErrorHandler" : {
+ "$ref" : "#/items/definitions/org.apache.camel.model.errorhandler.NoErrorHandlerDefinition"
+ }
+ }
+ }, {
+ "type" : "object",
+ "required" : [ "refErrorHandler" ],
+ "properties" : {
+ "refErrorHandler" : {
+ "$ref" : "#/items/definitions/org.apache.camel.model.errorhandler.RefErrorHandlerDefinition"
+ }
+ }
+ }, {
+ "type" : "object",
+ "required" : [ "springTransactionErrorHandler" ],
+ "properties" : {
+ "springTransactionErrorHandler" : {
+ "$ref" : "#/items/definitions/org.apache.camel.model.errorhandler.SpringTransactionErrorHandlerDefinition"
+ }
+ }
+ } ]
+ } ],
+ "properties" : {
+ "deadLetterChannel" : { },
+ "defaultErrorHandler" : { },
+ "jtaTransactionErrorHandler" : { },
+ "noErrorHandler" : { },
+ "refErrorHandler" : { },
+ "springTransactionErrorHandler" : { }
+ }
+ },
"org.apache.camel.dsl.yaml.deserializers.BeansDeserializer" : {
"type" : "array",
"additionalProperties" : false,
@@ -214,7 +293,7 @@
"$ref" : "#/items/definitions/org.apache.camel.model.app.RegistryBeanDefinition"
}
},
- "org.apache.camel.dsl.yaml.deserializers.ErrorHandlerBuilderDeserializer" : {
+ "org.apache.camel.dsl.yaml.deserializers.ErrorHandlerDeserializer" : {
"type" : "object",
"additionalProperties" : false,
"anyOf" : [ {
@@ -5094,6 +5173,12 @@
"description" : {
"type" : "string"
},
+ "errorHandler" : {
+ "$ref" : "#/items/definitions/org.apache.camel.ErrorHandlerFactory"
+ },
+ "errorHandlerRef" : {
+ "type" : "string"
+ },
"from" : {
"$ref" : "#/items/definitions/org.apache.camel.model.FromDefinition"
},
@@ -16206,7 +16291,7 @@
"$ref" : "#/items/definitions/org.apache.camel.dsl.yaml.deserializers.BeansDeserializer"
},
"errorHandler" : {
- "$ref" : "#/items/definitions/org.apache.camel.dsl.yaml.deserializers.ErrorHandlerBuilderDeserializer"
+ "$ref" : "#/items/definitions/org.apache.camel.dsl.yaml.deserializers.ErrorHandlerDeserializer"
},
"from" : {
"$ref" : "#/items/definitions/org.apache.camel.dsl.yaml.deserializers.RouteFromDefinitionDeserializer"
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RoutesTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RoutesTest.groovy
index 4e4a2e5b4c6..ee19ea61da6 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RoutesTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RoutesTest.groovy
@@ -19,6 +19,8 @@ package org.apache.camel.dsl.yaml
import org.apache.camel.dsl.yaml.support.YamlTestSupport
import org.apache.camel.model.LogDefinition
import org.apache.camel.model.RouteDefinition
+import org.apache.camel.model.errorhandler.DeadLetterChannelDefinition
+import org.apache.camel.model.errorhandler.RefErrorHandlerDefinition
import org.junit.jupiter.api.Assertions
class RoutesTest extends YamlTestSupport {
@@ -164,6 +166,91 @@ class RoutesTest extends YamlTestSupport {
}
}
+ def "load route with error handler ref"() {
+ when:
+ loadRoutes '''
+ - route:
+ errorHandlerRef: "myErrorHandler"
+ from:
+ uri: "direct:info"
+ steps:
+ - log: "message"
+ '''
+ then:
+ context.routeDefinitions.size() == 1
+
+ with(context.routeDefinitions[0], RouteDefinition) {
+ input.endpointUri == 'direct:info'
+ with (outputs[0], LogDefinition) {
+ message == 'message'
+ }
+ errorHandlerFactorySet
+ errorHandlerFactory.class == RefErrorHandlerDefinition.class
+ with (errorHandlerFactory, RefErrorHandlerDefinition) {
+ ref == "myErrorHandler"
+ }
+ }
+ }
+
+ def "load route with error handler"() {
+ when:
+ loadRoutes '''
+ - route:
+ errorHandler:
+ refErrorHandler:
+ ref: "myErrorHandler"
+ from:
+ uri: "direct:info"
+ steps:
+ - log: "message"
+ '''
+ then:
+ context.routeDefinitions.size() == 1
+
+ with(context.routeDefinitions[0], RouteDefinition) {
+ input.endpointUri == 'direct:info'
+ with (outputs[0], LogDefinition) {
+ message == 'message'
+ }
+ errorHandlerFactorySet
+ errorHandlerFactory.class == RefErrorHandlerDefinition.class
+ with (errorHandlerFactory, RefErrorHandlerDefinition) {
+ ref == "myErrorHandler"
+ }
+ }
+ }
+
+ def "load route with error handler properties"() {
+ when:
+ loadRoutes '''
+ - route:
+ errorHandler:
+ deadLetterChannel:
+ deadLetterUri: "mock:on-error"
+ redeliveryPolicy:
+ maximumRedeliveries: 3
+ from:
+ uri: "direct:info"
+ steps:
+ - log: "message"
+ '''
+ then:
+ context.routeDefinitions.size() == 1
+
+ with(context.routeDefinitions[0], RouteDefinition) {
+ input.endpointUri == 'direct:info'
+ with (outputs[0], LogDefinition) {
+ message == 'message'
+ }
+ errorHandlerFactorySet
+ errorHandlerFactory.class == DeadLetterChannelDefinition.class
+ with (errorHandlerFactory, DeadLetterChannelDefinition) {
+ deadLetterUri == 'mock:on-error'
+ redeliveryPolicy.maximumRedeliveries == "3"
+ }
+ }
+ }
+
def "load route with input/output types"() {
when:
loadRoutes '''
@@ -191,7 +278,6 @@ class RoutesTest extends YamlTestSupport {
}
}
-
def "load route inlined camelCase"() {
when:
loadRoutes '''