From bc4b77d5e6bf87053cb228fef57c038db6d28e24 Mon Sep 17 00:00:00 2001 From: Carsten Erker Date: Wed, 20 Mar 2013 15:39:41 +0100 Subject: [PATCH 1/4] CAMEL-6137: Added a new option "upload" to the producer which works according to option "download" in the FTP consumer: If false, no file will be uploaded, no temporary file will be created, no done file will be created, but the Exchange.FILE_NAME_PRODUCED header will be set. Defaults to true. --- .../component/file/GenericFileProducer.java | 153 ++++++++++-------- .../file/remote/RemoteFileEndpoint.java | 9 ++ .../file/remote/RemoteFileProducer.java | 5 + .../remote/FtpProducerSiteCommandTest.java | 33 ++-- .../file/remote/FtpServerTestSupport.java | 2 +- 5 files changed, 121 insertions(+), 81 deletions(-) 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..9d82b56d6e504 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 @@ -113,91 +113,93 @@ protected void processExchange(Exchange exchange, String target) throws Exceptio try { preWriteCheck(); - // should we write to a temporary name and then afterwards rename to real target - boolean writeAsTempAndRename = ObjectHelper.isNotEmpty(endpoint.getTempFileName()); - String tempTarget = null; - // remember if target exists to avoid checking twice - Boolean targetExists = null; - if (writeAsTempAndRename) { - // compute temporary name with the temp prefix - 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 (isUploadFile()) { + // should we write to a temporary name and then afterwards rename to real target + boolean writeAsTempAndRename = ObjectHelper.isNotEmpty(endpoint.getTempFileName()); + String tempTarget = null; + // remember if target exists to avoid checking twice + Boolean targetExists = null; + if (writeAsTempAndRename) { + // compute temporary name with the temp prefix + 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); + } } } - } - // delete any pre existing temp file - if (operations.existsFile(tempTarget)) { - log.trace("Deleting existing temp file: {}", tempTarget); - if (!operations.deleteFile(tempTarget)) { - throw new GenericFileOperationFailedException("Cannot delete file: " + tempTarget); + // delete any pre existing temp file + if (operations.existsFile(tempTarget)) { + log.trace("Deleting existing temp file: {}", tempTarget); + if (!operations.deleteFile(tempTarget)) { + throw new GenericFileOperationFailedException("Cannot delete file: " + tempTarget); + } } } - } - // write/upload the file - writeFile(exchange, tempTarget != null ? tempTarget : target); - - // 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); + // write/upload the file + writeFile(exchange, tempTarget != null ? tempTarget : target); + + // 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); + } } - } - // now we are ready to rename the temp file to the target file - log.trace("Renaming file: [{}] to: [{}]", tempTarget, target); - boolean renamed = operations.renameFile(tempTarget, target); - if (!renamed) { - throw new GenericFileOperationFailedException("Cannot rename file from: " + tempTarget + " to: " + target); + // now we are ready to rename the temp file to the target file + log.trace("Renaming file: [{}] to: [{}]", tempTarget, target); + boolean renamed = operations.renameFile(tempTarget, target); + if (!renamed) { + throw new GenericFileOperationFailedException("Cannot rename file from: " + tempTarget + " to: " + target); + } } - } - // any done file to write? - if (endpoint.getDoneFileName() != null) { - String doneFileName = endpoint.createDoneFileName(target); - ObjectHelper.notEmpty(doneFileName, "doneFileName", endpoint); + // any done file to write? + if (endpoint.getDoneFileName() != null) { + String doneFileName = endpoint.createDoneFileName(target); + ObjectHelper.notEmpty(doneFileName, "doneFileName", endpoint); - // create empty exchange with empty body to write as the done file - Exchange empty = new DefaultExchange(exchange); - empty.getIn().setBody(""); + // create empty exchange with empty body to write as the done file + Exchange empty = new DefaultExchange(exchange); + empty.getIn().setBody(""); - log.trace("Writing done file: [{}]", doneFileName); - // delete any existing done file - if (operations.existsFile(doneFileName)) { - if (!operations.deleteFile(doneFileName)) { - throw new GenericFileOperationFailedException("Cannot delete existing done file: " + doneFileName); + log.trace("Writing done file: [{}]", doneFileName); + // delete any existing done file + if (operations.existsFile(doneFileName)) { + if (!operations.deleteFile(doneFileName)) { + throw new GenericFileOperationFailedException("Cannot delete existing done file: " + doneFileName); + } } + writeFile(empty, doneFileName); } - writeFile(empty, doneFileName); } // let's store the name we really used in the header, so end-users @@ -210,6 +212,15 @@ protected void processExchange(Exchange exchange, String target) throws Exceptio postWriteCheck(); } + /** + * Override if required. Files are actually sent / returns true by default + * + * @return true to send files, false to skip sending files. + */ + protected boolean isUploadFile() { + return true; + } + /** * If we fail writing out a file, we will call this method. This hook is * provided to disconnect from servers or clean up files we created (if needed). diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java index 1951143ad36bf..895573ef55238 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java @@ -38,6 +38,7 @@ public abstract class RemoteFileEndpoint extends GenericFileEndpoint { private boolean disconnect; private boolean fastExistsCheck; private boolean download = true; + private boolean upload = true; public RemoteFileEndpoint() { // no args constructor for spring bean endpoint configuration @@ -208,4 +209,12 @@ public boolean isDownload() { public void setDownload(boolean download) { this.download = download; } + + public boolean isUpload() { + return this.upload; + } + + public void setUpload(boolean upload) { + this.upload = upload; + } } diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java index 87882aad16949..84f78a7d0b48d 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java @@ -136,6 +136,11 @@ public void postWriteCheck() { } } + @Override + protected boolean isUploadFile() { + return getEndpoint().isUpload(); + } + @Override protected void doStart() throws Exception { log.debug("Starting"); diff --git a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerSiteCommandTest.java b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerSiteCommandTest.java index 064e2c2e8b793..bfa4e69627fb4 100644 --- a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerSiteCommandTest.java +++ b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerSiteCommandTest.java @@ -18,27 +18,42 @@ import java.io.File; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; import org.apache.camel.converter.IOConverter; import org.junit.Test; public class FtpProducerSiteCommandTest extends FtpServerTestSupport { + private String getFtpUrl() { + return "ftp://admin@localhost:" + getPort() + "/site?password=admin&siteCommand=help site"; + } + @Override - public boolean isUseRouteBuilder() { - return false; + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from( "direct:callSiteCommandWithoutUpload" ) + .to( "ftp://admin@localhost:" + getPort() + "/site?password=admin&siteCommand=STAT&upload=false" ); + } + }; } - private String getFtpUrl() { - return "ftp://admin@localhost:" + getPort() + "/site?password=admin&siteCommand=help site"; + @Test + public void testSiteCommandWithoutUploadingFile() throws Exception { + template.sendBodyAndHeader( "direct:callSiteCommandWithoutUpload", "Hello world", Exchange.FILE_NAME, "hello.txt" ); + + File file = new File( FTP_ROOT_DIR + "/site/hello.txt" ); + assertFalse( "No file should be uploaded", file.exists() ); } @Test public void testSiteCommand() throws Exception { - sendFile(getFtpUrl(), "Hello World", "hello.txt"); + sendFile( getFtpUrl(), "Hello World", "hello.txt" ); - File file = new File(FTP_ROOT_DIR + "/site/hello.txt"); - assertTrue("The uploaded file should exists", file.exists()); - assertEquals("Hello World", IOConverter.toString(file, null)); + File file = new File( FTP_ROOT_DIR + "/site/hello.txt" ); + assertTrue( "The uploaded file should exist", file.exists() ); + assertEquals( "Hello World", IOConverter.toString( file, null ) ); } - } \ No newline at end of file diff --git a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpServerTestSupport.java b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpServerTestSupport.java index 7df7a9296b1e1..7c695507f91df 100644 --- a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpServerTestSupport.java +++ b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpServerTestSupport.java @@ -38,7 +38,7 @@ public abstract class FtpServerTestSupport extends BaseServerTestSupport { protected static final String FTP_ROOT_DIR = "./target/res/home"; - protected static final File USERS_FILE = new File("./src/test/resources/users.properties"); + protected static final File USERS_FILE = new File(FtpServerTestSupport.class.getResource( "/users.properties" ).getFile()); protected static final String DEFAULT_LISTENER = "default"; protected FtpServer ftpServer; From 312f536920f9676042feadcfa3d081e9f82b942d Mon Sep 17 00:00:00 2001 From: Carsten Erker Date: Thu, 21 Mar 2013 17:57:34 +0100 Subject: [PATCH 2/4] CAMEL-6137: Added a new option "siteCommandCapture" to the RemoteFileConfiguration: if true, the output of the site commands will be returned in the exchange's body as a List with the output of each executed site command as a list element in order of execution. If false, the body remains untouched. Defaults to false. --- .../component/file/GenericFileProducer.java | 4 +- .../component/file/remote/FtpOperations.java | 19 ++++++-- .../file/remote/RemoteFileConfiguration.java | 26 +++++++++-- .../file/remote/RemoteFileOperations.java | 12 +++++ .../file/remote/RemoteFileProducer.java | 3 +- .../component/file/remote/SftpOperations.java | 5 +++ .../remote/FtpProducerSiteCommandTest.java | 44 +++++++++++++++---- .../camel/component/jsch/ScpOperations.java | 7 ++- 8 files changed, 100 insertions(+), 20 deletions(-) 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 9d82b56d6e504..47b87133d01ad 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 @@ -111,7 +111,7 @@ protected void processExchange(Exchange exchange, String target) throws Exceptio log.trace("Processing file: {} for exchange: {}", target, exchange); try { - preWriteCheck(); + preWriteCheck(exchange); if (isUploadFile()) { // should we write to a temporary name and then afterwards rename to real target @@ -232,7 +232,7 @@ public void handleFailedWrite(Exchange exchange, Exception exception) throws Exc /** * Perform any actions that need to occur before we write such as connecting to an FTP server etc. */ - public void preWriteCheck() throws Exception { + public void preWriteCheck(Exchange exchange) throws Exception { // nothing needed to check } diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java index 4cbc4ddb32390..27f0bc5749c6b 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java @@ -167,8 +167,12 @@ public boolean connect(RemoteFileConfiguration configuration) throws GenericFile throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e); } - // site commands - if (endpoint.getConfiguration().getSiteCommand() != null) { + return true; + } + + public void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException { + if (configuration.getSiteCommand() != null) { + List siteOutput = new ArrayList(); // commands can be separated using new line Iterator it = ObjectHelper.createIterator(endpoint.getConfiguration().getSiteCommand(), "\n"); while (it.hasNext()) { @@ -177,14 +181,21 @@ public boolean connect(RemoteFileConfiguration configuration) throws GenericFile log.trace("Site command to send: {}", command); if (command != null) { boolean result = sendSiteCommand(command); + + if (configuration.isSiteCommandCapture()) { + String reply = getFtpClient().getReplyString(); + siteOutput.add(reply); + } + if (!result) { throw new GenericFileOperationFailedException("Site command: " + command + " returned false"); } } } + if (configuration.isSiteCommandCapture()) { + exchange.getIn().setBody(siteOutput); + } } - - return true; } public boolean isConnected() throws GenericFileOperationFailedException { diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java index e5325bacfa677..89f3e3c75c3b6 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java @@ -47,6 +47,7 @@ public enum PathSeparator { UNIX, Windows, Auto }; private int soTimeout; private boolean throwExceptionOnConnectFailed; private String siteCommand; + private boolean siteCommandCapture = false; private boolean stepwise = true; private PathSeparator separator = PathSeparator.Auto; private boolean streamDownload; @@ -57,7 +58,7 @@ public RemoteFileConfiguration() { public RemoteFileConfiguration(URI uri) { configure(uri); } - + @Override public boolean needToNormalize() { return false; @@ -230,6 +231,25 @@ public void setSiteCommand(String siteCommand) { this.siteCommand = siteCommand; } + public boolean isSiteCommandCapture() { + return siteCommandCapture; + } + + /** + * Capture the output of the site commands. The output of the site commands will be returned + * in the exchange's body as a List with the output of each executed site command + * as a list element in order of execution. The order of execution is defined by the order + * of the site commands in the siteCommand option (each separated by a newline character). + * If false, the body remains untouched. + *

+ * The default is false. + * + * @param siteCommandCapture if true, capture site command output. + */ + public void setSiteCommandCapture(boolean siteCommandCapture) { + this.siteCommandCapture = siteCommandCapture; + } + public boolean isStepwise() { return stepwise; } @@ -261,7 +281,7 @@ public PathSeparator getSeparator() { public void setSeparator(PathSeparator separator) { this.separator = separator; } - + public boolean isStreamDownload() { return streamDownload; } @@ -271,7 +291,7 @@ public boolean isStreamDownload() { * the remote files are streamed to the route as they are read. When set to false, the remote files * are loaded into memory before being sent into the route. * - * @param streamDownload + * @param streamDownload */ public void setStreamDownload(boolean streamDownload) { this.streamDownload = streamDownload; diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileOperations.java index 55573cbe48232..0c5cb01c83b60 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileOperations.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileOperations.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.file.remote; +import org.apache.camel.Exchange; import org.apache.camel.component.file.GenericFileOperationFailedException; import org.apache.camel.component.file.GenericFileOperations; @@ -65,4 +66,15 @@ public interface RemoteFileOperations extends GenericFileOperations { */ boolean sendSiteCommand(String command) throws GenericFileOperationFailedException; + /** + * Sends the site commands to the remote server which are specified in the + * configuration option siteCommand. If option siteCommandCapture is true, + * the output of each site command will be captured and returned as a List + * in the body. + * + * @param configuration the configuration + * @param exchange the exchange + * @throws GenericFileOperationFailedException can be thrown + */ + void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException; } diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java index 84f78a7d0b48d..00bca04b28837 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java @@ -89,7 +89,7 @@ public void disconnect() throws GenericFileOperationFailedException { } @Override - public void preWriteCheck() throws Exception { + public void preWriteCheck(Exchange exchange) throws Exception { // before writing send a noop to see if the connection is alive and works boolean noop = false; if (loggedIn) { @@ -114,6 +114,7 @@ public void preWriteCheck() throws Exception { } else { connectIfNecessary(); } + getOperations().sendSiteCommands(getEndpoint().getConfiguration(), exchange); } catch (Exception e) { loggedIn = false; diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java index 68da99e7a8da1..07beac73489f9 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java @@ -867,4 +867,9 @@ public boolean sendSiteCommand(String command) throws GenericFileOperationFailed // is not implemented return true; } + + @Override + public void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException { + throw new GenericFileOperationFailedException("Operation 'site ..' not supported by the sftp: protocol"); + } } diff --git a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerSiteCommandTest.java b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerSiteCommandTest.java index bfa4e69627fb4..be100881f1745 100644 --- a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerSiteCommandTest.java +++ b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpProducerSiteCommandTest.java @@ -17,12 +17,16 @@ package org.apache.camel.component.file.remote; import java.io.File; +import java.util.List; import org.apache.camel.Exchange; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.converter.IOConverter; import org.junit.Test; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.startsWith; + public class FtpProducerSiteCommandTest extends FtpServerTestSupport { private String getFtpUrl() { @@ -34,26 +38,48 @@ protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { - from( "direct:callSiteCommandWithoutUpload" ) - .to( "ftp://admin@localhost:" + getPort() + "/site?password=admin&siteCommand=STAT&upload=false" ); + from("direct:callSiteCommandWithoutUpload") + .to("ftp://admin@localhost:" + getPort() + "/site?password=admin&siteCommand=STAT&upload=false"); + + from("direct:callSiteCommandAndCaptureOutput") + .inOut("ftp://admin@localhost:" + getPort() + "/site?password=admin&siteCommand=STAT&upload=false&siteCommandCapture=true"); + + from("direct:callTwoSiteCommands") + .inOut("ftp://admin@localhost:" + getPort() + "/site?password=admin&siteCommand=STAT%0AZONE&upload=false&siteCommandCapture=true"); } }; } @Test public void testSiteCommandWithoutUploadingFile() throws Exception { - template.sendBodyAndHeader( "direct:callSiteCommandWithoutUpload", "Hello world", Exchange.FILE_NAME, "hello.txt" ); + template.sendBodyAndHeader("direct:callSiteCommandWithoutUpload", "Hello world", Exchange.FILE_NAME, "hello.txt"); + + File file = new File(FTP_ROOT_DIR + "/site/hello.txt"); + assertFalse("No file should be uploaded", file.exists()); + } - File file = new File( FTP_ROOT_DIR + "/site/hello.txt" ); - assertFalse( "No file should be uploaded", file.exists() ); + @Test + public void testCaptureSiteCommandOutput() throws Exception { + List output = template.requestBody("direct:callSiteCommandAndCaptureOutput", null, List.class); + + assertThat("Body should contain one line of site command output", output.size(), is(1)); + assertThat("Site command output should start with response code 200", output.get(0), startsWith("200")); + } + + @Test + public void testCallsTwoSiteCommands() throws Exception { + List output = template.requestBody("direct:callTwoSiteCommands", null, List.class); + System.out.println(output.get(0)); + System.out.println(output.get(1)); + assertThat("Body should contain one line of site command output", output.size(), is(2)); } @Test public void testSiteCommand() throws Exception { - sendFile( getFtpUrl(), "Hello World", "hello.txt" ); + sendFile(getFtpUrl(), "Hello World", "hello.txt"); - File file = new File( FTP_ROOT_DIR + "/site/hello.txt" ); - assertTrue( "The uploaded file should exist", file.exists() ); - assertEquals( "Hello World", IOConverter.toString( file, null ) ); + File file = new File(FTP_ROOT_DIR + "/site/hello.txt"); + assertTrue("The uploaded file should exist", file.exists()); + assertEquals("Hello World", IOConverter.toString(file, null)); } } \ No newline at end of file diff --git a/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java b/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java index 4bea7fb2988c2..efa876222793e 100644 --- a/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java +++ b/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java @@ -212,7 +212,12 @@ public boolean sendSiteCommand(String command) throws GenericFileOperationFailed // TODO: not really used, maybe implement at a later time return true; } - + + @Override + public void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException { + throw new GenericFileOperationFailedException("Operation 'site ..' not supported by the scp: protocol"); + } + private Session createSession(ScpConfiguration config) { ObjectHelper.notNull(config, "ScpConfiguration"); try { From 84f10cf3a5a17e7bc82c4143825e0e6054c5f3de Mon Sep 17 00:00:00 2001 From: Carsten Erker Date: Thu, 21 Mar 2013 18:11:27 +0100 Subject: [PATCH 3/4] CAMEL-6137: Send site commands also when consuming; in this case without capturing output. --- .../camel/component/file/remote/FtpOperations.java | 9 +++++---- .../camel/component/file/remote/RemoteFileConsumer.java | 1 + .../component/file/remote/RemoteFileOperations.java | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java index 27f0bc5749c6b..0522aad803e36 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperations.java @@ -172,7 +172,8 @@ public boolean connect(RemoteFileConfiguration configuration) throws GenericFile public void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException { if (configuration.getSiteCommand() != null) { - List siteOutput = new ArrayList(); + final boolean captureOutput = exchange != null && configuration.isSiteCommandCapture(); + final List siteOutput = new ArrayList(); // commands can be separated using new line Iterator it = ObjectHelper.createIterator(endpoint.getConfiguration().getSiteCommand(), "\n"); while (it.hasNext()) { @@ -182,9 +183,9 @@ public void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exc if (command != null) { boolean result = sendSiteCommand(command); - if (configuration.isSiteCommandCapture()) { + if (captureOutput) { String reply = getFtpClient().getReplyString(); - siteOutput.add(reply); + siteOutput.add( reply ); } if (!result) { @@ -192,7 +193,7 @@ public void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exc } } } - if (configuration.isSiteCommandCapture()) { + if ( captureOutput ) { exchange.getIn().setBody(siteOutput); } } diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java index e347c7dcc1f68..0669ccccd2053 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java @@ -55,6 +55,7 @@ protected boolean prePollCheck() throws Exception { } else { connectIfNecessary(); } + getOperations().sendSiteCommands( getEndpoint().getConfiguration(), null ); } catch (Exception e) { loggedIn = false; diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileOperations.java index 0c5cb01c83b60..116a402348a25 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileOperations.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileOperations.java @@ -71,9 +71,11 @@ public interface RemoteFileOperations extends GenericFileOperations { * configuration option siteCommand. If option siteCommandCapture is true, * the output of each site command will be captured and returned as a List * in the body. + *

+ * Works with the producer only. * * @param configuration the configuration - * @param exchange the exchange + * @param exchange the exchange; if null, output will not be captured * @throws GenericFileOperationFailedException can be thrown */ void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException; From facfeb38b14764d1496a5f1ba9bb184086e9a63f Mon Sep 17 00:00:00 2001 From: Carsten Erker Date: Thu, 21 Mar 2013 18:32:29 +0100 Subject: [PATCH 4/4] CAMEL-6137: sendSiteCommand() should do nothing --- .../org/apache/camel/component/file/remote/SftpOperations.java | 2 +- .../java/org/apache/camel/component/jsch/ScpOperations.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java index 07beac73489f9..60460356404a4 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java @@ -870,6 +870,6 @@ public boolean sendSiteCommand(String command) throws GenericFileOperationFailed @Override public void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException { - throw new GenericFileOperationFailedException("Operation 'site ..' not supported by the sftp: protocol"); + // is not implemented } } diff --git a/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java b/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java index efa876222793e..32ae1fcd686b5 100644 --- a/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java +++ b/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java @@ -215,7 +215,7 @@ public boolean sendSiteCommand(String command) throws GenericFileOperationFailed @Override public void sendSiteCommands(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException { - throw new GenericFileOperationFailedException("Operation 'site ..' not supported by the scp: protocol"); + // TODO: not really used, maybe implement at a later time } private Session createSession(ScpConfiguration config) {