INT-1756 added support for auto-creating remote directories
This commit is contained in:
@@ -47,6 +47,7 @@ public class RemoteFileOutboundChannelAdapterParser extends AbstractOutboundChan
|
||||
"org.springframework.integration.file.remote.handler.FileTransferringMessageHandler");
|
||||
handlerBuilder.addConstructorArgValue(sessionFactoryBuilder.getBeanDefinition());
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(handlerBuilder, element, "temporary-file-suffix");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(handlerBuilder, element, "auto-create-directory");
|
||||
|
||||
// configure remote directory expression
|
||||
String remoteDirectory = element.getAttribute("remote-directory");
|
||||
|
||||
@@ -48,6 +48,8 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
|
||||
public volatile String temporaryFileSuffix =".writing";
|
||||
|
||||
private final SessionFactory sessionFactory;
|
||||
|
||||
private volatile boolean autoCreateDirectory = false;
|
||||
|
||||
private volatile ExpressionEvaluatingMessageProcessor<String> directoryExpressionProcessor;
|
||||
|
||||
@@ -65,7 +67,10 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
|
||||
public void setAutoCreateDirectory(boolean autoCreateDirectory) {
|
||||
this.autoCreateDirectory = autoCreateDirectory;
|
||||
}
|
||||
|
||||
public void setRemoteFileSeparator(String remoteFileSeparator) {
|
||||
Assert.hasText(remoteFileSeparator, "'remoteFileSeparator' must not be empty");
|
||||
this.remoteFileSeparator = remoteFileSeparator;
|
||||
@@ -185,10 +190,32 @@ public class FileTransferringMessageHandler extends AbstractMessageHandler {
|
||||
String remoteFilePath = remoteDirectory + fileName;
|
||||
// write remote file first with .writing extension
|
||||
String tempFilePath = remoteFilePath + this.temporaryFileSuffix;
|
||||
|
||||
if (this.autoCreateDirectory){
|
||||
this.ensureDirectoryExists(session, remoteDirectory, remoteDirectory);
|
||||
}
|
||||
|
||||
session.write(fileInputStream, tempFilePath);
|
||||
fileInputStream.close();
|
||||
// then rename it to its final name
|
||||
session.rename(tempFilePath, remoteFilePath);
|
||||
}
|
||||
|
||||
private void ensureDirectoryExists(Session session, String remoteDirectory, String originalRemoteDirectory){
|
||||
try {
|
||||
session.list(remoteDirectory);
|
||||
String missingDirectoryPath = originalRemoteDirectory.substring(remoteDirectory.length());
|
||||
String[] directories = StringUtils.tokenizeToStringArray(missingDirectoryPath, this.remoteFileSeparator);
|
||||
String directory = remoteDirectory + this.remoteFileSeparator;
|
||||
for (String directorySegment : directories) {
|
||||
directory += directorySegment+this.remoteFileSeparator;
|
||||
logger.debug("Creating '" + directory + "'");
|
||||
session.mkdir(directory);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.debug("Directory '" + remoteDirectory + "' does not exist");
|
||||
remoteDirectory = remoteDirectory.substring(0, remoteDirectory.lastIndexOf(this.remoteFileSeparator));
|
||||
this.ensureDirectoryExists(session, remoteDirectory, originalRemoteDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +148,10 @@ public class CachingSessionFactory implements SessionFactory, DisposableBean {
|
||||
public void rename(String pathFrom, String pathTo) throws IOException {
|
||||
this.targetSession.rename(pathFrom, pathTo);
|
||||
}
|
||||
|
||||
public void mkdir(String directory) throws IOException {
|
||||
this.targetSession.mkdir(directory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ public interface Session {
|
||||
|
||||
void write(InputStream inputStream, String destination) throws IOException;
|
||||
|
||||
void mkdir(String directory) throws IOException;
|
||||
|
||||
void rename(String pathFrom, String pathTo) throws IOException;
|
||||
|
||||
void close();
|
||||
|
||||
@@ -113,4 +113,15 @@ class FtpSession implements Session {
|
||||
}
|
||||
logger.info("File have been successfully renamed from: " + pathFrom + " to " + pathTo);
|
||||
}
|
||||
|
||||
public void mkdir(String directory) throws IOException {
|
||||
try {
|
||||
this.client.makeDirectory(directory);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("failed to create directory '" + directory + "'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,4 +140,12 @@ class SftpSession implements Session {
|
||||
}
|
||||
}
|
||||
|
||||
public void mkdir(String directory) throws IOException {
|
||||
try {
|
||||
this.channel.mkdir(directory);
|
||||
} catch (SftpException e) {
|
||||
throw new NestedIOException("failed to create remote directory '" + directory + "'.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,6 +77,14 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="auto-create-directory" type="xsd:string" default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify whether to automatically create the remote target directory if it doesn't exist.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-filename-generator" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
@@ -64,7 +64,7 @@ public class SftpInboundOutboundSanitySample {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
//@Ignore
|
||||
public void testOutbound() throws Exception{
|
||||
ApplicationContext ac =
|
||||
new ClassPathXmlApplicationContext("SftpOutboundTransferSample-ignored.xml", this.getClass());
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
charset="UTF-8"
|
||||
temporary-file-suffix=".foo"
|
||||
remote-filename-generator-expression="payload.getName() + '-foo'"
|
||||
remote-directory="/Users/ozhurakousky/workspace-sts-2.3.3.M2/si/spring-integration/spring-integration-sftp/remote-target-dir"/>
|
||||
auto-create-directory="true"
|
||||
remote-directory="/Users/ozhurakousky/workspace-sts-2.3.3.M2/si/spring-integration/spring-integration-sftp/remote-target-dir/foo/bar/baz"/>
|
||||
|
||||
</beans>
|
||||
|
||||
Reference in New Issue
Block a user