diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpSendingMessageHandler.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpSendingMessageHandler.java index 78b1839acd..b2b9ad0dc4 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpSendingMessageHandler.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpSendingMessageHandler.java @@ -15,17 +15,22 @@ */ package org.springframework.integration.ftp; +import org.apache.commons.lang.SystemUtils; import org.apache.commons.net.ftp.FTPClient; import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; import org.springframework.integration.Message; import org.springframework.integration.MessageDeliveryException; +import org.springframework.integration.MessageHandlingException; +import org.springframework.integration.MessageRejectedException; import org.springframework.integration.core.MessageHandler; +import org.springframework.integration.file.DefaultFileNameGenerator; +import org.springframework.integration.file.FileNameGenerator; import org.springframework.util.Assert; +import org.springframework.util.FileCopyUtils; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; +import java.io.*; import java.net.SocketException; @@ -51,16 +56,94 @@ public class FtpSendingMessageHandler implements MessageHandler, InitializingBea public void afterPropertiesSet() throws Exception { Assert.notNull(ftpClientPool, "'ftpClientPool' must not be null"); + Assert.notNull(temporaryBufferFolder, "'temporaryBufferFolder' must not be null"); + temporaryBufferFolderFile = this.temporaryBufferFolder.getFile(); } - public void handleMessage(Message message) { + /* Ugh this needs to be put in a convenient place accessible for all the file:, sftp:, and ftp:* adapters */ + + private File handleFileMessage(File sourceFile, File tempFile, File resultFile) + throws IOException { + if (sourceFile.renameTo(resultFile)) { + return resultFile; + } + + FileCopyUtils.copy(sourceFile, tempFile); + tempFile.renameTo(resultFile); + + return resultFile; + } + + private File handleByteArrayMessage(byte[] bytes, File tempFile, File resultFile) + throws IOException { + FileCopyUtils.copy(bytes, tempFile); + tempFile.renameTo(resultFile); + + return resultFile; + } + + private File handleStringMessage(String content, File tempFile, File resultFile, String charset) + throws IOException { + OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tempFile), charset); + FileCopyUtils.copy(content, writer); + tempFile.renameTo(resultFile); + + return resultFile; + } + + private static final String TEMPORARY_FILE_SUFFIX = ".writing"; + private FileNameGenerator fileNameGenerator = new DefaultFileNameGenerator(); + private File temporaryBufferFolderFile; + private Resource temporaryBufferFolder = new FileSystemResource(SystemUtils.getJavaIoTmpDir()); + + public void setTemporaryBufferFolder(Resource temporaryBufferFolder) { + this.temporaryBufferFolder = temporaryBufferFolder; + } + + public void setFileNameGenerator(FileNameGenerator fileNameGenerator) { + this.fileNameGenerator = fileNameGenerator; + } + + private File redeemForStorableFile(Message msg) throws MessageDeliveryException { + try { + Object payload = msg.getPayload(); + String generateFileName = this.fileNameGenerator.generateFileName(msg); + File tempFile = new File(temporaryBufferFolderFile, generateFileName + TEMPORARY_FILE_SUFFIX); + File resultFile = new File(temporaryBufferFolderFile, generateFileName); + File sendableFile; + if (payload instanceof String) + sendableFile = this.handleStringMessage((String) payload, tempFile, resultFile, this.charset); + else if (payload instanceof File) + sendableFile = this.handleFileMessage((File) payload, tempFile, resultFile); + else if (payload instanceof byte[]) + sendableFile = this.handleByteArrayMessage((byte[]) payload, tempFile, resultFile); + else sendableFile = null; + return sendableFile; + } catch (Throwable th) { + throw new MessageDeliveryException(msg); + } + + } + + private String charset; + + public void setCharset(String charset) { + this.charset = charset; + } + /* Ugh this needs to be put in a convenient place accessible for all the file:, sftp:, and ftp:* adapters */ + + + public void handleMessage(Message message) throws MessageRejectedException, + MessageHandlingException, MessageDeliveryException { + + Assert.notNull(message, "'message' must not be null"); Object payload = message.getPayload(); - Assert.notNull(payload, "Message payload must not be null"); - Assert.isInstanceOf(File.class, payload, "Message payload must be an instance of [java.io.File]"); - File file = (File) payload; + Assert.notNull(payload, "Message payload must not be null"); + + File file = this.redeemForStorableFile(message); if ((file != null) && file.exists()) { FTPClient client = null; @@ -76,6 +159,12 @@ public class FtpSendingMessageHandler implements MessageHandler, InitializingBea } catch (Exception e) { throw new MessageDeliveryException(message, "Error handling message for file [" + file + "]", e); } finally { + if ( file.exists()) + try { + file.delete(); + } catch (Throwable th) { + /// noop + } if (client != null) { ftpClientPool.releaseClient(client); } @@ -84,14 +173,17 @@ public class FtpSendingMessageHandler implements MessageHandler, InitializingBea if (!sentSuccesfully) { throw new MessageDeliveryException(message, "Failed to store file '" + file + "'"); } + } + } private boolean sendFile(File file, FTPClient client) - throws FileNotFoundException, IOException { + throws FileNotFoundException, IOException { FileInputStream fileInputStream = new FileInputStream(file); boolean sent = client.storeFile(file.getName(), fileInputStream); fileInputStream.close(); + return sent; } diff --git a/spring-integration-ftp/src/test/resources/inbound-ftp-context.xml b/spring-integration-ftp/src/test/resources/inbound-ftp-context.xml index d5251db6ee..355348baaf 100644 --- a/spring-integration-ftp/src/test/resources/inbound-ftp-context.xml +++ b/spring-integration-ftp/src/test/resources/inbound-ftp-context.xml @@ -13,10 +13,6 @@ ignore-unresolvable="true"/> - - - - msg) throws MessageDeliveryException { + try { + Object payload = msg.getPayload(); + String generateFileName = this.fileNameGenerator.generateFileName(msg); + File tempFile = new File(temporaryBufferFolderFile, generateFileName + TEMPORARY_FILE_SUFFIX); + File resultFile = new File(temporaryBufferFolderFile, generateFileName); + File sendableFile; + if (payload instanceof String) + sendableFile = this.handleStringMessage((String) payload, tempFile, resultFile, this.charset); + else if (payload instanceof File) + sendableFile = this.handleFileMessage((File) payload, tempFile, resultFile); + else if (payload instanceof byte[]) + sendableFile = this.handleByteArrayMessage((byte[]) payload, tempFile, resultFile); + else sendableFile = null; + return sendableFile; + } catch (Throwable th) { + throw new MessageDeliveryException(msg); + } + + } + + private String charset; + + public void setCharset(String charset) { + this.charset = charset; + } + /* Ugh this needs to be put in a convenient place accessible for all the file:, sftp:, and ftp:* adapters */ + + + public void handleMessage(final Message message) throws MessageRejectedException, MessageHandlingException, MessageDeliveryException { - assert this.pool != null : "need a working pool"; - assert message.getPayload() instanceof File : "the payload needs to be java.io.File"; - + Assert.state(this.pool != null , "need a working pool"); + File inboundFilePayload = this.redeemForStorableFile( message); try { - File inboundFilePayload = (File) message.getPayload(); if ((inboundFilePayload != null) && inboundFilePayload.exists()) { sendFileToRemoteEndpoint(message, inboundFilePayload); @@ -75,6 +153,10 @@ public class SftpSendingMessageHandler implements MessageHandler, InitializingBe } catch (Throwable thr) { // logger.debug("recieved an exception.", thr); throw new MessageDeliveryException(message, "couldn't deliver the message!", thr); + } finally { + if(inboundFilePayload!=null&&inboundFilePayload.exists()) + inboundFilePayload.delete() ; + } }