Author: davsclaus Date: Sun Oct 3 07:54:34 2010 New Revision: 1003927 URL: http://svn.apache.org/viewvc?rev=1003927&view=rev Log: CAMEL-3174: FTP consumers will use - change back to parent dir when polling sub folders - strategy. API change in FileOperators.
Added: camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeAbsoluteTest.java - copied, changed from r1003830, camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategyTest.java camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpServerTestSupport.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java?rev=1003927&r1=1003926&r2=1003927&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileOperations.java Sun Oct 3 07:54:34 2010 @@ -133,6 +133,10 @@ public class FileOperations implements G // noop } + public void changeToParentDirectory() throws GenericFileOperationFailedException { + // noop + } + public String getCurrentDirectory() throws GenericFileOperationFailedException { // noop return null; Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java?rev=1003927&r1=1003926&r2=1003927&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java Sun Oct 3 07:54:34 2010 @@ -105,6 +105,13 @@ public interface GenericFileOperations<T void changeCurrentDirectory(String path) throws GenericFileOperationFailedException; /** + * Change the current remote directory to the parent + * + * @throws GenericFileOperationFailedException can be thrown + */ + void changeToParentDirectory() throws GenericFileOperationFailedException; + + /** * List the files in the current directory * * @return a list of backing objects representing the files Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategyTest.java?rev=1003927&r1=1003926&r2=1003927&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategyTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategyTest.java Sun Oct 3 07:54:34 2010 @@ -82,6 +82,9 @@ public class GenericFileDeleteProcessStr public void changeCurrentDirectory(String path) throws GenericFileOperationFailedException { } + public void changeToParentDirectory() throws GenericFileOperationFailedException { + } + public List<Object> listFiles() throws GenericFileOperationFailedException { return null; } Modified: camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java?rev=1003927&r1=1003926&r2=1003927&view=diff ============================================================================== --- camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java (original) +++ camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java Sun Oct 3 07:54:34 2010 @@ -37,18 +37,22 @@ public class FtpConsumer extends RemoteF } protected boolean pollDirectory(String fileName, List<GenericFile<FTPFile>> fileList) { - // strip trailing slash - fileName = FileUtil.stripTrailingSeparator(fileName); - return pollDirectory(fileName, null, fileList); - } - - protected boolean pollDirectory(String absolutePath, String dirName, List<GenericFile<FTPFile>> fileList) { // must remember current dir so we stay in that directory after the poll String currentDir = operations.getCurrentDirectory(); - boolean answer = doPollDirectory(absolutePath, dirName, fileList); + // strip trailing slash + fileName = FileUtil.stripTrailingSeparator(fileName); + boolean answer = doPollDirectory(fileName, null, fileList); operations.changeCurrentDirectory(currentDir); + + return answer; + } + + protected boolean pollSubDirectory(String absolutePath, String dirName, List<GenericFile<FTPFile>> fileList) { + boolean answer = doPollDirectory(absolutePath, dirName, fileList); + // change back to parent directory when finished polling sub directory + operations.changeToParentDirectory(); return answer; } @@ -94,7 +98,7 @@ public class FtpConsumer extends RemoteF // recursive scan and add the sub files and folders String subDirectory = file.getName(); String path = absolutePath + "/" + subDirectory; - boolean canPollMore = pollDirectory(path, subDirectory, fileList); + boolean canPollMore = pollSubDirectory(path, subDirectory, fileList); if (!canPollMore) { return false; } Modified: camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java?rev=1003927&r1=1003926&r2=1003927&view=diff ============================================================================== --- camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java (original) +++ camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java Sun Oct 3 07:54:34 2010 @@ -500,11 +500,18 @@ public class FtpOperations implements Re return; } + // if it starts with the root path then a little special handling for that + if (path.startsWith("/") || path.startsWith("\\")) { + // change to root path + doChangeDirectory(path.substring(0, 1)); + path = path.substring(1); + } + // split into multiple dirs final String[] dirs = path.split("/|\\\\"); if (dirs == null || dirs.length == 0) { - // this is the root path + // path was just a relative single path doChangeDirectory(path); return; } @@ -516,7 +523,7 @@ public class FtpOperations implements Re } private void doChangeDirectory(String path) { - if (path == null || ".".equals(path)) { + if (path == null || ".".equals(path) || ObjectHelper.isEmpty(path)) { return; } @@ -534,6 +541,14 @@ public class FtpOperations implements Re } } + public void changeToParentDirectory() throws GenericFileOperationFailedException { + try { + client.changeToParentDirectory(); + } catch (IOException e) { + throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e); + } + } + public List<FTPFile> listFiles() throws GenericFileOperationFailedException { if (log.isTraceEnabled()) { log.trace("listFiles()"); Modified: camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java?rev=1003927&r1=1003926&r2=1003927&view=diff ============================================================================== --- camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java (original) +++ camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java Sun Oct 3 07:54:34 2010 @@ -37,31 +37,51 @@ public class SftpConsumer extends Remote } protected boolean pollDirectory(String fileName, List<GenericFile<ChannelSftp.LsEntry>> fileList) { - if (log.isTraceEnabled()) { - log.trace("pollDirectory from fileName: " + fileName); - } + // must remember current dir so we stay in that directory after the poll + String currentDir = operations.getCurrentDirectory(); - if (fileName == null) { - return true; + // strip trailing slash + fileName = FileUtil.stripTrailingSeparator(fileName); + + boolean answer = doPollDirectory(fileName, null, fileList); + + operations.changeCurrentDirectory(currentDir); + return answer; + } + + protected boolean pollSubDirectory(String absolutePath, String dirName, List<GenericFile<ChannelSftp.LsEntry>> fileList) { + boolean answer = doPollDirectory(absolutePath, dirName, fileList); + // change back to parent directory when finished polling sub directory + operations.changeToParentDirectory(); + return answer; + } + + protected boolean doPollDirectory(String absolutePath, String dirName, List<GenericFile<ChannelSftp.LsEntry>> fileList) { + if (log.isTraceEnabled()) { + log.trace("doPollDirectory from absolutePath: " + absolutePath + ", dirName: " + dirName); } // remove trailing / - fileName = FileUtil.stripTrailingSeparator(fileName); + dirName = FileUtil.stripTrailingSeparator(dirName); + String dir = ObjectHelper.isNotEmpty(dirName) ? dirName : absolutePath; + + // change into directory (to ensure most FTP servers can list files) + operations.changeCurrentDirectory(dir); if (log.isTraceEnabled()) { - log.trace("Polling directory: " + fileName); + log.trace("Polling directory: " + dir); } - List<ChannelSftp.LsEntry> files = operations.listFiles(fileName); + List<ChannelSftp.LsEntry> files = operations.listFiles(); if (files == null || files.isEmpty()) { // no files in this directory to poll if (log.isTraceEnabled()) { - log.trace("No files found in directory: " + fileName); + log.trace("No files found in directory: " + dir); } return true; } else { // we found some files if (log.isTraceEnabled()) { - log.trace("Found " + files.size() + " in directory: " + fileName); + log.trace("Found " + files.size() + " in directory: " + dir); } } @@ -73,11 +93,12 @@ public class SftpConsumer extends Remote } if (file.getAttrs().isDir()) { - RemoteFile<ChannelSftp.LsEntry> remote = asRemoteFile(fileName, file); + RemoteFile<ChannelSftp.LsEntry> remote = asRemoteFile(absolutePath, file); if (endpoint.isRecursive() && isValidFile(remote, true)) { // recursive scan and add the sub files and folders - String subDirectory = fileName + "/" + file.getFilename(); - boolean canPollMore = pollDirectory(subDirectory, fileList); + String subDirectory = file.getFilename(); + String path = absolutePath + "/" + subDirectory; + boolean canPollMore = pollSubDirectory(path, subDirectory, fileList); if (!canPollMore) { return false; } @@ -85,7 +106,7 @@ public class SftpConsumer extends Remote // we cannot use file.getAttrs().isLink on Windows, so we dont invoke the method // just assuming its a file we should poll } else { - RemoteFile<ChannelSftp.LsEntry> remote = asRemoteFile(fileName, file); + RemoteFile<ChannelSftp.LsEntry> remote = asRemoteFile(absolutePath, file); if (isValidFile(remote, false)) { if (isInProgress(remote)) { if (log.isTraceEnabled()) { @@ -102,7 +123,7 @@ public class SftpConsumer extends Remote return true; } - private RemoteFile<ChannelSftp.LsEntry> asRemoteFile(String directory, ChannelSftp.LsEntry file) { + private RemoteFile<ChannelSftp.LsEntry> asRemoteFile(String absolutePath, ChannelSftp.LsEntry file) { RemoteFile<ChannelSftp.LsEntry> answer = new RemoteFile<ChannelSftp.LsEntry>(); answer.setEndpointPath(endpointPath); @@ -116,7 +137,8 @@ public class SftpConsumer extends Remote answer.setAbsolute(false); // create a pseudo absolute name - String absoluteFileName = (ObjectHelper.isNotEmpty(directory) ? directory + "/" : "") + file.getFilename(); + String dir = FileUtil.stripTrailingSeparator(absolutePath); + String absoluteFileName = dir + "/" + file.getFilename(); answer.setAbsoluteFilePath(absoluteFileName); // the relative filename, skip the leading endpoint configured path Modified: camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java?rev=1003927&r1=1003926&r2=1003927&view=diff ============================================================================== --- camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java (original) +++ camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java Sun Oct 3 07:54:34 2010 @@ -347,11 +347,18 @@ public class SftpOperations implements R return; } + // if it starts with the root path then a little special handling for that + if (path.startsWith("/") || path.startsWith("\\")) { + // change to root path + doChangeDirectory(path.substring(0, 1)); + path = path.substring(1); + } + // split into multiple dirs final String[] dirs = path.split("/|\\\\"); if (dirs == null || dirs.length == 0) { - // this is the root path + // path was just a relative single path doChangeDirectory(path); return; } @@ -363,7 +370,7 @@ public class SftpOperations implements R } private void doChangeDirectory(String path) { - if (path == null || ".".equals(path)) { + if (path == null || ".".equals(path) || ObjectHelper.isEmpty(path)) { return; } @@ -377,6 +384,18 @@ public class SftpOperations implements R } } + public void changeToParentDirectory() throws GenericFileOperationFailedException { + String current = getCurrentDirectory(); + + String parent = FileUtil.compactPath(current + "/.."); + // must start with absolute + if (!parent.startsWith("/")) { + parent = "/" + parent; + } + + changeCurrentDirectory(parent); + } + public List<ChannelSftp.LsEntry> listFiles() throws GenericFileOperationFailedException { return listFiles("."); } Modified: camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpServerTestSupport.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpServerTestSupport.java?rev=1003927&r1=1003926&r2=1003927&view=diff ============================================================================== --- camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpServerTestSupport.java (original) +++ camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpServerTestSupport.java Sun Oct 3 07:54:34 2010 @@ -35,7 +35,7 @@ import org.junit.Before; */ public class SftpServerTestSupport extends BaseServerTestSupport { - protected static final String FTP_ROOT_DIR = "./res/home/"; + protected static final String FTP_ROOT_DIR = "res/home/"; protected SshServer sshd; protected boolean canTest; Copied: camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeAbsoluteTest.java (from r1003830, camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeAbsoluteTest.java?p2=camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeAbsoluteTest.java&p1=camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeTest.java&r1=1003830&r2=1003927&rev=1003927&view=diff ============================================================================== --- camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeTest.java (original) +++ camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeAbsoluteTest.java Sun Oct 3 07:54:34 2010 @@ -19,15 +19,17 @@ package org.apache.camel.component.file. import org.apache.camel.Exchange; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; +import org.junit.Ignore; import org.junit.Test; /** * @version $Revision$ */ -public class SftpSimpleConsumeTest extends SftpServerTestSupport { +...@ignore("Absolute do not work with Apache SSHD") +public class SftpSimpleConsumeAbsoluteTest extends SftpServerTestSupport { @Test - public void testSftpSimpleConsume() throws Exception { + public void testSftpSimpleConsumeAbsolute() throws Exception { if (!canTest()) { return; } @@ -35,7 +37,7 @@ public class SftpSimpleConsumeTest exten String expected = "Hello World"; // create file using regular file - template.sendBodyAndHeader("file://" + FTP_ROOT_DIR, expected, Exchange.FILE_NAME, "hello.txt"); + template.sendBodyAndHeader("file:////tmp", expected, Exchange.FILE_NAME, "hello.txt"); MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedMessageCount(1); @@ -51,7 +53,7 @@ public class SftpSimpleConsumeTest exten return new RouteBuilder() { @Override public void configure() throws Exception { - from("sftp://localhost:" + getPort() + "/" + FTP_ROOT_DIR + "?username=admin&password=admin&delay=10s&disconnect=true") + from("sftp://localhost:" + getPort() + "//tmp?username=admin&password=admin&delay=10s&disconnect=true") .routeId("foo").noAutoStartup() .to("mock:result"); }