diff --git a/spring-sftp-upload-demo/.gitignore b/sftp-upload-demo/.gitignore similarity index 100% rename from spring-sftp-upload-demo/.gitignore rename to sftp-upload-demo/.gitignore diff --git a/spring-sftp-upload-demo/.mvn/wrapper/maven-wrapper.jar b/sftp-upload-demo/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from spring-sftp-upload-demo/.mvn/wrapper/maven-wrapper.jar rename to sftp-upload-demo/.mvn/wrapper/maven-wrapper.jar diff --git a/spring-sftp-upload-demo/.mvn/wrapper/maven-wrapper.properties b/sftp-upload-demo/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from spring-sftp-upload-demo/.mvn/wrapper/maven-wrapper.properties rename to sftp-upload-demo/.mvn/wrapper/maven-wrapper.properties diff --git a/spring-sftp-upload-demo/mvnw b/sftp-upload-demo/mvnw similarity index 100% rename from spring-sftp-upload-demo/mvnw rename to sftp-upload-demo/mvnw diff --git a/spring-sftp-upload-demo/mvnw.cmd b/sftp-upload-demo/mvnw.cmd similarity index 100% rename from spring-sftp-upload-demo/mvnw.cmd rename to sftp-upload-demo/mvnw.cmd diff --git a/spring-sftp-upload-demo/pom.xml b/sftp-upload-demo/pom.xml similarity index 100% rename from spring-sftp-upload-demo/pom.xml rename to sftp-upload-demo/pom.xml diff --git a/sftp-upload-demo/sftp-upload-demo.zip b/sftp-upload-demo/sftp-upload-demo.zip new file mode 100644 index 0000000..5e149ee Binary files /dev/null and b/sftp-upload-demo/sftp-upload-demo.zip differ diff --git a/spring-sftp-upload-demo/src/main/resources/application.properties b/sftp-upload-demo/src/main/resources/application.properties similarity index 100% rename from spring-sftp-upload-demo/src/main/resources/application.properties rename to sftp-upload-demo/src/main/resources/application.properties diff --git a/spring-sftp-upload-demo/src/test/resources/keys/sftp_rsa b/sftp-upload-demo/src/test/resources/keys/sftp_rsa similarity index 100% rename from spring-sftp-upload-demo/src/test/resources/keys/sftp_rsa rename to sftp-upload-demo/src/test/resources/keys/sftp_rsa diff --git a/spring-sftp-upload-demo/src/test/resources/keys/sftp_rsa.pub b/sftp-upload-demo/src/test/resources/keys/sftp_rsa.pub similarity index 100% rename from spring-sftp-upload-demo/src/test/resources/keys/sftp_rsa.pub rename to sftp-upload-demo/src/test/resources/keys/sftp_rsa.pub diff --git a/spring-sftp-upload-demo/src/main/java/com/pavelsklenar/SftpConfig.java b/spring-sftp-upload-demo/src/main/java/com/pavelsklenar/SftpConfig.java deleted file mode 100644 index 098e5a7..0000000 --- a/spring-sftp-upload-demo/src/main/java/com/pavelsklenar/SftpConfig.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.pavelsklenar; - -import java.io.File; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.Resource; -import org.springframework.expression.common.LiteralExpression; -import org.springframework.integration.annotation.Gateway; -import org.springframework.integration.annotation.MessagingGateway; -import org.springframework.integration.annotation.ServiceActivator; -import org.springframework.integration.file.FileNameGenerator; -import org.springframework.integration.file.remote.session.CachingSessionFactory; -import org.springframework.integration.file.remote.session.SessionFactory; -import org.springframework.integration.sftp.outbound.SftpMessageHandler; -import org.springframework.integration.sftp.session.DefaultSftpSessionFactory; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageHandler; - -import com.jcraft.jsch.ChannelSftp.LsEntry; - -@Configuration -public class SftpConfig { - - @Value("${sftp.host}") - private String sftpHost; - - @Value("${sftp.port:22}") - private int sftpPort; - - @Value("${sftp.user}") - private String sftpUser; - - @Value("${sftp.privateKey:#{null}}") - private Resource sftpPrivateKey; - - @Value("${sftp.privateKeyPassphrase:}") - private String sftpPrivateKeyPassphrase; - - @Value("${sftp.password:#{null}}") - private String sftpPasword; - - @Value("${sftp.remote.directory:/}") - private String sftpRemoteDirectory; - - @Bean - public SessionFactory sftpSessionFactory() { - DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true); - factory.setHost(sftpHost); - factory.setPort(sftpPort); - factory.setUser(sftpUser); - if (sftpPrivateKey != null) { - factory.setPrivateKey(sftpPrivateKey); - factory.setPrivateKeyPassphrase(sftpPrivateKeyPassphrase); - } else { - factory.setPassword(sftpPasword); - } - factory.setAllowUnknownKeys(true); - return new CachingSessionFactory(factory); - } - - @Bean - @ServiceActivator(inputChannel = "toSftpChannel") - public MessageHandler handler() { - SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory()); - handler.setRemoteDirectoryExpression(new LiteralExpression(sftpRemoteDirectory)); - handler.setFileNameGenerator(new FileNameGenerator() { - - @Override - public String generateFileName(Message message) { - if (message.getPayload() instanceof File) { - return ((File) message.getPayload()).getName(); - } else { - throw new IllegalArgumentException("File expected as payload."); - } - } - - }); - return handler; - } - - @MessagingGateway - public interface UploadGateway { - - @Gateway(requestChannel = "toSftpChannel") - void upload(File file); - - } - -} diff --git a/spring-sftp-upload-demo/src/main/java/com/pavelsklenar/SpringSftpUploadDemoApplication.java b/spring-sftp-upload-demo/src/main/java/com/pavelsklenar/SpringSftpUploadDemoApplication.java deleted file mode 100644 index 8bccdb0..0000000 --- a/spring-sftp-upload-demo/src/main/java/com/pavelsklenar/SpringSftpUploadDemoApplication.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.pavelsklenar; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.integration.annotation.IntegrationComponentScan; -import org.springframework.integration.config.EnableIntegration; - -@SpringBootApplication -@IntegrationComponentScan -@EnableIntegration -public class SpringSftpUploadDemoApplication { - - public static void main(String[] args) { - SpringApplication.run(SpringSftpUploadDemoApplication.class, args); - } -} diff --git a/spring-sftp-upload-demo/src/test/java/com/pavelsklenar/EmbeddedSftpServer.java b/spring-sftp-upload-demo/src/test/java/com/pavelsklenar/EmbeddedSftpServer.java deleted file mode 100644 index 62544d6..0000000 --- a/spring-sftp-upload-demo/src/test/java/com/pavelsklenar/EmbeddedSftpServer.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.pavelsklenar; - -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.KeyFactory; -import java.security.PublicKey; -import java.security.spec.RSAPublicKeySpec; -import java.util.Collections; - -import org.apache.commons.codec.binary.Base64; -import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory; -import org.apache.sshd.server.Command; -import org.apache.sshd.server.SshServer; -import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator; -import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; -import org.apache.sshd.server.scp.ScpCommandFactory; -import org.apache.sshd.server.session.ServerSession; -import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.SmartLifecycle; -import org.springframework.core.io.ClassPathResource; -import org.springframework.util.SocketUtils; -import org.springframework.util.StreamUtils; - -/** - * SFTP server for integration testing - * @author Artem Bilan - * @author pavel.sklenar - */ -public class EmbeddedSftpServer implements InitializingBean, SmartLifecycle { - - public static final int PORT = SocketUtils.findAvailableTcpPort(); - - private final SshServer server = SshServer.setUpDefaultServer(); - - private volatile int port; - - private volatile boolean running; - - public void setPort(int port) { - this.port = port; - } - - @Override - public void afterPropertiesSet() throws Exception { - final PublicKey allowedKey = decodePublicKey(); - this.server.setPublickeyAuthenticator(new PublickeyAuthenticator() { - - @Override - public boolean authenticate(String username, PublicKey key, ServerSession session) { - return key.equals(allowedKey); - } - - }); - this.server.setPort(this.port); - this.server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(Files.createTempFile("host_file", ".ser"))); - this.server.setSubsystemFactories(Collections.>singletonList(new SftpSubsystemFactory())); - server.setFileSystemFactory(new VirtualFileSystemFactory(Files.createTempDirectory("SFTP_TEMP"))); - server.setCommandFactory(new ScpCommandFactory()); - } - - public void setHomeFolder(Path path) { - server.setFileSystemFactory(new VirtualFileSystemFactory(path)); - } - - - private PublicKey decodePublicKey() throws Exception { - InputStream stream = new ClassPathResource("/keys/sftp_rsa.pub").getInputStream(); - byte[] decodeBuffer = Base64.decodeBase64(StreamUtils.copyToByteArray(stream)); - ByteBuffer bb = ByteBuffer.wrap(decodeBuffer); - int len = bb.getInt(); - byte[] type = new byte[len]; - bb.get(type); - if ("ssh-rsa".equals(new String(type))) { - BigInteger e = decodeBigInt(bb); - BigInteger m = decodeBigInt(bb); - RSAPublicKeySpec spec = new RSAPublicKeySpec(m, e); - return KeyFactory.getInstance("RSA").generatePublic(spec); - - } - else { - throw new IllegalArgumentException("Only supports RSA"); - } - } - - private BigInteger decodeBigInt(ByteBuffer bb) { - int len = bb.getInt(); - byte[] bytes = new byte[len]; - bb.get(bytes); - return new BigInteger(bytes); - } - - @Override - public boolean isAutoStartup() { - return PORT == this.port; - } - - @Override - public int getPhase() { - return Integer.MAX_VALUE; - } - - @Override - public void start() { - try { - server.start(); - this.running = true; - } - catch (IOException e) { - throw new IllegalStateException(e); - } - } - - @Override - public void stop(Runnable callback) { - stop(); - callback.run(); - } - - @Override - public void stop() { - if (this.running) { - try { - server.stop(false); - } - catch (IOException e) { - throw new IllegalStateException(e); - } - finally { - this.running = false; - } - } - } - - @Override - public boolean isRunning() { - return this.running; - } - - public SshServer getServer() { - return server; - } - -} diff --git a/spring-sftp-upload-demo/src/test/java/com/pavelsklenar/SpringSftpUploadDemoApplicationTests.java b/spring-sftp-upload-demo/src/test/java/com/pavelsklenar/SpringSftpUploadDemoApplicationTests.java deleted file mode 100644 index 549173b..0000000 --- a/spring-sftp-upload-demo/src/test/java/com/pavelsklenar/SpringSftpUploadDemoApplicationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.pavelsklenar; - -import static org.junit.Assert.assertEquals; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Collectors; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; - -import com.pavelsklenar.SftpConfig.UploadGateway; - -@RunWith(SpringRunner.class) -@SpringBootTest -@TestPropertySource(properties = { "sftp.port = 10022" }) -public class SpringSftpUploadDemoApplicationTests { - - @Autowired - private UploadGateway gateway; - - private static EmbeddedSftpServer server; - - private static Path sftpFolder; - - @BeforeClass - public static void startServer() throws Exception { - server = new EmbeddedSftpServer(); - server.setPort(10022); - sftpFolder = Files.createTempDirectory("SFTP_UPLOAD_TEST"); - server.afterPropertiesSet(); - server.setHomeFolder(sftpFolder); - // Starting SFTP - if (!server.isRunning()) { - server.start(); - } - } - - @Before - @After - public void cleanSftpFolder() throws IOException { - Files.walk(sftpFolder).filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete); - } - - @Test - public void testUpload() throws IOException { - // Prepare phase - Path tempFile = Files.createTempFile("UPLOAD_TEST", ".csv"); - - // Prerequisites - assertEquals(0, Files.list(sftpFolder).count()); - - // test phase - gateway.upload(tempFile.toFile()); - - // Validation phase - List paths = Files.list(sftpFolder).collect(Collectors.toList()); - assertEquals(1, paths.size()); - assertEquals(tempFile.getFileName(), paths.get(0).getFileName()); - } - - @AfterClass - public static void stopServer() { - if (server.isRunning()) { - server.stop(); - } - } - -}