From 7aea76c6c45261cfa5fb62b4ec521769341e6912 Mon Sep 17 00:00:00 2001 From: Joaquin Santana Date: Tue, 15 Oct 2019 17:12:24 +0200 Subject: [PATCH] GH-3026: Fix chmod support for DSL Fixes https://github.com/spring-projects/spring-integration/issues/3026 **Cherry-pick to `5.1.x`** * Populate proper `FileTransferringMessageHandler` impl from DSL spec implementations. This way we are able to use a provided `chmod` from Java DSL * Added `FileTransferringMessageHandlerSpec` ctor TODO * Update SftpTests * Code cleanup; `@Ignore` `SftpTests.testSftpOutboundFlowWithChmod()` since it doesn't work properly on Windows --- .../FileTransferringMessageHandlerSpec.java | 6 ++++ .../ftp/dsl/FtpMessageHandlerSpec.java | 9 ++++-- .../integration/ftp/dsl/FtpTests.java | 25 ++++++++++++++++ .../sftp/dsl/SftpMessageHandlerSpec.java | 10 +++++-- .../integration/sftp/dsl/SftpTests.java | 30 +++++++++++++++++++ ...oundRemoteFileSystemSynchronizerTests.java | 4 ++- 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/dsl/FileTransferringMessageHandlerSpec.java b/spring-integration-file/src/main/java/org/springframework/integration/file/dsl/FileTransferringMessageHandlerSpec.java index 46a196758d..4e58423fb8 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/dsl/FileTransferringMessageHandlerSpec.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/dsl/FileTransferringMessageHandlerSpec.java @@ -41,6 +41,7 @@ import org.springframework.util.Assert; * @param the target {@link FileTransferringMessageHandlerSpec} implementation type. * * @author Artem Bilan + * @author Joaquin Santana * * @since 5.0 */ @@ -52,6 +53,10 @@ public abstract class FileTransferringMessageHandlerSpec sessionFactory) { this.target = new FileTransferringMessageHandler<>(sessionFactory); } @@ -62,6 +67,7 @@ public abstract class FileTransferringMessageHandlerSpec remoteFileTemplate, FileExistsMode fileExistsMode) { + this.target = new FileTransferringMessageHandler<>(remoteFileTemplate, fileExistsMode); } diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/dsl/FtpMessageHandlerSpec.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/dsl/FtpMessageHandlerSpec.java index 97d992eb78..260ae0d8cb 100644 --- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/dsl/FtpMessageHandlerSpec.java +++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/dsl/FtpMessageHandlerSpec.java @@ -22,25 +22,28 @@ import org.springframework.integration.file.dsl.FileTransferringMessageHandlerSp import org.springframework.integration.file.remote.RemoteFileTemplate; import org.springframework.integration.file.remote.session.SessionFactory; import org.springframework.integration.file.support.FileExistsMode; +import org.springframework.integration.ftp.outbound.FtpMessageHandler; /** * A {@link FileTransferringMessageHandlerSpec} for FTP. * * @author Artem Bilan + * @author Joaquin Santana + * * @since 5.0 */ public class FtpMessageHandlerSpec extends FileTransferringMessageHandlerSpec { FtpMessageHandlerSpec(SessionFactory sessionFactory) { - super(sessionFactory); + this.target = new FtpMessageHandler(sessionFactory); } FtpMessageHandlerSpec(RemoteFileTemplate remoteFileTemplate) { - super(remoteFileTemplate); + this.target = new FtpMessageHandler(remoteFileTemplate.getSessionFactory()); } FtpMessageHandlerSpec(RemoteFileTemplate remoteFileTemplate, FileExistsMode fileExistsMode) { - super(remoteFileTemplate, fileExistsMode); + this.target = new FtpMessageHandler(remoteFileTemplate, fileExistsMode); } } diff --git a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java index 4edf4084f7..860d61b078 100644 --- a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java +++ b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/dsl/FtpTests.java @@ -66,6 +66,7 @@ import org.springframework.util.FileCopyUtils; /** * @author Artem Bilan * @author Gary Russell + * @author Joaquin Santana * * @since 5.0 */ @@ -192,6 +193,30 @@ public class FtpTests extends FtpTestSupport { registration.destroy(); } + @Test + public void testFtpOutboundFlowWithChmod() { + IntegrationFlow flow = f -> f + .handle(Ftp.outboundAdapter(sessionFactory(), FileExistsMode.FAIL) + .useTemporaryFileName(false) + .fileNameExpression("headers['" + FileHeaders.FILENAME + "']") + .chmod(0644) + .remoteDirectory("ftpTarget")); + IntegrationFlowRegistration registration = this.flowContext.registration(flow).register(); + String fileName = "foo.file"; + Message message = MessageBuilder + .withPayload(new ByteArrayInputStream("foo".getBytes(StandardCharsets.UTF_8))) + .setHeader(FileHeaders.FILENAME, fileName) + .build(); + registration.getInputChannel().send(message); + RemoteFileTemplate template = new RemoteFileTemplate<>(sessionFactory()); + FTPFile[] files = template.execute(session -> + session.list(getTargetRemoteDirectory().getName() + "/" + fileName)); + assertThat(files.length).isEqualTo(1); + assertThat(files[0].getSize()).isEqualTo(3); + + registration.destroy(); + } + @Test @SuppressWarnings("unchecked") public void testFtpMgetFlow() { diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/dsl/SftpMessageHandlerSpec.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/dsl/SftpMessageHandlerSpec.java index ae6370eb27..e0d150fbfc 100644 --- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/dsl/SftpMessageHandlerSpec.java +++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/dsl/SftpMessageHandlerSpec.java @@ -20,26 +20,30 @@ import org.springframework.integration.file.dsl.FileTransferringMessageHandlerSp import org.springframework.integration.file.remote.RemoteFileTemplate; import org.springframework.integration.file.remote.session.SessionFactory; import org.springframework.integration.file.support.FileExistsMode; +import org.springframework.integration.sftp.outbound.SftpMessageHandler; +import org.springframework.integration.sftp.session.SftpRemoteFileTemplate; import com.jcraft.jsch.ChannelSftp; /** * @author Artem Bilan + * @author Joaquin Santana + * * @since 5.0 */ public class SftpMessageHandlerSpec extends FileTransferringMessageHandlerSpec { SftpMessageHandlerSpec(SessionFactory sessionFactory) { - super(sessionFactory); + this.target = new SftpMessageHandler(sessionFactory); } SftpMessageHandlerSpec(RemoteFileTemplate remoteFileTemplate) { - super(remoteFileTemplate); + this.target = new SftpMessageHandler(remoteFileTemplate.getSessionFactory()); } SftpMessageHandlerSpec(RemoteFileTemplate remoteFileTemplate, FileExistsMode fileExistsMode) { - super(remoteFileTemplate, fileExistsMode); + this.target = new SftpMessageHandler(new SftpRemoteFileTemplate(remoteFileTemplate.getSessionFactory()), fileExistsMode); } } diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/dsl/SftpTests.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/dsl/SftpTests.java index e4a9e011d7..23a5083c6c 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/dsl/SftpTests.java +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/dsl/SftpTests.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.util.List; import java.util.regex.Matcher; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,6 +55,7 @@ import com.jcraft.jsch.ChannelSftp; /** * @author Artem Bilan * @author Gary Russell + * @author Joaquin Santana * * @since 5.0 * @@ -146,6 +148,34 @@ public class SftpTests extends SftpTestSupport { registration.destroy(); } + + @Test + @Ignore("Doesn't work as expected on Windows") + public void testSftpOutboundFlowWithChmod() { + IntegrationFlow flow = f -> f.handle(Sftp.outboundAdapter(sessionFactory(), FileExistsMode.FAIL) + .useTemporaryFileName(false) + .fileNameExpression("headers['" + FileHeaders.FILENAME + "']") + .chmod(0644) + .remoteDirectory("sftpTarget")); + IntegrationFlowRegistration registration = this.flowContext.registration(flow).register(); + String fileName = "foo.file"; + registration.getInputChannel().send(MessageBuilder.withPayload("foo") + .setHeader(FileHeaders.FILENAME, fileName) + .build()); + + RemoteFileTemplate template = new RemoteFileTemplate<>(sessionFactory()); + ChannelSftp.LsEntry[] files = template.execute(session -> + session.list(getTargetRemoteDirectory().getName() + "/" + fileName)); + assertThat(files.length).isEqualTo(1); + assertThat(files[0].getAttrs().getSize()).isEqualTo(3); + String[] permissions = files[0].getAttrs().getPermissionsString().substring(1).replaceAll("--", "-").split("-"); + assertThat(permissions[0]).isEqualTo("rw"); + assertThat(permissions[1]).isEqualTo("r"); + assertThat(permissions[2]).isEqualTo("r"); + + registration.destroy(); + } + @Test @SuppressWarnings("unchecked") public void testSftpMgetFlow() { diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/inbound/SftpInboundRemoteFileSystemSynchronizerTests.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/inbound/SftpInboundRemoteFileSystemSynchronizerTests.java index 82f2845cd8..1a73fbdeb6 100644 --- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/inbound/SftpInboundRemoteFileSystemSynchronizerTests.java +++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/inbound/SftpInboundRemoteFileSystemSynchronizerTests.java @@ -59,6 +59,7 @@ import com.jcraft.jsch.SftpATTRS; * @author Gunnar Hillert * @author Gary Russell * @author Artem Bilan + * @author Joaquin Santana * * @since 2.0 */ @@ -169,7 +170,8 @@ public class SftpInboundRemoteFileSystemSynchronizerTests { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DATE, 1); - when(lsEntry.getAttrs().getMTime()).thenReturn(new Long(calendar.getTimeInMillis() / 1000).intValue()); + when(lsEntry.getAttrs().getMTime()) + .thenReturn(Long.valueOf(calendar.getTimeInMillis() / 1000).intValue()); when(lsEntry.getFilename()).thenReturn(fileName); when(lsEntry.getLongname()).thenReturn(fileName); sftpEntries.add(lsEntry);