All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.spring.spi.TransactionErrorHandlerReifier Maven / Gradle / Ivy

There is a newer version: 4.9.0
Show newest version
/*
 * 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.SpringTransactionErrorHandlerDefinition;
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.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 TransactionErrorHandlerReifier extends ErrorHandlerReifier {

    private static final Logger LOG = LoggerFactory.getLogger(TransactionErrorHandlerReifier.class);

    public TransactionErrorHandlerReifier(Route route, SpringTransactionErrorHandlerDefinition definition) {
        super(route, definition);
    }

    @Override
    public Processor createErrorHandler(Processor processor) throws Exception {
        // must have a transaction template
        TransactionTemplate transactionTemplate = resolveTransactionTemplate(definition);
        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);
        LoggingLevel rollbackLoggingLevel = resolveRollbackLoggingLevel(definition);

        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) {

        TransactionTemplate answer = null;

        SpringTransactionPolicy policy = (SpringTransactionPolicy) definition.getTransactedPolicy();
        if (policy == null && definition.getTransactedPolicyRef() != null) {
            policy = mandatoryLookup(definition.getTransactedPolicyRef(), SpringTransactionPolicy.class);
        }
        if (policy != null) {
            answer = policy.getTransactionTemplate();
        }

        if (answer == null) {
            Map mapPolicy = findByTypeWithName(SpringTransactionPolicy.class);
            if (mapPolicy != null && mapPolicy.size() == 1) {
                policy = mapPolicy.values().iterator().next();
                if (policy != null) {
                    answer = policy.getTransactionTemplate();
                }
            }
        }

        if (answer == null) {
            policy = lookupByNameAndType(PROPAGATION_REQUIRED, SpringTransactionPolicy.class);
            if (policy != null) {
                answer = policy.getTransactionTemplate();
            }
        }

        if (answer == null) {
            Map 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 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) {
        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(parse(LoggingLevel.class, definition.getLevel()));
        }
        return answer;
    }

    private LoggingLevel resolveRollbackLoggingLevel(TransactionErrorHandlerDefinition definition) {
        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;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy