diff --git a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExist.java b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExist.java index 2e00de1e11a56..261f2504f5937 100644 --- a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExist.java +++ b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExist.java @@ -23,5 +23,5 @@ */ public enum GenericFileExist { - Override, Append, Fail, Ignore, Move + Override, Append, Fail, Ignore, Move, TryRename } diff --git a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java index bd0a24888fc94..901cfc72fdb5e 100644 --- a/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java +++ b/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java @@ -123,25 +123,32 @@ protected void processExchange(Exchange exchange, String target) throws Exceptio tempTarget = createTempFileName(exchange, target); log.trace("Writing using tempNameFile: {}", tempTarget); - - // cater for file exists option on the real target as - // the file operations code will work on the temp file - - // if an existing file already exists what should we do? - targetExists = operations.existsFile(target); - if (targetExists) { - if (endpoint.getFileExist() == GenericFileExist.Ignore) { - // ignore but indicate that the file was written - log.trace("An existing file already exists: {}. Ignore and do not override it.", target); - return; - } else if (endpoint.getFileExist() == GenericFileExist.Fail) { - throw new GenericFileOperationFailedException("File already exist: " + target + ". Cannot write new file."); - } else if (endpoint.isEagerDeleteTargetFile() && endpoint.getFileExist() == GenericFileExist.Override) { - // we override the target so we do this by deleting it so the temp file can be renamed later - // with success as the existing target file have been deleted - log.trace("Eagerly deleting existing file: {}", target); - if (!operations.deleteFile(target)) { - throw new GenericFileOperationFailedException("Cannot delete file: " + target); + + //if we should eager delete target file before deploying temporary file + if (endpoint.getFileExist() != GenericFileExist.TryRename && endpoint.isEagerDeleteTargetFile()) { + + // cater for file exists option on the real target as + // the file operations code will work on the temp file + + // if an existing file already exists what should we do? + targetExists = operations.existsFile(target); + if (targetExists) { + + log.trace("EagerDeleteTargetFile, target exists"); + + if (endpoint.getFileExist() == GenericFileExist.Ignore) { + // ignore but indicate that the file was written + log.trace("An existing file already exists: {}. Ignore and do not override it.", target); + return; + } else if (endpoint.getFileExist() == GenericFileExist.Fail) { + throw new GenericFileOperationFailedException("File already exist: " + target + ". Cannot write new file."); + } else if (endpoint.isEagerDeleteTargetFile() && endpoint.getFileExist() == GenericFileExist.Override) { + // we override the target so we do this by deleting it so the temp file can be renamed later + // with success as the existing target file have been deleted + log.trace("Eagerly deleting existing file: {}", target); + if (!operations.deleteFile(target)) { + throw new GenericFileOperationFailedException("Cannot delete file: " + target); + } } } } @@ -161,15 +168,29 @@ protected void processExchange(Exchange exchange, String target) throws Exceptio // if we did write to a temporary name then rename it to the real // name after we have written the file if (tempTarget != null) { - - // if we should not eager delete the target file then do it now just before renaming - if (!endpoint.isEagerDeleteTargetFile() && targetExists - && endpoint.getFileExist() == GenericFileExist.Override) { - // we override the target so we do this by deleting it so the temp file can be renamed later - // with success as the existing target file have been deleted - log.trace("Deleting existing file: {}", target); - if (!operations.deleteFile(target)) { - throw new GenericFileOperationFailedException("Cannot delete file: " + target); + // if we did not eager delete the target file + if (endpoint.getFileExist() != GenericFileExist.TryRename && !endpoint.isEagerDeleteTargetFile()) { + + // if an existing file already exists what should we do? + targetExists = operations.existsFile(target); + if (targetExists) { + + log.trace("Not using EagerDeleteTargetFile, target exists"); + + if (endpoint.getFileExist() == GenericFileExist.Ignore) { + // ignore but indicate that the file was written + log.trace("An existing file already exists: {}. Ignore and do not override it.", target); + return; + } else if (endpoint.getFileExist() == GenericFileExist.Fail) { + throw new GenericFileOperationFailedException("File already exist: " + target + ". Cannot write new file."); + } else if (endpoint.getFileExist() == GenericFileExist.Override) { + // we override the target so we do this by deleting it so the temp file can be renamed later + // with success as the existing target file have been deleted + log.trace("Deleting existing file: {}", target); + if (!operations.deleteFile(target)) { + throw new GenericFileOperationFailedException("Cannot delete file: " + target); + } + } } } diff --git a/camel-core/src/test/java/org/apache/camel/component/file/FileProducerFileExistTryRenameTest.java b/camel-core/src/test/java/org/apache/camel/component/file/FileProducerFileExistTryRenameTest.java new file mode 100644 index 0000000000000..dd72304cf5980 --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/component/file/FileProducerFileExistTryRenameTest.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.component.file; + +import java.util.Locale; + +import junit.framework.TestResult; +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.TestSupport; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; + +/** + * @version + */ +public class FileProducerFileExistTryRenameTest extends ContextTestSupport { + + @Override + protected void setUp() throws Exception { + deleteDirectory("target/file"); + super.setUp(); + template.sendBodyAndHeader("file://target/file", "Hello World", Exchange.FILE_NAME, "hello.txt"); + } + + + public void testIgnore() throws Exception { + + // Does not work on Windows + if(TestSupport.isPlatform("windows")) + return; + + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedBodiesReceived("Bye World"); + mock.expectedFileExists("target/file/hello.txt", "Bye World"); + + template.sendBodyAndHeader("file://target/file?fileExist=TryRename&tempPrefix=tmp", "Bye World", Exchange.FILE_NAME, "hello.txt"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("file://target/file?noop=true&delay=1000").convertBodyTo(String.class).to("mock:result"); + } + }; + } +} \ No newline at end of file