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

org.apache.camel.component.file.strategy.FileIdempotentRepositoryReadLockStrategy Maven / Gradle / Ivy

There is a newer version: 4.6.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.component.file.strategy;

import java.io.File;

import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.Exchange;
import org.apache.camel.LoggingLevel;
import org.apache.camel.component.file.GenericFile;
import org.apache.camel.component.file.GenericFileEndpoint;
import org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy;
import org.apache.camel.component.file.GenericFileOperations;
import org.apache.camel.spi.IdempotentRepository;
import org.apache.camel.support.ServiceSupport;
import org.apache.camel.util.CamelLogger;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A file read lock that uses an {@link org.apache.camel.spi.IdempotentRepository} as the lock strategy. This allows to plugin and use existing
 * idempotent repositories that for example supports clustering. The other read lock strategies that are using marker files or file locks,
 * are not guaranteed to work in clustered setup with various platform and file systems.
 */
public class FileIdempotentRepositoryReadLockStrategy extends ServiceSupport implements GenericFileExclusiveReadLockStrategy, CamelContextAware {

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

    private GenericFileEndpoint endpoint;
    private LoggingLevel readLockLoggingLevel = LoggingLevel.DEBUG;
    private CamelContext camelContext;
    private IdempotentRepository idempotentRepository;
    private boolean removeOnRollback = true;
    private boolean removeOnCommit;

    @Override
    public void prepareOnStartup(GenericFileOperations operations, GenericFileEndpoint endpoint) throws Exception {
        this.endpoint = endpoint;
        LOG.info("Using FileIdempotentRepositoryReadLockStrategy: {} on endpoint: {}", idempotentRepository, endpoint);
    }

    @Override
    public boolean acquireExclusiveReadLock(GenericFileOperations operations, GenericFile file, Exchange exchange) throws Exception {
        // in clustered mode then another node may have processed the file so we must check here again if the file exists
        File path = file.getFile();
        if (!path.exists()) {
            return false;
        }

        // check if we can begin on this file
        String key = asKey(file);
        boolean answer = idempotentRepository.add(key);
        if (!answer) {
            // another node is processing the file so skip
            CamelLogger.log(LOG, readLockLoggingLevel, "Cannot acquire read lock. Will skip the file: " + file);
        }
        return answer;
    }

    @Override
    public void releaseExclusiveReadLockOnAbort(GenericFileOperations operations, GenericFile file, Exchange exchange) throws Exception {
        // noop
    }

    @Override
    public void releaseExclusiveReadLockOnRollback(GenericFileOperations operations, GenericFile file, Exchange exchange) throws Exception {
        String key = asKey(file);
        if (removeOnRollback) {
            idempotentRepository.remove(key);
        } else {
            // okay we should not remove then confirm it instead
            idempotentRepository.confirm(key);
        }
    }

    @Override
    public void releaseExclusiveReadLockOnCommit(GenericFileOperations operations, GenericFile file, Exchange exchange) throws Exception {
        String key = asKey(file);
        if (removeOnCommit) {
            idempotentRepository.remove(key);
        } else {
            // confirm on commit
            idempotentRepository.confirm(key);
        }
    }

    public void setTimeout(long timeout) {
        // noop
    }

    public void setCheckInterval(long checkInterval) {
        // noop
    }

    public void setReadLockLoggingLevel(LoggingLevel readLockLoggingLevel) {
        this.readLockLoggingLevel = readLockLoggingLevel;
    }

    public void setMarkerFiler(boolean markerFile) {
        // noop
    }

    public void setDeleteOrphanLockFiles(boolean deleteOrphanLockFiles) {
        // noop
    }

    public CamelContext getCamelContext() {
        return camelContext;
    }

    public void setCamelContext(CamelContext camelContext) {
        this.camelContext = camelContext;
    }

    /**
     * The idempotent repository to use as the store for the read locks.
     */
    public IdempotentRepository getIdempotentRepository() {
        return idempotentRepository;
    }

    /**
     * The idempotent repository to use as the store for the read locks.
     */
    public void setIdempotentRepository(IdempotentRepository idempotentRepository) {
        this.idempotentRepository = idempotentRepository;
    }

    /**
     * Whether to remove the file from the idempotent repository when doing a rollback.
     * 

* By default this is true. */ public boolean isRemoveOnRollback() { return removeOnRollback; } /** * Whether to remove the file from the idempotent repository when doing a rollback. *

* By default this is true. */ public void setRemoveOnRollback(boolean removeOnRollback) { this.removeOnRollback = removeOnRollback; } /** * Whether to remove the file from the idempotent repository when doing a commit. *

* By default this is false. */ public boolean isRemoveOnCommit() { return removeOnCommit; } /** * Whether to remove the file from the idempotent repository when doing a commit. *

* By default this is false. */ public void setRemoveOnCommit(boolean removeOnCommit) { this.removeOnCommit = removeOnCommit; } protected String asKey(GenericFile file) { // use absolute file path as default key, but evaluate if an expression key was configured String key = file.getAbsoluteFilePath(); if (endpoint.getIdempotentKey() != null) { Exchange dummy = endpoint.createExchange(file); key = endpoint.getIdempotentKey().evaluate(dummy, String.class); } return key; } @Override protected void doStart() throws Exception { ObjectHelper.notNull(camelContext, "camelContext", this); ObjectHelper.notNull(idempotentRepository, "idempotentRepository", this); // ensure the idempotent repository is added as a service so CamelContext will stop the repo when it shutdown itself camelContext.addService(idempotentRepository, true); } @Override protected void doStop() throws Exception { // noop } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy