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 2014/04/03 09:57:51 UTC

[1/2] git commit: CAMEL-6458: Add renameUsingCopy option to File Component

Repository: camel
Updated Branches:
  refs/heads/camel-2.13.x 4e9e1a706 -> 94e7c6d3b


CAMEL-6458: Add renameUsingCopy option to File Component

The new renameUsingCopy option controls whether rename operations are
performed using a copy and delete strategy. This is primarily used in
environments where the regular rename operation is unreliable (e.g.
across different file systems and networks).

Signed-off-by: Gregor Zurowski <gr...@zurowski.org>


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3e5221cf
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3e5221cf
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3e5221cf

Branch: refs/heads/camel-2.13.x
Commit: 3e5221cf1b1279ced34cb640031cde4a70647a0b
Parents: 4e9e1a7
Author: Gregor Zurowski <gr...@zurowski.org>
Authored: Sat Mar 29 14:33:04 2014 -0400
Committer: Claus Ibsen <da...@apache.org>
Committed: Thu Apr 3 10:01:09 2014 +0200

----------------------------------------------------------------------
 .../camel/component/file/FileEndpoint.java      | 10 ++++++
 .../camel/component/file/FileOperations.java    |  9 ++++-
 .../java/org/apache/camel/util/FileUtil.java    | 36 ++++++++++++++++----
 3 files changed, 48 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/3e5221cf/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java b/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java
index 21f7fdb..4e0a920 100644
--- a/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java
+++ b/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java
@@ -41,6 +41,8 @@ public class FileEndpoint extends GenericFileEndpoint<File> {
     @UriParam
     private boolean copyAndDeleteOnRenameFail = true;
     @UriParam
+    private boolean renameUsingCopy;
+    @UriParam
     private boolean forceWrites = true;
 
     public FileEndpoint() {
@@ -174,6 +176,14 @@ public class FileEndpoint extends GenericFileEndpoint<File> {
         this.copyAndDeleteOnRenameFail = copyAndDeleteOnRenameFail;
     }
 
+    public boolean isRenameUsingCopy() {
+        return renameUsingCopy;
+    }
+
+    public void setRenameUsingCopy(boolean renameUsingCopy) {
+        this.renameUsingCopy = renameUsingCopy;
+    }
+
     public boolean isForceWrites() {
         return forceWrites;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/3e5221cf/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java b/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java
index a1d34ae..2d9f72d 100644
--- a/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java
+++ b/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java
@@ -64,13 +64,20 @@ public class FileOperations implements GenericFileOperations<File> {
     }
 
     public boolean renameFile(String from, String to) throws GenericFileOperationFailedException {
+        boolean renamed = false;
         File file = new File(from);
         File target = new File(to);
         try {
-            return FileUtil.renameFile(file, target, endpoint.isCopyAndDeleteOnRenameFail());
+            if (endpoint.isRenameUsingCopy()) {
+                renamed = FileUtil.renameFileUsingCopy(file, target);
+            } else {
+                renamed = FileUtil.renameFile(file, target, endpoint.isCopyAndDeleteOnRenameFail());
+            }
         } catch (IOException e) {
             throw new GenericFileOperationFailedException("Error renaming file from " + from + " to " + to, e);
         }
+        
+        return renamed;
     }
 
     public boolean existsFile(String name) throws GenericFileOperationFailedException {

http://git-wip-us.apache.org/repos/asf/camel/blob/3e5221cf/camel-core/src/main/java/org/apache/camel/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/FileUtil.java b/camel-core/src/main/java/org/apache/camel/util/FileUtil.java
index d51330f..6376c44 100644
--- a/camel-core/src/main/java/org/apache/camel/util/FileUtil.java
+++ b/camel-core/src/main/java/org/apache/camel/util/FileUtil.java
@@ -425,12 +425,7 @@ public final class FileUtil {
         if (!renamed && copyAndDeleteOnRenameFail) {
             // now do a copy and delete as all rename attempts failed
             LOG.debug("Cannot rename file from: {} to: {}, will now use a copy/delete approach instead", from, to);
-            copyFile(from, to);
-            if (!deleteFile(from)) {
-                throw new IOException("Renaming file from: " + from + " to: " + to + " failed due cannot delete from file: " + from + " after copy succeeded");
-            } else {
-                renamed = true;
-            }
+            renameFileUsingCopy(from, to);
         }
 
         if (LOG.isDebugEnabled() && count > 0) {
@@ -439,6 +434,35 @@ public final class FileUtil {
         return renamed;
     }
 
+    /**
+     * Rename file using copy and delete strategy. This is primarily used in
+     * environments where the regular rename operation is unreliable.
+     * 
+     * @param from the file to be renamed
+     * @param to the new target file
+     * @return <tt>true</tt> if the file was renamed successfully, otherwise <tt>false</tt>
+     * @throws IOException If an I/O error occurs during copy or delete operations.
+     */
+    public static boolean renameFileUsingCopy(File from, File to) throws IOException {
+        // do not try to rename non existing files
+        if (!from.exists()) {
+            return false;
+        }
+
+        boolean renamed = false;
+
+        LOG.debug("Rename file '{}' to '{}' using copy/delete strategy.", from, to);
+
+        copyFile(from, to);
+        if (!deleteFile(from)) {
+            throw new IOException("Renaming file from '" + from + "' to '" + to + "' failed: Cannot delete file '" + from + "' after copy succeeded");
+        } else {
+            renamed = true;
+        }
+
+        return renamed;
+    }
+
     public static void copyFile(File from, File to) throws IOException {
         FileChannel in = new FileInputStream(from).getChannel();
         FileChannel out = new FileOutputStream(to).getChannel();


[2/2] git commit: CAMEL-6458: Add tests for renameUsingCopy option

Posted by da...@apache.org.
CAMEL-6458: Add tests for renameUsingCopy option

Signed-off-by: Gregor Zurowski <gr...@zurowski.org>


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/94e7c6d3
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/94e7c6d3
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/94e7c6d3

Branch: refs/heads/camel-2.13.x
Commit: 94e7c6d3b7c94fc599f9db900b12a885b248b9fb
Parents: 3e5221c
Author: Gregor Zurowski <gr...@zurowski.org>
Authored: Sat Mar 29 14:48:10 2014 -0400
Committer: Claus Ibsen <da...@apache.org>
Committed: Thu Apr 3 10:01:15 2014 +0200

----------------------------------------------------------------------
 .../file/FileProducerRenameUsingCopyTest.java   | 56 ++++++++++++++++++++
 .../org/apache/camel/util/FileUtilTest.java     | 11 ++++
 2 files changed, 67 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/94e7c6d3/camel-core/src/test/java/org/apache/camel/component/file/FileProducerRenameUsingCopyTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/component/file/FileProducerRenameUsingCopyTest.java b/camel-core/src/test/java/org/apache/camel/component/file/FileProducerRenameUsingCopyTest.java
new file mode 100644
index 0000000..c5dbfb6
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/component/file/FileProducerRenameUsingCopyTest.java
@@ -0,0 +1,56 @@
+/**
+ * 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.io.File;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+
+public class FileProducerRenameUsingCopyTest extends ContextTestSupport {
+
+    @Override
+    protected void setUp() throws Exception {
+        deleteDirectory("target/file");
+        super.setUp();
+    }
+
+    public void testMove() throws Exception {
+        final String body = "Hello Camel";
+        template.sendBodyAndHeader("file://target/file", body, Exchange.FILE_NAME, "hello.txt");
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.expectedFileExists("target/file/done/hello.txt", body);
+        assertMockEndpointsSatisfied();
+
+        assertTrue("File not copied", new File("target/file/done/hello.txt").exists());
+        assertFalse("File not deleted", new File("target/file/hello.txt").exists());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("file://target/file?renameUsingCopy=true&move=done").convertBodyTo(String.class).to("mock:result");
+            }
+        };
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/94e7c6d3/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java b/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java
index 1ef3b1e..89446e9 100644
--- a/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/FileUtilTest.java
@@ -221,4 +221,15 @@ public class FileUtilTest extends TestCase {
         assertFalse(tmpDir.exists());
     }
 
+    public void testRenameUsingDelete() throws Exception {
+        File file = new File("target/foo.txt");
+        if (!file.exists()) {
+            FileUtil.createNewFile(file);
+        }
+        
+        File target = new File("target/bar.txt");
+        FileUtil.renameFileUsingCopy(file, target);
+        assertTrue("File not copied", target.exists());
+        assertFalse("File not deleted", file.exists());
+    }
 }