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/07 09:41:11 UTC

[camel] 02/05: 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 dbe67dafb1fae5182edc64ec7bd925105ca6737a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Apr 7 10:37:53 2022 +0200

    CAMEL-16834: error handler in model DSL. WIP
---
 .../spring/xml/handler/CamelNamespaceHandler.java  |  13 +-
 ...a => LegacyTransactionErrorHandlerReifier.java} |  12 +-
 .../spi/NewTransactionErrorHandlerReifier.java     | 216 --------------------
 .../spring/spi/TransactionErrorHandlerBuilder.java |   3 +-
 .../spring/spi/TransactionErrorHandlerReifier.java | 218 +++++++++++++++------
 ...er.java => LegacyDeadLetterChannelReifier.java} |   7 +-
 ....java => LegacyDefaultErrorHandlerReifier.java} |   7 +-
 ...fier.java => LegacyErrorHandlerRefReifier.java} |   7 +-
 ...ifier.java => LegacyNoErrorHandlerReifier.java} |   7 +-
 .../errorhandler/ErrorHandlerSupportTest.java      |   4 +-
 .../DefaultExceptionPolicyStrategyTest.java        |   4 +-
 11 files changed, 203 insertions(+), 295 deletions(-)

diff --git a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/handler/CamelNamespaceHandler.java b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/handler/CamelNamespaceHandler.java
index 366c440fe63..9b8bd04ed9a 100644
--- a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/handler/CamelNamespaceHandler.java
+++ b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/handler/CamelNamespaceHandler.java
@@ -40,10 +40,10 @@ import org.apache.camel.core.xml.CamelPropertyPlaceholderDefinition;
 import org.apache.camel.core.xml.CamelRouteControllerDefinition;
 import org.apache.camel.core.xml.CamelStreamCachingStrategyDefinition;
 import org.apache.camel.impl.engine.DefaultCamelContextNameStrategy;
-import org.apache.camel.reifier.errorhandler.DeadLetterChannelReifier;
-import org.apache.camel.reifier.errorhandler.DefaultErrorHandlerReifier;
 import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
-import org.apache.camel.reifier.errorhandler.NoErrorHandlerReifier;
+import org.apache.camel.reifier.errorhandler.LegacyDeadLetterChannelReifier;
+import org.apache.camel.reifier.errorhandler.LegacyDefaultErrorHandlerReifier;
+import org.apache.camel.reifier.errorhandler.LegacyNoErrorHandlerReifier;
 import org.apache.camel.spi.CamelContextNameStrategy;
 import org.apache.camel.spi.NamespaceAware;
 import org.apache.camel.spring.xml.CamelBeanPostProcessor;
@@ -84,9 +84,10 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport {
 
     static {
         // legacy camel-spring-xml error-handling using its own model and parsers
-        ErrorHandlerReifier.registerReifier(DeadLetterChannelBuilder.class, DeadLetterChannelReifier::new);
-        ErrorHandlerReifier.registerReifier(DefaultErrorHandlerBuilder.class, DefaultErrorHandlerReifier::new);
-        ErrorHandlerReifier.registerReifier(NoErrorHandlerBuilder.class, NoErrorHandlerReifier::new);
+        ErrorHandlerReifier.registerReifier(DeadLetterChannelBuilder.class, LegacyDeadLetterChannelReifier::new);
+        ErrorHandlerReifier.registerReifier(DefaultErrorHandlerBuilder.class, LegacyDefaultErrorHandlerReifier::new);
+        ErrorHandlerReifier.registerReifier(NoErrorHandlerBuilder.class, LegacyNoErrorHandlerReifier::new);
+        // note: spring transaction error handler is registered in camel-spring
     }
 
     private static final String SPRING_NS = "http://camel.apache.org/schema/spring";
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/LegacyTransactionErrorHandlerReifier.java
similarity index 91%
copy from components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java
copy to components/camel-spring/src/main/java/org/apache/camel/spring/spi/LegacyTransactionErrorHandlerReifier.java
index 763a1b6900d..75a52cf4bfa 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/LegacyTransactionErrorHandlerReifier.java
@@ -21,7 +21,7 @@ import java.util.Map;
 import org.apache.camel.ErrorHandlerFactory;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
-import org.apache.camel.reifier.errorhandler.DefaultErrorHandlerReifier;
+import org.apache.camel.reifier.errorhandler.LegacyDefaultErrorHandlerReifier;
 import org.apache.camel.spi.TransactedPolicy;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
@@ -31,11 +31,15 @@ import org.springframework.transaction.support.TransactionTemplate;
 
 import static org.apache.camel.model.TransactedDefinition.PROPAGATION_REQUIRED;
 
-public class TransactionErrorHandlerReifier extends DefaultErrorHandlerReifier<TransactionErrorHandlerBuilder> {
+/**
+ * Legacy error handler for XML DSL in camel-spring-xml/camel-blueprint
+ */
+@Deprecated
+public class LegacyTransactionErrorHandlerReifier extends LegacyDefaultErrorHandlerReifier<TransactionErrorHandlerBuilder> {
 
-    private static final Logger LOG = LoggerFactory.getLogger(TransactionErrorHandlerReifier.class);
+    private static final Logger LOG = LoggerFactory.getLogger(LegacyTransactionErrorHandlerReifier.class);
 
-    public TransactionErrorHandlerReifier(Route route, ErrorHandlerFactory definition) {
+    public LegacyTransactionErrorHandlerReifier(Route route, ErrorHandlerFactory definition) {
         super(route, definition);
     }
 
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/NewTransactionErrorHandlerReifier.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/NewTransactionErrorHandlerReifier.java
deleted file mode 100644
index 455ad94bcba..00000000000
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/NewTransactionErrorHandlerReifier.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.spring.spi;
-
-import java.util.Map;
-import java.util.concurrent.ScheduledExecutorService;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.LoggingLevel;
-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.TransactionErrorHandlerDefinition;
-import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
-import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
-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.spi.TransactedPolicy;
-import org.apache.camel.util.ObjectHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.support.TransactionTemplate;
-
-import static org.apache.camel.model.TransactedDefinition.PROPAGATION_REQUIRED;
-
-public class NewTransactionErrorHandlerReifier extends ErrorHandlerReifier<TransactionErrorHandlerDefinition> {
-
-    private static final Logger LOG = LoggerFactory.getLogger(NewTransactionErrorHandlerReifier.class);
-
-    public NewTransactionErrorHandlerReifier(Route route, TransactionErrorHandlerDefinition definition) {
-        super(route, definition);
-    }
-
-    @Override
-    public Processor createErrorHandler(Processor processor) throws Exception {
-        // must have a transaction template
-        TransactionTemplate transactionTemplate = resolveTransactionTemplate(definition, camelContext);
-        ObjectHelper.notNull(transactionTemplate, "transactionTemplate", this);
-
-        // optimize to use shared default instance if using out of the box settings
-        RedeliveryPolicy redeliveryPolicy = resolveRedeliveryPolicy(definition, camelContext);
-        CamelLogger logger = resolveLogger(definition, camelContext);
-        LoggingLevel rollbackLoggingLevel = resolveRollbackLoggingLevel(definition, camelContext);
-
-        TransactionErrorHandler answer = new TransactionErrorHandler(
-                camelContext, processor, logger,
-                getProcessor(definition.getOnRedeliveryProcessor(), definition.getOnRedeliveryRef()),
-                redeliveryPolicy,
-                transactionTemplate,
-                resolveRetryWhilePolicy(definition, camelContext),
-                getExecutorService(definition.getExecutorServiceBean(), definition.getExecutorServiceRef()),
-                rollbackLoggingLevel,
-                getProcessor(definition.getOnExceptionOccurredProcessor(), definition.getOnExceptionOccurredRef()));
-        // configure error handler before we can use it
-        configure(answer);
-        return answer;
-    }
-
-    private TransactionTemplate resolveTransactionTemplate(
-            TransactionErrorHandlerDefinition definition, CamelContext camelContext) {
-
-        String ref = definition.getTransactionTemplateRef();
-        if (ref != null) {
-            return mandatoryLookup(ref, TransactionTemplate.class);
-        }
-
-        // lookup in context if no transaction template has been configured
-        LOG.debug("No TransactionTemplate configured on TransactionErrorHandlerBuilder. Will try find it in the registry.");
-
-        TransactionTemplate answer = null;
-        Map<String, TransactedPolicy> mapPolicy = findByTypeWithName(TransactedPolicy.class);
-        if (mapPolicy != null && mapPolicy.size() == 1) {
-            TransactedPolicy policy = mapPolicy.values().iterator().next();
-            if (policy instanceof SpringTransactionPolicy) {
-                answer = ((SpringTransactionPolicy) policy).getTransactionTemplate();
-            }
-        }
-
-        if (answer == null) {
-            TransactedPolicy policy = lookupByNameAndType(PROPAGATION_REQUIRED, TransactedPolicy.class);
-            if (policy instanceof SpringTransactionPolicy) {
-                answer = ((SpringTransactionPolicy) policy).getTransactionTemplate();
-            }
-        }
-
-        if (answer == null) {
-            Map<String, TransactionTemplate> mapTemplate = findByTypeWithName(TransactionTemplate.class);
-            if (mapTemplate == null || mapTemplate.isEmpty()) {
-                LOG.trace("No TransactionTemplate found in registry.");
-            } else if (mapTemplate.size() == 1) {
-                answer = mapTemplate.values().iterator().next();
-            } else {
-                LOG.debug("Found {} TransactionTemplate in registry. Cannot determine which one to use. "
-                          + "Please configure a TransactionTemplate on the TransactionErrorHandlerBuilder",
-                        mapTemplate.size());
-            }
-        }
-
-        if (answer == null) {
-            Map<String, PlatformTransactionManager> mapManager = findByTypeWithName(PlatformTransactionManager.class);
-            if (mapManager == null || mapManager.isEmpty()) {
-                LOG.trace("No PlatformTransactionManager found in registry.");
-            } else if (mapManager.size() == 1) {
-                answer = new TransactionTemplate(mapManager.values().iterator().next());
-            } else {
-                LOG.debug(
-                        "Found {} PlatformTransactionManager in registry. Cannot determine which one to use for TransactionTemplate. "
-                          + "Please configure a TransactionTemplate on the TransactionErrorHandlerBuilder",
-                        mapManager.size());
-            }
-        }
-
-        if (answer != null) {
-            LOG.debug("Found TransactionTemplate in registry to use: {}", answer);
-        }
-        return answer;
-    }
-
-    private CamelLogger resolveLogger(TransactionErrorHandlerDefinition definition, CamelContext camelContext) {
-        CamelLogger answer = definition.getLoggerBean();
-        if (answer == null && definition.getLoggerRef() != null) {
-            answer = mandatoryLookup(definition.getLoggerRef(), CamelLogger.class);
-        }
-        if (answer == null) {
-            answer = new CamelLogger(LoggerFactory.getLogger(TransactionErrorHandler.class), LoggingLevel.ERROR);
-        }
-        if (definition.getLevel() != null) {
-            answer.setLevel(definition.getLevel());
-        }
-        return answer;
-    }
-
-    private LoggingLevel resolveRollbackLoggingLevel(TransactionErrorHandlerDefinition definition, CamelContext camelContext) {
-        LoggingLevel answer = LoggingLevel.WARN;
-        if (definition.getRollbackLoggingLevel() != null) {
-            answer = parse(LoggingLevel.class, definition.getRollbackLoggingLevel());
-        }
-        return answer;
-    }
-
-    private RedeliveryPolicy resolveRedeliveryPolicy(TransactionErrorHandlerDefinition definition, CamelContext camelContext) {
-        RedeliveryPolicy answer = null;
-        RedeliveryPolicyDefinition def = definition.getRedeliveryPolicy();
-        if (def == null && definition.getRedeliveryPolicyRef() != null) {
-            // ref may point to a definition
-            def = lookupByNameAndType(definition.getRedeliveryPolicyRef(), RedeliveryPolicyDefinition.class);
-        }
-        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;
-    }
-
-    private Predicate resolveRetryWhilePolicy(TransactionErrorHandlerDefinition 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;
-    }
-
-    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 = lookupByNameAndType(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/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
index d473e7cb318..e718c44e0c4 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
@@ -32,7 +32,8 @@ import org.springframework.transaction.support.TransactionTemplate;
 public class TransactionErrorHandlerBuilder extends DefaultErrorHandlerBuilder {
 
     static {
-        ErrorHandlerReifier.registerReifier(TransactionErrorHandlerBuilder.class, TransactionErrorHandlerReifier::new);
+        // legacy camel-spring-xml error-handling using its own model and parsers
+        ErrorHandlerReifier.registerReifier(TransactionErrorHandlerBuilder.class, LegacyTransactionErrorHandlerReifier::new);
     }
 
     private static final Logger LOG = LoggerFactory.getLogger(TransactionErrorHandlerBuilder.class);
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java
index 763a1b6900d..13d78b47165 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java
@@ -17,11 +17,21 @@
 package org.apache.camel.spring.spi;
 
 import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
 
-import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.CamelContext;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
-import org.apache.camel.reifier.errorhandler.DefaultErrorHandlerReifier;
+import org.apache.camel.model.RedeliveryPolicyDefinition;
+import org.apache.camel.model.errorhandler.TransactionErrorHandlerDefinition;
+import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
+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.spi.TransactedPolicy;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
@@ -31,80 +41,176 @@ import org.springframework.transaction.support.TransactionTemplate;
 
 import static org.apache.camel.model.TransactedDefinition.PROPAGATION_REQUIRED;
 
-public class TransactionErrorHandlerReifier extends DefaultErrorHandlerReifier<TransactionErrorHandlerBuilder> {
+public class TransactionErrorHandlerReifier extends ErrorHandlerReifier<TransactionErrorHandlerDefinition> {
 
     private static final Logger LOG = LoggerFactory.getLogger(TransactionErrorHandlerReifier.class);
 
-    public TransactionErrorHandlerReifier(Route route, ErrorHandlerFactory definition) {
+    public TransactionErrorHandlerReifier(Route route, TransactionErrorHandlerDefinition definition) {
         super(route, definition);
     }
 
     @Override
     public Processor createErrorHandler(Processor processor) throws Exception {
-        TransactionTemplate transactionTemplate = definition.getTransactionTemplate();
-        if (transactionTemplate == null) {
-            // lookup in context if no transaction template has been configured
-            LOG.debug("No TransactionTemplate configured on TransactionErrorHandlerBuilder. Will try find it in the registry.");
-
-            Map<String, TransactedPolicy> mapPolicy = findByTypeWithName(TransactedPolicy.class);
-            if (mapPolicy != null && mapPolicy.size() == 1) {
-                TransactedPolicy policy = mapPolicy.values().iterator().next();
-                if (policy instanceof SpringTransactionPolicy) {
-                    transactionTemplate = ((SpringTransactionPolicy) policy).getTransactionTemplate();
-                }
-            }
+        // must have a transaction template
+        TransactionTemplate transactionTemplate = resolveTransactionTemplate(definition, camelContext);
+        ObjectHelper.notNull(transactionTemplate, "transactionTemplate", this);
 
-            if (transactionTemplate == null) {
-                TransactedPolicy policy = lookupByNameAndType(PROPAGATION_REQUIRED, TransactedPolicy.class);
-                if (policy instanceof SpringTransactionPolicy) {
-                    transactionTemplate = ((SpringTransactionPolicy) policy).getTransactionTemplate();
-                }
+        // optimize to use shared default instance if using out of the box settings
+        RedeliveryPolicy redeliveryPolicy = resolveRedeliveryPolicy(definition, camelContext);
+        CamelLogger logger = resolveLogger(definition, camelContext);
+        LoggingLevel rollbackLoggingLevel = resolveRollbackLoggingLevel(definition, camelContext);
+
+        TransactionErrorHandler answer = new TransactionErrorHandler(
+                camelContext, processor, logger,
+                getProcessor(definition.getOnRedeliveryProcessor(), definition.getOnRedeliveryRef()),
+                redeliveryPolicy,
+                transactionTemplate,
+                resolveRetryWhilePolicy(definition, camelContext),
+                getExecutorService(definition.getExecutorServiceBean(), definition.getExecutorServiceRef()),
+                rollbackLoggingLevel,
+                getProcessor(definition.getOnExceptionOccurredProcessor(), definition.getOnExceptionOccurredRef()));
+        // configure error handler before we can use it
+        configure(answer);
+        return answer;
+    }
+
+    private TransactionTemplate resolveTransactionTemplate(
+            TransactionErrorHandlerDefinition definition, CamelContext camelContext) {
+
+        String ref = definition.getTransactionTemplateRef();
+        if (ref != null) {
+            return mandatoryLookup(ref, TransactionTemplate.class);
+        }
+
+        // lookup in context if no transaction template has been configured
+        LOG.debug("No TransactionTemplate configured on TransactionErrorHandlerBuilder. Will try find it in the registry.");
+
+        TransactionTemplate answer = null;
+        Map<String, TransactedPolicy> mapPolicy = findByTypeWithName(TransactedPolicy.class);
+        if (mapPolicy != null && mapPolicy.size() == 1) {
+            TransactedPolicy policy = mapPolicy.values().iterator().next();
+            if (policy instanceof SpringTransactionPolicy) {
+                answer = ((SpringTransactionPolicy) policy).getTransactionTemplate();
             }
+        }
 
-            if (transactionTemplate == null) {
-                Map<String, TransactionTemplate> mapTemplate = findByTypeWithName(TransactionTemplate.class);
-                if (mapTemplate == null || mapTemplate.isEmpty()) {
-                    LOG.trace("No TransactionTemplate found in registry.");
-                } else if (mapTemplate.size() == 1) {
-                    transactionTemplate = mapTemplate.values().iterator().next();
-                } else {
-                    LOG.debug("Found {} TransactionTemplate in registry. Cannot determine which one to use. "
-                              + "Please configure a TransactionTemplate on the TransactionErrorHandlerBuilder",
-                            mapTemplate.size());
-                }
+        if (answer == null) {
+            TransactedPolicy policy = lookupByNameAndType(PROPAGATION_REQUIRED, TransactedPolicy.class);
+            if (policy instanceof SpringTransactionPolicy) {
+                answer = ((SpringTransactionPolicy) policy).getTransactionTemplate();
             }
+        }
 
-            if (transactionTemplate == null) {
-                Map<String, PlatformTransactionManager> mapManager = findByTypeWithName(PlatformTransactionManager.class);
-                if (mapManager == null || mapManager.isEmpty()) {
-                    LOG.trace("No PlatformTransactionManager found in registry.");
-                } else if (mapManager.size() == 1) {
-                    transactionTemplate = new TransactionTemplate(mapManager.values().iterator().next());
-                } else {
-                    LOG.debug(
-                            "Found {} PlatformTransactionManager in registry. Cannot determine which one to use for TransactionTemplate. "
-                              + "Please configure a TransactionTemplate on the TransactionErrorHandlerBuilder",
-                            mapManager.size());
-                }
+        if (answer == null) {
+            Map<String, TransactionTemplate> mapTemplate = findByTypeWithName(TransactionTemplate.class);
+            if (mapTemplate == null || mapTemplate.isEmpty()) {
+                LOG.trace("No TransactionTemplate found in registry.");
+            } else if (mapTemplate.size() == 1) {
+                answer = mapTemplate.values().iterator().next();
+            } else {
+                LOG.debug("Found {} TransactionTemplate in registry. Cannot determine which one to use. "
+                          + "Please configure a TransactionTemplate on the TransactionErrorHandlerBuilder",
+                        mapTemplate.size());
             }
+        }
 
-            if (transactionTemplate != null) {
-                LOG.debug("Found TransactionTemplate in registry to use: {}", transactionTemplate);
+        if (answer == null) {
+            Map<String, PlatformTransactionManager> mapManager = findByTypeWithName(PlatformTransactionManager.class);
+            if (mapManager == null || mapManager.isEmpty()) {
+                LOG.trace("No PlatformTransactionManager found in registry.");
+            } else if (mapManager.size() == 1) {
+                answer = new TransactionTemplate(mapManager.values().iterator().next());
+            } else {
+                LOG.debug(
+                        "Found {} PlatformTransactionManager in registry. Cannot determine which one to use for TransactionTemplate. "
+                          + "Please configure a TransactionTemplate on the TransactionErrorHandlerBuilder",
+                        mapManager.size());
             }
         }
 
-        ObjectHelper.notNull(transactionTemplate, "transactionTemplate", this);
+        if (answer != null) {
+            LOG.debug("Found TransactionTemplate in registry to use: {}", answer);
+        }
+        return answer;
+    }
+
+    private CamelLogger resolveLogger(TransactionErrorHandlerDefinition definition, CamelContext camelContext) {
+        CamelLogger answer = definition.getLoggerBean();
+        if (answer == null && definition.getLoggerRef() != null) {
+            answer = mandatoryLookup(definition.getLoggerRef(), CamelLogger.class);
+        }
+        if (answer == null) {
+            answer = new CamelLogger(LoggerFactory.getLogger(TransactionErrorHandler.class), LoggingLevel.ERROR);
+        }
+        if (definition.getLevel() != null) {
+            answer.setLevel(definition.getLevel());
+        }
+        return answer;
+    }
+
+    private LoggingLevel resolveRollbackLoggingLevel(TransactionErrorHandlerDefinition definition, CamelContext camelContext) {
+        LoggingLevel answer = LoggingLevel.WARN;
+        if (definition.getRollbackLoggingLevel() != null) {
+            answer = parse(LoggingLevel.class, definition.getRollbackLoggingLevel());
+        }
+        return answer;
+    }
+
+    private RedeliveryPolicy resolveRedeliveryPolicy(TransactionErrorHandlerDefinition definition, CamelContext camelContext) {
+        RedeliveryPolicy answer = null;
+        RedeliveryPolicyDefinition def = definition.getRedeliveryPolicy();
+        if (def == null && definition.getRedeliveryPolicyRef() != null) {
+            // ref may point to a definition
+            def = lookupByNameAndType(definition.getRedeliveryPolicyRef(), RedeliveryPolicyDefinition.class);
+        }
+        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;
+    }
+
+    private Predicate resolveRetryWhilePolicy(TransactionErrorHandlerDefinition 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);
+        }
 
-        TransactionErrorHandler answer = new TransactionErrorHandler(
-                camelContext, processor,
-                definition.getLogger(), definition.getOnRedelivery(),
-                definition.getRedeliveryPolicy(), transactionTemplate,
-                definition.getRetryWhilePolicy(camelContext),
-                getExecutorService(definition.getExecutorService(), definition.getExecutorServiceRef()),
-                definition.getRollbackLoggingLevel(), definition.getOnExceptionOccurred());
-        // configure error handler before we can use it
-        configure(answer);
         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 = lookupByNameAndType(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-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyDeadLetterChannelReifier.java
similarity index 92%
rename from core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java
rename to core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyDeadLetterChannelReifier.java
index 9212ab9bc90..598012ceb19 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyDeadLetterChannelReifier.java
@@ -28,10 +28,13 @@ import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
 import org.apache.camel.spi.CamelLogger;
 import org.apache.camel.util.ObjectHelper;
 
+/**
+ * Legacy error handler for XML DSL in camel-spring-xml/camel-blueprint
+ */
 @Deprecated
-public class DeadLetterChannelReifier extends DefaultErrorHandlerReifier<DeadLetterChannelProperties> {
+public class LegacyDeadLetterChannelReifier extends LegacyDefaultErrorHandlerReifier<DeadLetterChannelProperties> {
 
-    public DeadLetterChannelReifier(Route route, ErrorHandlerFactory definition) {
+    public LegacyDeadLetterChannelReifier(Route route, ErrorHandlerFactory definition) {
         super(route, definition);
     }
 
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyDefaultErrorHandlerReifier.java
similarity index 93%
rename from core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java
rename to core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyDefaultErrorHandlerReifier.java
index 400919a16a7..5b368436b66 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyDefaultErrorHandlerReifier.java
@@ -28,10 +28,13 @@ import org.apache.camel.spi.CamelLogger;
 import org.apache.camel.spi.ExecutorServiceManager;
 import org.apache.camel.spi.ThreadPoolProfile;
 
+/**
+ * Legacy error handler for XML DSL in camel-spring-xml/camel-blueprint
+ */
 @Deprecated
-public class DefaultErrorHandlerReifier<T extends DefaultErrorHandlerProperties> extends ErrorHandlerReifier<T> {
+public class LegacyDefaultErrorHandlerReifier<T extends DefaultErrorHandlerProperties> extends ErrorHandlerReifier<T> {
 
-    public DefaultErrorHandlerReifier(Route route, ErrorHandlerFactory definition) {
+    public LegacyDefaultErrorHandlerReifier(Route route, ErrorHandlerFactory definition) {
         super(route, (T) definition);
     }
 
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyErrorHandlerRefReifier.java
similarity index 88%
rename from core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java
rename to core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyErrorHandlerRefReifier.java
index e5fadb1b85e..aa6ef97e4cf 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyErrorHandlerRefReifier.java
@@ -24,10 +24,13 @@ import org.apache.camel.model.errorhandler.ErrorHandlerHelper;
 import org.apache.camel.model.errorhandler.ErrorHandlerRefProperties;
 import org.apache.camel.util.ObjectHelper;
 
+/**
+ * Legacy error handler for XML DSL in camel-spring-xml/camel-blueprint
+ */
 @Deprecated
-public class ErrorHandlerRefReifier extends ErrorHandlerReifier<ErrorHandlerRefProperties> {
+public class LegacyErrorHandlerRefReifier extends ErrorHandlerReifier<ErrorHandlerRefProperties> {
 
-    public ErrorHandlerRefReifier(Route route, ErrorHandlerFactory definition) {
+    public LegacyErrorHandlerRefReifier(Route route, ErrorHandlerFactory definition) {
         super(route, (ErrorHandlerRefProperties) definition);
     }
 
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/NoErrorHandlerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyNoErrorHandlerReifier.java
similarity index 84%
rename from core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/NoErrorHandlerReifier.java
rename to core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyNoErrorHandlerReifier.java
index 9d15013322a..857b646cbe6 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/NoErrorHandlerReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/LegacyNoErrorHandlerReifier.java
@@ -23,10 +23,13 @@ import org.apache.camel.model.errorhandler.NoErrorHandlerProperties;
 import org.apache.camel.processor.errorhandler.NoErrorHandler;
 import org.apache.camel.spi.ErrorHandler;
 
+/**
+ * Legacy error handler for XML DSL in camel-spring-xml/camel-blueprint
+ */
 @Deprecated
-public class NoErrorHandlerReifier extends ErrorHandlerReifier<NoErrorHandlerProperties> {
+public class LegacyNoErrorHandlerReifier extends ErrorHandlerReifier<NoErrorHandlerProperties> {
 
-    public NoErrorHandlerReifier(Route route, ErrorHandlerFactory definition) {
+    public LegacyNoErrorHandlerReifier(Route route, ErrorHandlerFactory definition) {
         super(route, (NoErrorHandlerProperties) definition);
     }
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupportTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupportTest.java
index 72a4231c33a..e87b7e49d4b 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupportTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupportTest.java
@@ -25,7 +25,7 @@ import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.model.OnExceptionDefinition;
-import org.apache.camel.reifier.errorhandler.DefaultErrorHandlerReifier;
+import org.apache.camel.reifier.errorhandler.NewDefaultErrorHandlerReifier;
 import org.apache.camel.spi.ErrorHandler;
 import org.junit.jupiter.api.Test;
 
@@ -81,7 +81,7 @@ public class ErrorHandlerSupportTest extends ContextTestSupport {
 
     private static void addExceptionPolicy(
             ErrorHandlerSupport handlerSupport, Route route, OnExceptionDefinition exceptionType) {
-        new DefaultErrorHandlerReifier<>(route, null).addExceptionPolicy(handlerSupport, exceptionType);
+        new NewDefaultErrorHandlerReifier(route, null).addExceptionPolicy(handlerSupport, exceptionType);
     }
 
     private static String getExceptionPolicyFor(ErrorHandlerSupport support, Throwable childException, int index) {
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java
index 7889cc3c793..793e37dac33 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java
@@ -36,7 +36,7 @@ import org.apache.camel.model.OnExceptionDefinition;
 import org.apache.camel.processor.errorhandler.DefaultExceptionPolicyStrategy;
 import org.apache.camel.processor.errorhandler.ExceptionPolicy;
 import org.apache.camel.processor.errorhandler.ExceptionPolicyKey;
-import org.apache.camel.reifier.errorhandler.DefaultErrorHandlerReifier;
+import org.apache.camel.reifier.errorhandler.NewDefaultErrorHandlerReifier;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -56,7 +56,7 @@ public class DefaultExceptionPolicyStrategyTest {
     private ExceptionPolicy exceptionPolicy(Class<? extends Throwable> exceptionClass) {
         CamelContext cc = new DefaultCamelContext();
         Route context = new DefaultRoute(cc, null, null, null, null, null);
-        return new DefaultErrorHandlerReifier<>(context, null)
+        return new NewDefaultErrorHandlerReifier(context, null)
                 .createExceptionPolicy(new OnExceptionDefinition(exceptionClass));
     }