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 2022/04/05 11:14:52 UTC
[camel] 01/07: CAMEL-16834: error handler in model DSL. WIP
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch errorhandler-in-dsl
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 5db79fcdef2dab7560346fa4fe2e988c466de2ae
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Mar 9 15:49:27 2022 +0100
CAMEL-16834: error handler in model DSL. WIP
---
.../xml/CamelRedeliveryPolicyFactoryBean.java | 1 +
.../camel/spring/xml/ErrorHandlerDefinition.java | 1 +
.../apache/camel/spring/xml/ErrorHandlerType.java | 1 +
.../java/org/apache/camel/ErrorHandlerFactory.java | 1 +
.../camel/impl/engine/AbstractCamelContext.java | 1 +
.../org/apache/camel/impl/engine/DefaultRoute.java | 1 +
.../services/org/apache/camel/model.properties | 7 +
.../org/apache/camel/model/errorHandler.json | 18 ++
.../camel/model/errorhandler/baseErrorHandler.json | 16 ++
.../model/errorhandler/deadLetterChannel.json | 32 ++++
.../model/errorhandler/defaultErrorHandler.json | 30 +++
.../camel/model/errorhandler/errorHandler.json | 34 ++++
.../org/apache/camel/model/errorhandler/jaxb.index | 6 +
.../camel/model/errorhandler/noErrorHandler.json | 17 ++
.../errorhandler/transactionErrorHandler.json | 32 ++++
.../resources/org/apache/camel/model/jaxb.index | 1 +
.../apache/camel/builder/ErrorHandlerBuilder.java | 1 +
.../apache/camel/model/ErrorHandlerDefinition.java | 65 +++++++
.../org/apache/camel/model/RouteDefinition.java | 15 ++
.../camel/model/RouteTemplatesDefinition.java | 1 +
.../org/apache/camel/model/RoutesDefinition.java | 1 +
.../errorhandler/BaseErrorHandlerDefinition.java} | 18 +-
.../errorhandler/DeadLetterChannelDefinition.java | 108 +++++++++++
.../DefaultErrorHandlerDefinition.java | 201 ++++++++++++---------
.../errorhandler/NoErrorHandlerDefinition.java} | 15 +-
.../TransactionErrorHandlerDefinition.java | 65 +++++++
.../org/apache/camel/reifier/RouteReifier.java | 14 +-
.../reifier/errorhandler/ErrorHandlerReifier.java | 132 +++++++++++++-
.../errorhandler/NewDeadLetterChannelReifier.java | 142 +++++++++++++++
.../errorhandler/NewDeadLetterChannelTest.java | 50 +++++
.../java/org/apache/camel/xml/in/ModelParser.java | 75 ++++++++
31 files changed, 997 insertions(+), 105 deletions(-)
diff --git a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelRedeliveryPolicyFactoryBean.java b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelRedeliveryPolicyFactoryBean.java
index b4bb6ef03de..a671f303f74 100644
--- a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelRedeliveryPolicyFactoryBean.java
+++ b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelRedeliveryPolicyFactoryBean.java
@@ -36,6 +36,7 @@ import org.springframework.context.ApplicationContextAware;
@Metadata(label = "spring,configuration")
@XmlRootElement(name = "redeliveryPolicyProfile")
@XmlAccessorType(XmlAccessType.FIELD)
+@Deprecated
public class CamelRedeliveryPolicyFactoryBean extends AbstractCamelRedeliveryPolicyFactoryBean
implements FactoryBean<RedeliveryPolicy>, ApplicationContextAware {
diff --git a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerDefinition.java b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerDefinition.java
index 1d1141a4a5f..4e914856cdb 100644
--- a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerDefinition.java
+++ b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerDefinition.java
@@ -33,6 +33,7 @@ import org.apache.camel.spi.Metadata;
@Metadata(label = "spring,configuration,error")
@XmlRootElement(name = "errorHandler")
@XmlAccessorType(XmlAccessType.FIELD)
+@Deprecated
public class ErrorHandlerDefinition extends IdentifiedType {
@XmlAttribute
@Metadata(defaultValue = "DefaultErrorHandler", required = true)
diff --git a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerType.java b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerType.java
index d0824755c99..0583efb04e7 100644
--- a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerType.java
+++ b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerType.java
@@ -31,6 +31,7 @@ import org.apache.camel.spring.spi.TransactionErrorHandlerBuilder;
@Metadata(label = "spring,configuration,error")
@XmlType
@XmlEnum
+@Deprecated
public enum ErrorHandlerType {
DefaultErrorHandler,
diff --git a/core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java b/core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java
index 9941a6ae1c4..4a881b143c0 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java
@@ -19,6 +19,7 @@ package org.apache.camel;
/**
* Factory for creating {@link org.apache.camel.spi.ErrorHandler}s.
*/
+@Deprecated
public interface ErrorHandlerFactory {
}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 2dbd8980ada..52f177d9f3b 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -282,6 +282,7 @@ public abstract class AbstractCamelContext extends BaseService
private String basePackageScan;
private boolean lightweight;
private Long delay;
+ @Deprecated
private ErrorHandlerFactory errorHandlerFactory;
private Map<String, String> globalOptions = new HashMap<>();
private volatile String version;
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
index c1021759700..5c39c860bea 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
@@ -92,6 +92,7 @@ public class DefaultRoute extends ServiceSupport implements Route {
private ResumeStrategy resumeStrategy;
// camel-core-model
+ @Deprecated
private ErrorHandlerFactory errorHandlerFactory;
// camel-core-model: must be concurrent as error handlers can be mutated concurrently via multicast/recipientlist EIPs
private final ConcurrentMap<ErrorHandlerFactory, Set<NamedNode>> errorHandlers = new ConcurrentHashMap<>();
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 812a9610d11..3108d901eba 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
@@ -6,6 +6,7 @@ asn1
avro
barcode
base64
+baseErrorHandler
basicAuth
batch-config
bean
@@ -32,6 +33,8 @@ customLoadBalancer
customServiceFilter
dataFormats
datasonnet
+deadLetterChannel
+defaultErrorHandler
defaultLoadBalancer
delay
delete
@@ -42,6 +45,8 @@ doFinally
doTry
dynamicRouter
enrich
+errorHandler
+errorHandler
etcdServiceDiscovery
exchangeProperty
expression
@@ -92,6 +97,7 @@ mimeMultipart
multicast
mutualTLS
mvel
+noErrorHandler
oauth2
ognl
onCompletion
@@ -194,6 +200,7 @@ toD
tokenize
topic
transacted
+transactionErrorHandler
transform
transformers
typeFilter
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorHandler.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorHandler.json
new file mode 100644
index 00000000000..a5a05e25162
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorHandler.json
@@ -0,0 +1,18 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "errorHandler",
+ "title": "Error Handler",
+ "description": "Base class for error handler definitions.",
+ "deprecated": false,
+ "label": "configuration,error",
+ "javaType": "org.apache.camel.model.ErrorHandlerDefinition",
+ "abstract": false,
+ "input": false,
+ "output": false
+ },
+ "properties": {
+ "errorHandlerType": { "kind": "element", "displayName": "Error Handler Type", "required": true, "type": "object", "javaType": "org.apache.camel.model.errorhandler.BaseErrorHandlerDefinition", "oneOf": [ "deadLetterChannel", "defaultErrorHandler", "noErrorHandler", "transactionErrorHandler" ], "deprecated": false, "autowired": false, "secret": false },
+ "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }
+ }
+}
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/baseErrorHandler.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/baseErrorHandler.json
new file mode 100644
index 00000000000..45f57db5400
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/baseErrorHandler.json
@@ -0,0 +1,16 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "baseErrorHandler",
+ "title": "Base Error Handler",
+ "deprecated": false,
+ "label": "configuration,error",
+ "javaType": "org.apache.camel.model.errorhandler.BaseErrorHandlerDefinition",
+ "abstract": false,
+ "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": "The id of this node" }
+ }
+}
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/deadLetterChannel.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/deadLetterChannel.json
new file mode 100644
index 00000000000..276e0f1e050
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/deadLetterChannel.json
@@ -0,0 +1,32 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "deadLetterChannel",
+ "title": "Dead Letter Channel",
+ "description": "Dead letter channel error handler.",
+ "deprecated": false,
+ "label": "configuration,error",
+ "javaType": "org.apache.camel.model.errorhandler.DeadLetterChannelDefinition",
+ "abstract": false,
+ "input": false,
+ "output": false
+ },
+ "properties": {
+ "deadLetterUri": { "kind": "attribute", "displayName": "Dead Letter Uri", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The dead letter endpoint uri for the Dead Letter error handler." },
+ "deadLetterHandleNewException": { "kind": "attribute", "displayName": "Dead Letter Handle New Exception", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "true", "description": "Whether the dead letter channel should handle (and ignore) any new exception that may been thrown during sending the message to the dead letter endpoint. The default value is true which means any such kind of except [...]
+ "loggerRef": { "kind": "attribute", "displayName": "Logger Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "References to a logger to use as logger for the error handler" },
+ "level": { "kind": "attribute", "displayName": "Level", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "debug", "error", "info", "off", "trace", "warn" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "ERROR", "description": "Logging level to use when using the logging error handler type." },
+ "rollbackLoggingLevel": { "kind": "attribute", "displayName": "Rollback Logging Level", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "debug", "error", "info", "off", "trace", "warn" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "WARN", "description": "Sets the logging level to use for logging transactional rollback. This option is default WARN." },
+ "logName": { "kind": "attribute", "displayName": "Log Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of the logger to use for the logging error handler" },
+ "useOriginalMessage": { "kind": "attribute", "displayName": "Use Original Message", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message (original body and headers) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have failed and the org.apache [...]
+ "useOriginalBody": { "kind": "attribute", "displayName": "Use Original Body", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message body (original body only) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have failed and the org.apache.camel.E [...]
+ "onRedeliveryRef": { "kind": "attribute", "displayName": "On Redelivery Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed before a redelivery attempt. Can be used to change the org.apache.camel.Exchange before its being redelivered." },
+ "onExceptionOccurredRef": { "kind": "attribute", "displayName": "On Exception Occurred Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed just after an exception occurred. Can be used to perform custom logging about the occurred exception at the exact time it happened. Important: Any exception thrown from this processor will be ign [...]
+ "onPrepareFailureRef": { "kind": "attribute", "displayName": "On Prepare Failure Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor to prepare the org.apache.camel.Exchange before handled by the failure processor \/ dead letter channel. This allows for example to enrich the message before sending to a dead letter queue." },
+ "retryWhileRef": { "kind": "attribute", "displayName": "Retry While Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a retry while predicate. Will continue retrying until the predicate evaluates to false." },
+ "redeliveryPolicyRef": { "kind": "attribute", "displayName": "Redelivery Policy Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a RedeliveryPolicy to be used for redelivery settings." },
+ "executorServiceRef": { "kind": "attribute", "displayName": "Executor Service Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a thread pool to be used by the error handler" },
+ "redeliveryPolicy": { "kind": "element", "displayName": "Redelivery Policy", "required": false, "type": "object", "javaType": "org.apache.camel.model.RedeliveryPolicyDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the redelivery settings" },
+ "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }
+ }
+}
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/defaultErrorHandler.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/defaultErrorHandler.json
new file mode 100644
index 00000000000..b005124e34d
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/defaultErrorHandler.json
@@ -0,0 +1,30 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "defaultErrorHandler",
+ "title": "Default Error Handler",
+ "description": "Default error handler.",
+ "deprecated": false,
+ "label": "configuration,error",
+ "javaType": "org.apache.camel.model.errorhandler.DefaultErrorHandlerDefinition",
+ "abstract": false,
+ "input": false,
+ "output": false
+ },
+ "properties": {
+ "loggerRef": { "kind": "attribute", "displayName": "Logger Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "References to a logger to use as logger for the error handler" },
+ "level": { "kind": "attribute", "displayName": "Level", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "debug", "error", "info", "off", "trace", "warn" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "ERROR", "description": "Logging level to use when using the logging error handler type." },
+ "rollbackLoggingLevel": { "kind": "attribute", "displayName": "Rollback Logging Level", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "debug", "error", "info", "off", "trace", "warn" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "WARN", "description": "Sets the logging level to use for logging transactional rollback. This option is default WARN." },
+ "logName": { "kind": "attribute", "displayName": "Log Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of the logger to use for the logging error handler" },
+ "useOriginalMessage": { "kind": "attribute", "displayName": "Use Original Message", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message (original body and headers) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have failed and the org.apache [...]
+ "useOriginalBody": { "kind": "attribute", "displayName": "Use Original Body", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message body (original body only) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have failed and the org.apache.camel.E [...]
+ "onRedeliveryRef": { "kind": "attribute", "displayName": "On Redelivery Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed before a redelivery attempt. Can be used to change the org.apache.camel.Exchange before its being redelivered." },
+ "onExceptionOccurredRef": { "kind": "attribute", "displayName": "On Exception Occurred Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed just after an exception occurred. Can be used to perform custom logging about the occurred exception at the exact time it happened. Important: Any exception thrown from this processor will be ign [...]
+ "onPrepareFailureRef": { "kind": "attribute", "displayName": "On Prepare Failure Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor to prepare the org.apache.camel.Exchange before handled by the failure processor \/ dead letter channel. This allows for example to enrich the message before sending to a dead letter queue." },
+ "retryWhileRef": { "kind": "attribute", "displayName": "Retry While Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a retry while predicate. Will continue retrying until the predicate evaluates to false." },
+ "redeliveryPolicyRef": { "kind": "attribute", "displayName": "Redelivery Policy Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a RedeliveryPolicy to be used for redelivery settings." },
+ "executorServiceRef": { "kind": "attribute", "displayName": "Executor Service Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a thread pool to be used by the error handler" },
+ "redeliveryPolicy": { "kind": "element", "displayName": "Redelivery Policy", "required": false, "type": "object", "javaType": "org.apache.camel.model.RedeliveryPolicyDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the redelivery settings" },
+ "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }
+ }
+}
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/errorHandler.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/errorHandler.json
new file mode 100644
index 00000000000..599cbcdf899
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/errorHandler.json
@@ -0,0 +1,34 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "errorHandler",
+ "title": "Error Handler",
+ "description": "Error handler settings",
+ "deprecated": false,
+ "label": "configuration,error",
+ "javaType": "org.apache.camel.model.errorhandler.ErrorHandlerDefinition",
+ "abstract": false,
+ "input": false,
+ "output": false
+ },
+ "properties": {
+ "type": { "kind": "attribute", "displayName": "Type", "required": true, "type": "enum", "javaType": "org.apache.camel.model.errorhandler.ErrorHandlerType", "enum": [ "dead-letter-channel", "default-error-handler", "no-error-handler", "transaction-error-handler" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "DefaultErrorHandler", "description": "The type of the error handler" },
+ "deadLetterUri": { "kind": "attribute", "displayName": "Dead Letter Uri", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The dead letter endpoint uri for the Dead Letter error handler." },
+ "deadLetterHandleNewException": { "kind": "attribute", "displayName": "Dead Letter Handle New Exception", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Whether the dead letter channel should handle (and ignore) any new exception that may been thrown during sending the message to the dead letter endpoint. The default value is true which means any such kind of exception is handled and ignor [...]
+ "level": { "kind": "attribute", "displayName": "Level", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "debug", "error", "info", "off", "trace", "warn" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "ERROR", "description": "Logging level to use when using the logging error handler type." },
+ "rollbackLoggingLevel": { "kind": "attribute", "displayName": "Rollback Logging Level", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "debug", "error", "info", "off", "trace", "warn" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "WARN", "description": "Sets the logging level to use for logging transactional rollback. This option is default WARN." },
+ "logName": { "kind": "attribute", "displayName": "Log Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of the logger to use for the logging error handler" },
+ "useOriginalMessage": { "kind": "attribute", "displayName": "Use Original Message", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message (original body and headers) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have failed and the org.apache [...]
+ "useOriginalBody": { "kind": "attribute", "displayName": "Use Original Body", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message body (original body only) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have failed and the org.apache.camel.E [...]
+ "transactionTemplateRef": { "kind": "attribute", "displayName": "Transaction Template Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "References to the org.springframework.transaction.support.TransactionTemplate to use with the transaction error handler." },
+ "transactionManagerRef": { "kind": "attribute", "displayName": "Transaction Manager Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "References to the org.springframework.transaction.PlatformTransactionManager to use with the transaction error handler." },
+ "onRedeliveryRef": { "kind": "attribute", "displayName": "On Redelivery Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed before a redelivery attempt. Can be used to change the org.apache.camel.Exchange before its being redelivered." },
+ "onExceptionOccurredRef": { "kind": "attribute", "displayName": "On Exception Occurred Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed just after an exception occurred. Can be used to perform custom logging about the occurred exception at the exact time it happened. Important: Any exception thrown from this processor will be ign [...]
+ "onPrepareFailureRef": { "kind": "attribute", "displayName": "On Prepare Failure Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor to prepare the org.apache.camel.Exchange before handled by the failure processor \/ dead letter channel. This allows for example to enrich the message before sending to a dead letter queue." },
+ "retryWhileRef": { "kind": "attribute", "displayName": "Retry While Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to an retry while expression. Will continue retrying until expression evaluates to false." },
+ "redeliveryPolicyRef": { "kind": "attribute", "displayName": "Redelivery Policy Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a RedeliveryPolicy to be used for redelivery settings." },
+ "executorServiceRef": { "kind": "attribute", "displayName": "Executor Service Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a thread pool to be used by the error handler" },
+ "redeliveryPolicy": { "kind": "element", "displayName": "Redelivery Policy", "required": false, "type": "object", "javaType": "org.apache.camel.model.RedeliveryPolicyDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the redelivery settings" },
+ "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }
+ }
+}
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/jaxb.index b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/jaxb.index
new file mode 100644
index 00000000000..cc2c531fd69
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/jaxb.index
@@ -0,0 +1,6 @@
+# Generated by camel build tools - do NOT edit this file!
+BaseErrorHandlerDefinition
+DeadLetterChannelDefinition
+DefaultErrorHandlerDefinition
+NoErrorHandlerDefinition
+TransactionErrorHandlerDefinition
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/noErrorHandler.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/noErrorHandler.json
new file mode 100644
index 00000000000..f0e1feaaa4f
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/noErrorHandler.json
@@ -0,0 +1,17 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "noErrorHandler",
+ "title": "No Error Handler",
+ "description": "No error handler.",
+ "deprecated": false,
+ "label": "configuration,error",
+ "javaType": "org.apache.camel.model.errorhandler.NoErrorHandlerDefinition",
+ "abstract": false,
+ "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": "The id of this node" }
+ }
+}
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/transactionErrorHandler.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/transactionErrorHandler.json
new file mode 100644
index 00000000000..5ead1d35c39
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/errorhandler/transactionErrorHandler.json
@@ -0,0 +1,32 @@
+{
+ "model": {
+ "kind": "model",
+ "name": "transactionErrorHandler",
+ "title": "Transaction Error Handler",
+ "description": "Transactional error handler.",
+ "deprecated": false,
+ "label": "configuration,error",
+ "javaType": "org.apache.camel.model.errorhandler.TransactionErrorHandlerDefinition",
+ "abstract": false,
+ "input": false,
+ "output": false
+ },
+ "properties": {
+ "transactionTemplateRef": { "kind": "attribute", "displayName": "Transaction Template Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "References to the spring transaction template to use." },
+ "transactionManagerRef": { "kind": "attribute", "displayName": "Transaction Manager Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "References to the spring platform transaction manager to use." },
+ "loggerRef": { "kind": "attribute", "displayName": "Logger Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "References to a logger to use as logger for the error handler" },
+ "level": { "kind": "attribute", "displayName": "Level", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "debug", "error", "info", "off", "trace", "warn" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "ERROR", "description": "Logging level to use when using the logging error handler type." },
+ "rollbackLoggingLevel": { "kind": "attribute", "displayName": "Rollback Logging Level", "required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "debug", "error", "info", "off", "trace", "warn" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "WARN", "description": "Sets the logging level to use for logging transactional rollback. This option is default WARN." },
+ "logName": { "kind": "attribute", "displayName": "Log Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of the logger to use for the logging error handler" },
+ "useOriginalMessage": { "kind": "attribute", "displayName": "Use Original Message", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message (original body and headers) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have failed and the org.apache [...]
+ "useOriginalBody": { "kind": "attribute", "displayName": "Use Original Body", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Will use the original input org.apache.camel.Message body (original body only) when an org.apache.camel.Exchange is moved to the dead letter queue. Notice: this only applies when all redeliveries attempt have failed and the org.apache.camel.E [...]
+ "onRedeliveryRef": { "kind": "attribute", "displayName": "On Redelivery Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed before a redelivery attempt. Can be used to change the org.apache.camel.Exchange before its being redelivered." },
+ "onExceptionOccurredRef": { "kind": "attribute", "displayName": "On Exception Occurred Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor that should be processed just after an exception occurred. Can be used to perform custom logging about the occurred exception at the exact time it happened. Important: Any exception thrown from this processor will be ign [...]
+ "onPrepareFailureRef": { "kind": "attribute", "displayName": "On Prepare Failure Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a processor to prepare the org.apache.camel.Exchange before handled by the failure processor \/ dead letter channel. This allows for example to enrich the message before sending to a dead letter queue." },
+ "retryWhileRef": { "kind": "attribute", "displayName": "Retry While Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a retry while predicate. Will continue retrying until the predicate evaluates to false." },
+ "redeliveryPolicyRef": { "kind": "attribute", "displayName": "Redelivery Policy Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a RedeliveryPolicy to be used for redelivery settings." },
+ "executorServiceRef": { "kind": "attribute", "displayName": "Executor Service Ref", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a reference to a thread pool to be used by the error handler" },
+ "redeliveryPolicy": { "kind": "element", "displayName": "Redelivery Policy", "required": false, "type": "object", "javaType": "org.apache.camel.model.RedeliveryPolicyDefinition", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the redelivery settings" },
+ "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }
+ }
+}
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 592cf1a32fc..d88d8e1d458 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
@@ -13,6 +13,7 @@ DelayDefinition
DescriptionDefinition
DynamicRouterDefinition
EnrichDefinition
+ErrorHandlerDefinition
ExpressionSubElementDefinition
FaultToleranceConfigurationDefinition
FilterDefinition
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/ErrorHandlerBuilder.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/ErrorHandlerBuilder.java
index 5e9fbb749f9..0e41e6d9317 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/builder/ErrorHandlerBuilder.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/ErrorHandlerBuilder.java
@@ -21,6 +21,7 @@ import org.apache.camel.ErrorHandlerFactory;
/**
* A builder of a <a href="http://camel.apache.org/error-handler.html">Error Handler</a>
*/
+@Deprecated
public interface ErrorHandlerBuilder extends ErrorHandlerFactory {
/**
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ErrorHandlerDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ErrorHandlerDefinition.java
new file mode 100644
index 00000000000..473f2e08078
--- /dev/null
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ErrorHandlerDefinition.java
@@ -0,0 +1,65 @@
+/*
+ * 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 javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.model.errorhandler.BaseErrorHandlerDefinition;
+import org.apache.camel.model.errorhandler.DeadLetterChannelDefinition;
+import org.apache.camel.model.errorhandler.DefaultErrorHandlerDefinition;
+import org.apache.camel.model.errorhandler.NoErrorHandlerDefinition;
+import org.apache.camel.model.errorhandler.TransactionErrorHandlerDefinition;
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Base class for error handler definitions.
+ */
+@Metadata(label = "configuration,error")
+@XmlRootElement(name = "errorHandler")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ErrorHandlerDefinition extends IdentifiedType implements ErrorHandlerFactory {
+
+ @XmlElements({
+ @XmlElement(name = "defaultErrorHandler", type = DefaultErrorHandlerDefinition.class),
+ @XmlElement(name = "deadLetterChannel", type = DeadLetterChannelDefinition.class),
+ @XmlElement(name = "noErrorHandler", type = NoErrorHandlerDefinition.class),
+ @XmlElement(name = "transactionErrorHandler", type = TransactionErrorHandlerDefinition.class) })
+ private BaseErrorHandlerDefinition errorHandlerType;
+
+ public BaseErrorHandlerDefinition getErrorHandlerType() {
+ return errorHandlerType;
+ }
+
+ public void setErrorHandlerType(BaseErrorHandlerDefinition errorHandlerType) {
+ this.errorHandlerType = errorHandlerType;
+ }
+
+ @Override
+ public String toString() {
+ return "ErrorHandler[" + description() + "]";
+ }
+
+ protected String description() {
+ return errorHandlerType != null ? errorHandlerType.toString() : "";
+ }
+
+}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
index c7e2d3e8941..16fc5b8f9b7 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
@@ -76,7 +76,9 @@ public class RouteDefinition extends OutputDefinition<RouteDefinition> implement
private String shutdownRoute;
private String shutdownRunningTask;
private String errorHandlerRef;
+ @Deprecated
private ErrorHandlerFactory errorHandlerFactory;
+ private ErrorHandlerDefinition errorHandler;
// keep state whether the error handler is context scoped or not
// (will by default be context scoped of no explicit error handler
// configured)
@@ -413,6 +415,19 @@ public class RouteDefinition extends OutputDefinition<RouteDefinition> implement
return this;
}
+ /**
+ * Installs the given <a href="http://camel.apache.org/error-handler.html">error handler</a> builder.
+ *
+ * @param errorHandlerBuilder the error handler to be used by default for all child routes
+ * @return the current builder with the error handler configured
+ */
+ public RouteDefinition errorHandler2(ErrorHandlerDefinition errorHandlerBuilder) {
+ setErrorHandlerFactory(errorHandlerBuilder);
+ // we are now using a route scoped error handler
+ contextScopedErrorHandler = false;
+ return this;
+ }
+
/**
* Installs the given <a href="http://camel.apache.org/error-handler.html">error handler</a> builder.
*
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplatesDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplatesDefinition.java
index efe03c984bf..2dd38bd1f18 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplatesDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplatesDefinition.java
@@ -42,6 +42,7 @@ public class RouteTemplatesDefinition extends OptionalIdentifiedDefinition<Route
@XmlTransient
private CamelContext camelContext;
@XmlTransient
+ @Deprecated
private ErrorHandlerFactory errorHandlerFactory;
@XmlElementRef
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RoutesDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RoutesDefinition.java
index 2ce18c65348..2b388275d43 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/RoutesDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RoutesDefinition.java
@@ -62,6 +62,7 @@ public class RoutesDefinition extends OptionalIdentifiedDefinition<RoutesDefinit
@XmlTransient
private CamelContext camelContext;
@XmlTransient
+ @Deprecated
private ErrorHandlerFactory errorHandlerFactory;
@XmlTransient
private Resource resource;
diff --git a/core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/BaseErrorHandlerDefinition.java
similarity index 59%
copy from core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java
copy to core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/BaseErrorHandlerDefinition.java
index 9941a6ae1c4..2ad41764a3d 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/BaseErrorHandlerDefinition.java
@@ -14,11 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel;
+package org.apache.camel.model.errorhandler;
-/**
- * Factory for creating {@link org.apache.camel.spi.ErrorHandler}s.
- */
-public interface ErrorHandlerFactory {
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.model.IdentifiedType;
+import org.apache.camel.spi.Metadata;
+
+@Metadata(label = "configuration,error")
+@XmlRootElement(name = "baseErrorHandler")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class BaseErrorHandlerDefinition extends IdentifiedType implements ErrorHandlerFactory {
}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DeadLetterChannelDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DeadLetterChannelDefinition.java
new file mode 100644
index 00000000000..41fc490a18f
--- /dev/null
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DeadLetterChannelDefinition.java
@@ -0,0 +1,108 @@
+/*
+ * 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.errorhandler;
+
+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.builder.ErrorHandlerBuilder;
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Dead letter channel error handler.
+ */
+@Metadata(label = "configuration,error")
+@XmlRootElement(name = "deadLetterChannel")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class DeadLetterChannelDefinition extends DefaultErrorHandlerDefinition implements ErrorHandlerBuilder {
+
+ // TODO: fluent builders
+ // TODO: label, java type, ref
+
+ @XmlAttribute(required = true)
+ private String deadLetterUri;
+ @XmlAttribute
+ @Metadata(defaultValue = "true")
+ private String deadLetterHandleNewException;
+
+ public String getDeadLetterUri() {
+ return deadLetterUri;
+ }
+
+ /**
+ * The dead letter endpoint uri for the Dead Letter error handler.
+ */
+ public void setDeadLetterUri(String deadLetterUri) {
+ this.deadLetterUri = deadLetterUri;
+ }
+
+ public String getDeadLetterHandleNewException() {
+ return deadLetterHandleNewException;
+ }
+
+ /**
+ * Whether the dead letter channel should handle (and ignore) any new exception that may been thrown during sending
+ * the message to the dead letter endpoint.
+ * <p/>
+ * The default value is <tt>true</tt> which means any such kind of exception is handled and ignored. Set this to
+ * <tt>false</tt> to let the exception be propagated back on the {@link org.apache.camel.Exchange}. This can be used
+ * in situations where you use transactions, and want to use Camel's dead letter channel to deal with exceptions
+ * during routing, but if the dead letter channel itself fails because of a new exception being thrown, then by
+ * setting this to <tt>false</tt> the new exceptions is propagated back and set on the
+ * {@link org.apache.camel.Exchange}, which allows the transaction to detect the exception, and rollback.
+ */
+ public void setDeadLetterHandleNewException(String deadLetterHandleNewException) {
+ this.deadLetterHandleNewException = deadLetterHandleNewException;
+ }
+
+ @Override
+ public boolean supportTransacted() {
+ return false;
+ }
+
+ @Override
+ public ErrorHandlerBuilder cloneBuilder() {
+ DeadLetterChannelDefinition answer = new DeadLetterChannelDefinition();
+ cloneBuilder(answer);
+ return answer;
+ }
+
+ protected void cloneBuilder(DeadLetterChannelDefinition other) {
+ other.setLoggerBean(getLoggerBean());
+ if (getRedeliveryPolicy() != null) {
+ // TODO: copy
+ // other.setRedeliveryPolicy(getRedeliveryPolicy().copy());
+ }
+ other.setOnRedeliveryProcessor(getOnRedeliveryProcessor());
+ other.setOnRedeliveryRef(getOnRedeliveryRef());
+ other.setRetryWhilePredicate(getRetryWhilePredicate());
+ other.setRetryWhileRef(getRetryWhileRef());
+ other.setDeadLetterUri(getDeadLetterUri());
+ other.setOnPrepareFailureProcessor(getOnPrepareFailureProcessor());
+ other.setOnPrepareFailureRef(getOnPrepareFailureRef());
+ other.setOnExceptionOccurredProcessor(getOnExceptionOccurredProcessor());
+ other.setOnExceptionOccurredRef(getOnExceptionOccurredRef());
+ other.setDeadLetterHandleNewException(getDeadLetterHandleNewException());
+ other.setUseOriginalMessage(getUseOriginalMessage());
+ other.setUseOriginalBody(getUseOriginalBody());
+ other.setExecutorServiceBean(getExecutorServiceBean());
+ other.setExecutorServiceRef(getExecutorServiceRef());
+ }
+
+}
diff --git a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DefaultErrorHandlerDefinition.java
similarity index 71%
copy from components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerDefinition.java
copy to core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DefaultErrorHandlerDefinition.java
index 1d1141a4a5f..d65bf96944f 100644
--- a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/ErrorHandlerDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DefaultErrorHandlerDefinition.java
@@ -14,33 +14,51 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.spring.xml;
+package org.apache.camel.model.errorhandler;
+
+import java.util.concurrent.ScheduledExecutorService;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
import org.apache.camel.LoggingLevel;
-import org.apache.camel.model.IdentifiedType;
+import org.apache.camel.Predicate;
+import org.apache.camel.Processor;
+import org.apache.camel.model.RedeliveryPolicyDefinition;
import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
+import org.apache.camel.spi.CamelLogger;
import org.apache.camel.spi.Metadata;
/**
- * Error handler settings
+ * Default error handler.
*/
-@Metadata(label = "spring,configuration,error")
-@XmlRootElement(name = "errorHandler")
+@Metadata(label = "configuration,error")
+@XmlRootElement(name = "defaultErrorHandler")
@XmlAccessorType(XmlAccessType.FIELD)
-public class ErrorHandlerDefinition extends IdentifiedType {
- @XmlAttribute
- @Metadata(defaultValue = "DefaultErrorHandler", required = true)
- private ErrorHandlerType type = ErrorHandlerType.DefaultErrorHandler;
- @XmlAttribute
- private String deadLetterUri;
+public class DefaultErrorHandlerDefinition extends BaseErrorHandlerDefinition {
+
+ // TODO: fluent builders
+ // TODO: label, java type, ref
+
+ @XmlTransient
+ private CamelLogger loggerBean;
+ @XmlTransient
+ private Processor onRedeliveryProcessor;
+ @XmlTransient
+ private Processor onPrepareFailureProcessor;
+ @XmlTransient
+ private Processor onExceptionOccurredProcessor;
+ @XmlTransient
+ private ScheduledExecutorService executorServiceBean;
+ @XmlTransient
+ private Predicate retryWhilePredicate;
+
@XmlAttribute
- private String deadLetterHandleNewException;
+ private String loggerRef;
@XmlAttribute
@Metadata(defaultValue = "ERROR")
private LoggingLevel level;
@@ -50,13 +68,11 @@ public class ErrorHandlerDefinition extends IdentifiedType {
@XmlAttribute
private String logName;
@XmlAttribute
- private Boolean useOriginalMessage;
+ @Metadata(javaType = "java.lang.Boolean")
+ private String useOriginalMessage;
@XmlAttribute
- private Boolean useOriginalBody;
- @XmlAttribute
- private String transactionTemplateRef;
- @XmlAttribute
- private String transactionManagerRef;
+ @Metadata(javaType = "java.lang.Boolean")
+ private String useOriginalBody;
@XmlAttribute
private String onRedeliveryRef;
@XmlAttribute
@@ -70,47 +86,25 @@ public class ErrorHandlerDefinition extends IdentifiedType {
@XmlAttribute
private String executorServiceRef;
@XmlElement
- private CamelRedeliveryPolicyFactoryBean redeliveryPolicy;
-
- public ErrorHandlerType getType() {
- return type;
- }
+ private RedeliveryPolicyDefinition redeliveryPolicy;
- /**
- * The type of the error handler
- */
- public void setType(ErrorHandlerType type) {
- this.type = type;
- }
-
- public String getDeadLetterUri() {
- return deadLetterUri;
+ public String getLoggerRef() {
+ return loggerRef;
}
/**
- * The dead letter endpoint uri for the Dead Letter error handler.
+ * References to a logger to use as logger for the error handler
*/
- public void setDeadLetterUri(String deadLetterUri) {
- this.deadLetterUri = deadLetterUri;
+ public void setLoggerRef(String loggerRef) {
+ this.loggerRef = loggerRef;
}
- public String getDeadLetterHandleNewException() {
- return deadLetterHandleNewException;
+ public CamelLogger getLoggerBean() {
+ return loggerBean;
}
- /**
- * Whether the dead letter channel should handle (and ignore) any new exception that may been thrown during sending
- * the message to the dead letter endpoint.
- * <p/>
- * The default value is <tt>true</tt> which means any such kind of exception is handled and ignored. Set this to
- * <tt>false</tt> to let the exception be propagated back on the {@link org.apache.camel.Exchange}. This can be used
- * in situations where you use transactions, and want to use Camel's dead letter channel to deal with exceptions
- * during routing, but if the dead letter channel itself fails because of a new exception being thrown, then by
- * setting this to <tt>false</tt> the new exceptions is propagated back and set on the
- * {@link org.apache.camel.Exchange}, which allows the transaction to detect the exception, and rollback.
- */
- public void setDeadLetterHandleNewException(String deadLetterHandleNewException) {
- this.deadLetterHandleNewException = deadLetterHandleNewException;
+ public void setLoggerBean(CamelLogger loggerBean) {
+ this.loggerBean = loggerBean;
}
public LoggingLevel getLevel() {
@@ -148,7 +142,7 @@ public class ErrorHandlerDefinition extends IdentifiedType {
this.logName = logName;
}
- public Boolean getUseOriginalMessage() {
+ public String getUseOriginalMessage() {
return useOriginalMessage;
}
@@ -180,14 +174,12 @@ public class ErrorHandlerDefinition extends IdentifiedType {
* therefore use the parent original message.
* <p/>
* By default this feature is off.
- *
- * @see #setUseOriginalBody(Boolean)
*/
- public void setUseOriginalMessage(Boolean useOriginalMessage) {
+ public void setUseOriginalMessage(String useOriginalMessage) {
this.useOriginalMessage = useOriginalMessage;
}
- public Boolean getUseOriginalBody() {
+ public String getUseOriginalBody() {
return useOriginalBody;
}
@@ -219,48 +211,35 @@ public class ErrorHandlerDefinition extends IdentifiedType {
* therefore use the parent original message.
* <p/>
* By default this feature is off.
- *
- * @see #setUseOriginalMessage(Boolean)
*/
- public void setUseOriginalBody(Boolean useOriginalBody) {
+ public void setUseOriginalBody(String useOriginalBody) {
this.useOriginalBody = useOriginalBody;
}
- public String getTransactionTemplateRef() {
- return transactionTemplateRef;
- }
-
- /**
- * References to the {@link org.springframework.transaction.support.TransactionTemplate} to use with the transaction
- * error handler.
- */
- public void setTransactionTemplateRef(String transactionTemplateRef) {
- this.transactionTemplateRef = transactionTemplateRef;
- }
-
- public String getTransactionManagerRef() {
- return transactionManagerRef;
+ public String getOnRedeliveryRef() {
+ return onRedeliveryRef;
}
/**
- * References to the {@link org.springframework.transaction.PlatformTransactionManager} to use with the transaction
- * error handler.
+ * Sets a reference to a processor that should be processed <b>before</b> a redelivery attempt.
+ * <p/>
+ * Can be used to change the {@link org.apache.camel.Exchange} <b>before</b> its being redelivered.
*/
- public void setTransactionManagerRef(String transactionManagerRef) {
- this.transactionManagerRef = transactionManagerRef;
+ public void setOnRedeliveryRef(String onRedeliveryRef) {
+ this.onRedeliveryRef = onRedeliveryRef;
}
- public String getOnRedeliveryRef() {
- return onRedeliveryRef;
+ public Processor getOnRedeliveryProcessor() {
+ return onRedeliveryProcessor;
}
/**
- * Sets a reference to a processor that should be processed <b>before</b> a redelivery attempt.
+ * Sets a processor that should be processed <b>before</b> a redelivery attempt.
* <p/>
* Can be used to change the {@link org.apache.camel.Exchange} <b>before</b> its being redelivered.
*/
- public void setOnRedeliveryRef(String onRedeliveryRef) {
- this.onRedeliveryRef = onRedeliveryRef;
+ public void setOnRedeliveryProcessor(Processor onRedeliveryProcessor) {
+ this.onRedeliveryProcessor = onRedeliveryProcessor;
}
public String getOnExceptionOccurredRef() {
@@ -277,6 +256,20 @@ public class ErrorHandlerDefinition extends IdentifiedType {
this.onExceptionOccurredRef = onExceptionOccurredRef;
}
+ public Processor getOnExceptionOccurredProcessor() {
+ return onExceptionOccurredProcessor;
+ }
+
+ /**
+ * Sets a processor that should be processed <b>just after</b> an exception occurred. Can be used to perform custom
+ * logging about the occurred exception at the exact time it happened.
+ * <p/>
+ * Important: Any exception thrown from this processor will be ignored.
+ */
+ public void setOnExceptionOccurredProcessor(Processor onExceptionOccurredProcessor) {
+ this.onExceptionOccurredProcessor = onExceptionOccurredProcessor;
+ }
+
public String getOnPrepareFailureRef() {
return onPrepareFailureRef;
}
@@ -290,14 +283,26 @@ public class ErrorHandlerDefinition extends IdentifiedType {
this.onPrepareFailureRef = onPrepareFailureRef;
}
+ public Processor getOnPrepareFailureProcessor() {
+ return onPrepareFailureProcessor;
+ }
+
+ /**
+ * Sets a processor to prepare the {@link org.apache.camel.Exchange} before handled by the failure processor / dead
+ * letter channel. This allows for example to enrich the message before sending to a dead letter queue.
+ */
+ public void setOnPrepareFailureProcessor(Processor onPrepareFailureProcessor) {
+ this.onPrepareFailureProcessor = onPrepareFailureProcessor;
+ }
+
public String getRetryWhileRef() {
return retryWhileRef;
}
/**
- * Sets a reference to an retry while expression.
- * <p/>
- * Will continue retrying until expression evaluates to <tt>false</tt>.
+ * Sets a retry while predicate.
+ *
+ * Will continue retrying until the predicate evaluates to false.
*/
public void setRetryWhileRef(String retryWhileRef) {
this.retryWhileRef = retryWhileRef;
@@ -325,14 +330,38 @@ public class ErrorHandlerDefinition extends IdentifiedType {
this.executorServiceRef = executorServiceRef;
}
- public CamelRedeliveryPolicyFactoryBean getRedeliveryPolicy() {
+ public ScheduledExecutorService getExecutorServiceBean() {
+ return executorServiceBean;
+ }
+
+ /**
+ * Sets a thread pool to be used by the error handler
+ */
+ public void setExecutorServiceBean(ScheduledExecutorService executorServiceBean) {
+ this.executorServiceBean = executorServiceBean;
+ }
+
+ public Predicate getRetryWhilePredicate() {
+ return retryWhilePredicate;
+ }
+
+ /**
+ * Sets a retry while predicate.
+ *
+ * Will continue retrying until the predicate evaluates to false.
+ */
+ public void setRetryWhilePredicate(Predicate retryWhilePredicate) {
+ this.retryWhilePredicate = retryWhilePredicate;
+ }
+
+ public RedeliveryPolicyDefinition getRedeliveryPolicy() {
return redeliveryPolicy;
}
/**
* Sets the redelivery settings
*/
- public void setRedeliveryPolicy(CamelRedeliveryPolicyFactoryBean redeliveryPolicy) {
+ public void setRedeliveryPolicy(RedeliveryPolicyDefinition redeliveryPolicy) {
this.redeliveryPolicy = redeliveryPolicy;
}
}
diff --git a/core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/NoErrorHandlerDefinition.java
similarity index 64%
copy from core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java
copy to core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/NoErrorHandlerDefinition.java
index 9941a6ae1c4..31dfa7284ba 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ErrorHandlerFactory.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/NoErrorHandlerDefinition.java
@@ -14,11 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel;
+package org.apache.camel.model.errorhandler;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.spi.Metadata;
/**
- * Factory for creating {@link org.apache.camel.spi.ErrorHandler}s.
+ * No error handler.
*/
-public interface ErrorHandlerFactory {
+@Metadata(label = "configuration,error")
+@XmlRootElement(name = "noErrorHandler")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class NoErrorHandlerDefinition extends BaseErrorHandlerDefinition {
}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/TransactionErrorHandlerDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/TransactionErrorHandlerDefinition.java
new file mode 100644
index 00000000000..cb5eef529bb
--- /dev/null
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/TransactionErrorHandlerDefinition.java
@@ -0,0 +1,65 @@
+/*
+ * 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.errorhandler;
+
+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.spi.Metadata;
+
+/**
+ * Transactional error handler.
+ */
+@Metadata(label = "configuration,error")
+@XmlRootElement(name = "transactionErrorHandler")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class TransactionErrorHandlerDefinition extends DefaultErrorHandlerDefinition {
+
+ // TODO: fluent builders
+ // TODO: label, java type, ref
+ // TODO: spring and jta
+
+ @XmlAttribute
+ private String transactionTemplateRef;
+ @XmlAttribute
+ private String transactionManagerRef;
+
+ public String getTransactionTemplateRef() {
+ return transactionTemplateRef;
+ }
+
+ /**
+ * References to the spring transaction template to use.
+ */
+ public void setTransactionTemplateRef(String transactionTemplateRef) {
+ this.transactionTemplateRef = transactionTemplateRef;
+ }
+
+ public String getTransactionManagerRef() {
+ return transactionManagerRef;
+ }
+
+ /**
+ * References to the spring platform transaction manager to use.
+ */
+ public void setTransactionManagerRef(String transactionManagerRef) {
+ this.transactionManagerRef = transactionManagerRef;
+ }
+
+}
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java
index b13b98b2c5a..9ddaeea14bf 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java
@@ -225,7 +225,7 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> {
List<ProcessorDefinition<?>> list = new ArrayList<>(definition.getOutputs());
for (ProcessorDefinition<?> output : list) {
try {
- ProcessorReifier reifier = ProcessorReifier.reifier(route, output);
+ ProcessorReifier<?> reifier = ProcessorReifier.reifier(route, output);
// ensure node has id assigned
String outputId = output.idOrCreate(camelContext.adapt(ExtendedCamelContext.class).getNodeIdFactory());
@@ -241,7 +241,7 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> {
}
}
- // now lets turn all of the event driven consumer processors into a single route
+ // now lets turn all the event driven consumer processors into a single route
List<Processor> eventDrivenProcessors = route.getEventDrivenProcessors();
if (eventDrivenProcessors.isEmpty()) {
return null;
@@ -250,7 +250,7 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> {
// Set route properties
Map<String, Object> routeProperties = computeRouteProperties();
- // always use an pipeline even if there are only 1 processor as the pipeline
+ // always use a pipeline even if there are only 1 processor as the pipeline
// handles preparing the response from the exchange in regard to IN vs OUT messages etc
RoutePipeline target = new RoutePipeline(camelContext, eventDrivenProcessors);
target.setRouteId(id);
@@ -337,16 +337,14 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> {
// inject the route error handler for processors that are error handler aware
// this needs to be done here at the end because the route may be transactional and have a transaction error handler
- // automatic be configured which some EIPs like Multicast/RecipientList needs to be using for special fine grained error handling
+ // automatic be configured which some EIPs like Multicast/RecipientList needs to be using for special fine-grained error handling
ErrorHandlerFactory builder = route.getErrorHandlerFactory();
Processor errorHandler = camelContext.adapt(ModelCamelContext.class).getModelReifierFactory().createErrorHandler(route,
builder, null);
prepareErrorHandlerAware(route, errorHandler);
- camelContext.adapt(ExtendedCamelContext.class).addBootstrap(() -> {
- // okay route has been created from the model, then the model is no longer needed and we can de-reference
- route.clearRouteModel();
- });
+ // okay route has been created from the model, then the model is no longer needed, and we can de-reference
+ camelContext.adapt(ExtendedCamelContext.class).addBootstrap(route::clearRouteModel);
return route;
}
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
index 7ac9428ba7b..67c91b7a7f6 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
@@ -34,6 +34,7 @@ import org.apache.camel.Route;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.model.OnExceptionDefinition;
import org.apache.camel.model.RedeliveryPolicyDefinition;
+import org.apache.camel.model.errorhandler.DeadLetterChannelDefinition;
import org.apache.camel.model.errorhandler.DeadLetterChannelProperties;
import org.apache.camel.model.errorhandler.DefaultErrorHandlerProperties;
import org.apache.camel.model.errorhandler.ErrorHandlerRefProperties;
@@ -100,6 +101,18 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends
} else if (definition instanceof NoErrorHandlerProperties) {
return new NoErrorHandlerReifier(route, definition);
}
+
+ if (definition instanceof DeadLetterChannelDefinition) {
+ return new NewDeadLetterChannelReifier(route, (DeadLetterChannelDefinition) definition);
+ // } else if (definition instanceof DefaultErrorHandlerDefinition) {
+ // return new DefaultErrorHandlerReifier<>(route, definition);
+ // TODO: ref properties?
+ // } else if (definition instanceof ErrorHandlerRefProperties) {
+ // return new ErrorHandlerRefReifier(route, definition);
+ // } else if (definition instanceof NoErrorHandlerDefinition) {
+ // return new NoErrorHandlerReifier(route, definition);
+ }
+
return null;
}
@@ -125,10 +138,124 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends
ObjectHelper.isNotEmpty(def.getOutputs()), handled,
continued, retryWhile, onRedelivery,
onExceptionOccurred, def.getRedeliveryPolicyRef(),
- getRedeliveryPolicy(def.getRedeliveryPolicyType()), def.getExceptions());
+ createRedeliveryPolicyOptions(def.getRedeliveryPolicyType()), def.getExceptions());
}
- private static Map<RedeliveryOption, String> getRedeliveryPolicy(RedeliveryPolicyDefinition definition) {
+ public static RedeliveryPolicy createRedeliveryPolicy(RedeliveryPolicyDefinition definition, CamelContext context) {
+ Map<RedeliveryOption, String> options = createRedeliveryPolicyOptions(definition);
+ return createRedeliveryPolicy(options, context, null);
+ }
+
+ private static RedeliveryPolicy createRedeliveryPolicy(
+ Map<RedeliveryOption, String> definition, CamelContext context, RedeliveryPolicy parentPolicy) {
+ RedeliveryPolicy answer;
+ if (parentPolicy != null) {
+ answer = parentPolicy.copy();
+ } else {
+ answer = new RedeliveryPolicy();
+ }
+ try {
+ if (definition.get(RedeliveryOption.maximumRedeliveries) != null) {
+ answer.setMaximumRedeliveries(
+ CamelContextHelper.parseInteger(context, definition.get(RedeliveryOption.maximumRedeliveries)));
+ }
+ if (definition.get(RedeliveryOption.redeliveryDelay) != null) {
+ answer.setRedeliveryDelay(
+ CamelContextHelper.parseLong(context, definition.get(RedeliveryOption.redeliveryDelay)));
+ }
+ if (definition.get(RedeliveryOption.asyncDelayedRedelivery) != null) {
+ answer.setAsyncDelayedRedelivery(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.asyncDelayedRedelivery)));
+ }
+ if (definition.get(RedeliveryOption.retriesExhaustedLogLevel) != null) {
+ answer.setRetriesExhaustedLogLevel(CamelContextHelper.parse(context, LoggingLevel.class,
+ definition.get(RedeliveryOption.retriesExhaustedLogLevel)));
+ }
+ if (definition.get(RedeliveryOption.retryAttemptedLogLevel) != null) {
+ answer.setRetryAttemptedLogLevel(CamelContextHelper.parse(context, LoggingLevel.class,
+ definition.get(RedeliveryOption.retryAttemptedLogLevel)));
+ }
+ if (definition.get(RedeliveryOption.retryAttemptedLogInterval) != null) {
+ answer.setRetryAttemptedLogInterval(
+ CamelContextHelper.parseInteger(context, definition.get(RedeliveryOption.retryAttemptedLogInterval)));
+ }
+ if (definition.get(RedeliveryOption.backOffMultiplier) != null) {
+ answer.setBackOffMultiplier(
+ CamelContextHelper.parseDouble(context, definition.get(RedeliveryOption.backOffMultiplier)));
+ }
+ if (definition.get(RedeliveryOption.useExponentialBackOff) != null) {
+ answer.setUseExponentialBackOff(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.useExponentialBackOff)));
+ }
+ if (definition.get(RedeliveryOption.collisionAvoidanceFactor) != null) {
+ answer.setCollisionAvoidanceFactor(
+ CamelContextHelper.parseDouble(context, definition.get(RedeliveryOption.collisionAvoidanceFactor)));
+ }
+ if (definition.get(RedeliveryOption.useCollisionAvoidance) != null) {
+ answer.setUseCollisionAvoidance(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.useCollisionAvoidance)));
+ }
+ if (definition.get(RedeliveryOption.maximumRedeliveryDelay) != null) {
+ answer.setMaximumRedeliveryDelay(
+ CamelContextHelper.parseLong(context, definition.get(RedeliveryOption.maximumRedeliveryDelay)));
+ }
+ if (definition.get(RedeliveryOption.logStackTrace) != null) {
+ answer.setLogStackTrace(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logStackTrace)));
+ }
+ if (definition.get(RedeliveryOption.logRetryStackTrace) != null) {
+ answer.setLogRetryStackTrace(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logRetryStackTrace)));
+ }
+ if (definition.get(RedeliveryOption.logHandled) != null) {
+ answer.setLogHandled(CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logHandled)));
+ }
+ if (definition.get(RedeliveryOption.logNewException) != null) {
+ answer.setLogNewException(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logNewException)));
+ }
+ if (definition.get(RedeliveryOption.logContinued) != null) {
+ answer.setLogContinued(CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logContinued)));
+ }
+ if (definition.get(RedeliveryOption.logRetryAttempted) != null) {
+ answer.setLogRetryAttempted(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logRetryAttempted)));
+ }
+ if (definition.get(RedeliveryOption.logExhausted) != null) {
+ answer.setLogExhausted(CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logExhausted)));
+ }
+ if (definition.get(RedeliveryOption.logExhaustedMessageHistory) != null) {
+ answer.setLogExhaustedMessageHistory(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logExhaustedMessageHistory)));
+ }
+ if (definition.get(RedeliveryOption.logExhaustedMessageBody) != null) {
+ answer.setLogExhaustedMessageBody(
+ CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.logExhaustedMessageBody)));
+ }
+ if (definition.get(RedeliveryOption.disableRedelivery) != null) {
+ if (CamelContextHelper.parseBoolean(context, definition.get(RedeliveryOption.disableRedelivery))) {
+ answer.setMaximumRedeliveries(0);
+ }
+ }
+ if (definition.get(RedeliveryOption.delayPattern) != null) {
+ answer.setDelayPattern(CamelContextHelper.parseText(context, definition.get(RedeliveryOption.delayPattern)));
+ }
+ if (definition.get(RedeliveryOption.allowRedeliveryWhileStopping) != null) {
+ answer.setAllowRedeliveryWhileStopping(CamelContextHelper.parseBoolean(context,
+ definition.get(RedeliveryOption.allowRedeliveryWhileStopping)));
+ }
+ if (definition.get(RedeliveryOption.exchangeFormatterRef) != null) {
+ answer.setExchangeFormatterRef(
+ CamelContextHelper.parseText(context, definition.get(RedeliveryOption.exchangeFormatterRef)));
+ }
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeCamelException(e);
+ }
+
+ return answer;
+ }
+
+ private static Map<RedeliveryOption, String> createRedeliveryPolicyOptions(RedeliveryPolicyDefinition definition) {
if (definition == null) {
return null;
}
@@ -243,7 +370,6 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends
}
try {
-
// copy across the properties - if they are set
if (definition.getMaximumRedeliveries() != null) {
answer.setMaximumRedeliveries(CamelContextHelper.parseInteger(context, definition.getMaximumRedeliveries()));
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/NewDeadLetterChannelReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/NewDeadLetterChannelReifier.java
new file mode 100644
index 00000000000..a8ac22aa654
--- /dev/null
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/NewDeadLetterChannelReifier.java
@@ -0,0 +1,142 @@
+/*
+ * 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.reifier.errorhandler;
+
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Predicate;
+import org.apache.camel.Processor;
+import org.apache.camel.Route;
+import org.apache.camel.model.RedeliveryPolicyDefinition;
+import org.apache.camel.model.errorhandler.DeadLetterChannelDefinition;
+import org.apache.camel.processor.FatalFallbackErrorHandler;
+import org.apache.camel.processor.SendProcessor;
+import org.apache.camel.processor.errorhandler.DeadLetterChannel;
+import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
+import org.apache.camel.spi.CamelLogger;
+import org.apache.camel.spi.ExecutorServiceManager;
+import org.apache.camel.spi.Language;
+import org.apache.camel.spi.ThreadPoolProfile;
+import org.apache.camel.util.ObjectHelper;
+
+public class NewDeadLetterChannelReifier extends ErrorHandlerReifier<DeadLetterChannelDefinition> {
+
+ public NewDeadLetterChannelReifier(Route route, DeadLetterChannelDefinition definition) {
+ super(route, definition);
+ }
+
+ @Override
+ public Processor createErrorHandler(Processor processor) throws Exception {
+ ObjectHelper.notNull(definition.getDeadLetterUri(), "deadLetterUri", this);
+
+ // optimize to use shared default instance if using out of the box settings
+ RedeliveryPolicy redeliveryPolicy = resolveRedeliveryPolicy(definition, camelContext);
+ CamelLogger logger = resolveLogger(definition, camelContext);
+
+ Processor deadLetterProcessor = createDeadLetterChannelProcessor(definition.getDeadLetterUri());
+
+ DeadLetterChannel answer = new DeadLetterChannel(
+ camelContext, processor, logger,
+ getProcessor(definition.getOnRedeliveryProcessor(), definition.getRedeliveryPolicyRef()),
+ redeliveryPolicy, deadLetterProcessor,
+ definition.getDeadLetterUri(),
+ parseBoolean(definition.getDeadLetterHandleNewException(), true),
+ parseBoolean(definition.getUseOriginalMessage(), false),
+ parseBoolean(definition.getUseOriginalBody(), false),
+ resolveRetryWhilePolicy(definition, camelContext),
+ getExecutorService(definition.getExecutorServiceBean(), definition.getExecutorServiceRef()),
+ getProcessor(definition.getOnPrepareFailureProcessor(), definition.getOnPrepareFailureRef()),
+ getProcessor(definition.getOnExceptionOccurredProcessor(), definition.getOnExceptionOccurredRef()));
+ // configure error handler before we can use it
+ configure(answer);
+ return answer;
+ }
+
+ private Predicate resolveRetryWhilePolicy(DeadLetterChannelDefinition definition, CamelContext camelContext) {
+ Predicate answer = definition.getRetryWhilePredicate();
+
+ if (answer == null && definition.getRetryWhileRef() != null) {
+ // it is a bean expression
+ Language bean = camelContext.resolveLanguage("bean");
+ answer = bean.createPredicate(definition.getRetryWhileRef());
+ answer.initPredicate(camelContext);
+ }
+
+ return answer;
+ }
+
+ private CamelLogger resolveLogger(DeadLetterChannelDefinition definition, CamelContext camelContext) {
+ CamelLogger answer = definition.getLoggerBean();
+ if (answer == null && definition.getLoggerRef() != null) {
+ answer = mandatoryLookup(definition.getLoggerRef(), CamelLogger.class);
+ }
+ return answer;
+ }
+
+ private Processor createDeadLetterChannelProcessor(String uri) {
+ // wrap in our special safe fallback error handler if sending to
+ // dead letter channel fails
+ Processor child = new SendProcessor(camelContext.getEndpoint(uri), ExchangePattern.InOnly);
+ // force MEP to be InOnly so when sending to DLQ we would not expect
+ // a reply if the MEP was InOut
+ return new FatalFallbackErrorHandler(child, true);
+ }
+
+ private RedeliveryPolicy resolveRedeliveryPolicy(DeadLetterChannelDefinition definition, CamelContext camelContext) {
+ RedeliveryPolicy answer = null;
+ RedeliveryPolicyDefinition def = definition.getRedeliveryPolicy();
+ if (def != null) {
+ answer = ErrorHandlerReifier.createRedeliveryPolicy(def, camelContext, null);
+ }
+ if (def == null && definition.getRedeliveryPolicyRef() != null) {
+ answer = mandatoryLookup(definition.getRedeliveryPolicyRef(), RedeliveryPolicy.class);
+ }
+ if (answer == null) {
+ answer = RedeliveryPolicy.DEFAULT_POLICY;
+ }
+ return answer;
+ }
+
+ protected synchronized ScheduledExecutorService getExecutorService(
+ ScheduledExecutorService executorService, String executorServiceRef) {
+ if (executorService == null || executorService.isShutdown()) {
+ // camel context will shutdown the executor when it shutdown so no
+ // need to shut it down when stopping
+ if (executorServiceRef != null) {
+ executorService = lookup(executorServiceRef, ScheduledExecutorService.class);
+ if (executorService == null) {
+ ExecutorServiceManager manager = camelContext.getExecutorServiceManager();
+ ThreadPoolProfile profile = manager.getThreadPoolProfile(executorServiceRef);
+ executorService = manager.newScheduledThreadPool(this, executorServiceRef, profile);
+ }
+ if (executorService == null) {
+ throw new IllegalArgumentException("ExecutorService " + executorServiceRef + " not found in registry.");
+ }
+ } else {
+ // no explicit configured thread pool, so leave it up to the
+ // error handler to decide if it need
+ // a default thread pool from
+ // CamelContext#getErrorHandlerExecutorService
+ executorService = null;
+ }
+ }
+ return executorService;
+ }
+
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/NewDeadLetterChannelTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/NewDeadLetterChannelTest.java
new file mode 100644
index 00000000000..2379ac835f8
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/NewDeadLetterChannelTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.processor.errorhandler;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.errorhandler.DeadLetterChannelDefinition;
+import org.junit.jupiter.api.Test;
+
+public class NewDeadLetterChannelTest extends ContextTestSupport {
+
+ @Test
+ public void testNewDeadLetterChannel() throws Exception {
+ getMockEndpoint("mock:dead").expectedMessageCount(1);
+
+ template.sendBody("direct:start", "Hello World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ DeadLetterChannelDefinition dlc = new DeadLetterChannelDefinition();
+ dlc.setDeadLetterUri("mock:dead");
+
+ errorHandler(dlc);
+
+ from("direct:start")
+ .throwException(new IllegalArgumentException("Forced"));
+ }
+ };
+ }
+}
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 94bdffd78ac..177d40ac991 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
@@ -29,12 +29,14 @@ import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
+import org.apache.camel.LoggingLevel;
import org.apache.camel.model.*;
import org.apache.camel.model.cloud.*;
import org.apache.camel.model.config.BatchResequencerConfig;
import org.apache.camel.model.config.ResequencerConfig;
import org.apache.camel.model.config.StreamResequencerConfig;
import org.apache.camel.model.dataformat.*;
+import org.apache.camel.model.errorhandler.*;
import org.apache.camel.model.language.*;
import org.apache.camel.model.loadbalancer.*;
import org.apache.camel.model.rest.*;
@@ -382,6 +384,23 @@ public class ModelParser extends BaseParser {
return true;
}, expressionNodeElementHandler(), noValueHandler());
}
+ protected ErrorHandlerDefinition doParseErrorHandlerDefinition() throws IOException, XmlPullParserException {
+ return doParse(new ErrorHandlerDefinition(),
+ identifiedTypeAttributeHandler(), (def, key) -> {
+ switch (key) {
+ case "defaultErrorHandler": def.setErrorHandlerType(doParseDefaultErrorHandlerDefinition()); break;
+ case "deadLetterChannel": def.setErrorHandlerType(doParseDeadLetterChannelDefinition()); break;
+ case "noErrorHandler": def.setErrorHandlerType(doParseNoErrorHandlerDefinition()); break;
+ case "transactionErrorHandler": def.setErrorHandlerType(doParseTransactionErrorHandlerDefinition()); break;
+ default: return false;
+ }
+ return true;
+ }, noValueHandler());
+ }
+ protected BaseErrorHandlerDefinition doParseBaseErrorHandlerDefinition() throws IOException, XmlPullParserException {
+ return doParse(new BaseErrorHandlerDefinition(),
+ identifiedTypeAttributeHandler(), noElementHandler(), noValueHandler());
+ }
protected <T extends FaultToleranceConfigurationCommon> AttributeHandler<T> faultToleranceConfigurationCommonAttributeHandler() {
return (def, key, val) -> {
switch (key) {
@@ -2579,6 +2598,62 @@ public class ModelParser extends BaseParser {
return true;
}, noElementHandler(), noValueHandler());
}
+ protected DeadLetterChannelDefinition doParseDeadLetterChannelDefinition() throws IOException, XmlPullParserException {
+ return doParse(new DeadLetterChannelDefinition(), (def, key, val) -> {
+ switch (key) {
+ case "deadLetterHandleNewException": def.setDeadLetterHandleNewException(val); break;
+ case "deadLetterUri": def.setDeadLetterUri(val); break;
+ default: return defaultErrorHandlerDefinitionAttributeHandler().accept(def, key, val);
+ }
+ return true;
+ }, defaultErrorHandlerDefinitionElementHandler(), noValueHandler());
+ }
+ protected <T extends DefaultErrorHandlerDefinition> AttributeHandler<T> defaultErrorHandlerDefinitionAttributeHandler() {
+ return (def, key, val) -> {
+ switch (key) {
+ case "executorServiceRef": def.setExecutorServiceRef(val); break;
+ case "level": def.setLevel(LoggingLevel.valueOf(val)); break;
+ case "logName": def.setLogName(val); break;
+ case "loggerRef": def.setLoggerRef(val); break;
+ case "onExceptionOccurredRef": def.setOnExceptionOccurredRef(val); break;
+ case "onPrepareFailureRef": def.setOnPrepareFailureRef(val); break;
+ case "onRedeliveryRef": def.setOnRedeliveryRef(val); break;
+ case "redeliveryPolicyRef": def.setRedeliveryPolicyRef(val); break;
+ case "retryWhileRef": def.setRetryWhileRef(val); break;
+ case "rollbackLoggingLevel": def.setRollbackLoggingLevel(LoggingLevel.valueOf(val)); break;
+ case "useOriginalBody": def.setUseOriginalBody(val); break;
+ case "useOriginalMessage": def.setUseOriginalMessage(val); break;
+ default: return identifiedTypeAttributeHandler().accept(def, key, val);
+ }
+ return true;
+ };
+ }
+ protected <T extends DefaultErrorHandlerDefinition> ElementHandler<T> defaultErrorHandlerDefinitionElementHandler() {
+ return (def, key) -> {
+ if ("redeliveryPolicy".equals(key)) {
+ def.setRedeliveryPolicy(doParseRedeliveryPolicyDefinition());
+ return true;
+ }
+ return false;
+ };
+ }
+ protected DefaultErrorHandlerDefinition doParseDefaultErrorHandlerDefinition() throws IOException, XmlPullParserException {
+ return doParse(new DefaultErrorHandlerDefinition(), defaultErrorHandlerDefinitionAttributeHandler(), defaultErrorHandlerDefinitionElementHandler(), noValueHandler());
+ }
+ protected NoErrorHandlerDefinition doParseNoErrorHandlerDefinition() throws IOException, XmlPullParserException {
+ return doParse(new NoErrorHandlerDefinition(),
+ identifiedTypeAttributeHandler(), noElementHandler(), noValueHandler());
+ }
+ protected TransactionErrorHandlerDefinition doParseTransactionErrorHandlerDefinition() throws IOException, XmlPullParserException {
+ return doParse(new TransactionErrorHandlerDefinition(), (def, key, val) -> {
+ switch (key) {
+ case "transactionManagerRef": def.setTransactionManagerRef(val); break;
+ case "transactionTemplateRef": def.setTransactionTemplateRef(val); break;
+ default: return defaultErrorHandlerDefinitionAttributeHandler().accept(def, key, val);
+ }
+ return true;
+ }, defaultErrorHandlerDefinitionElementHandler(), noValueHandler());
+ }
protected CSimpleExpression doParseCSimpleExpression() throws IOException, XmlPullParserException {
return doParse(new CSimpleExpression(), (def, key, val) -> {
if ("resultType".equals(key)) {