@Test public void testOutbound() throws Exception{ final String sourceFileName = "README.md"; final String destinationFileName = sourceFileName +"_foo"; final ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("/META-INF/spring/integration/SftpOutboundTransferSample-context.xml", SftpOutboundTransferSample.class); @SuppressWarnings("unchecked") SessionFactory<LsEntry> sessionFactory = ac.getBean(CachingSessionFactory.class); RemoteFileTemplate<LsEntry> template = new RemoteFileTemplate<LsEntry>(sessionFactory); SftpTestUtils.createTestFiles(template); // Just the directory try { final File file = new File(sourceFileName); Assert.isTrue(file.exists(), String.format("File '%s' does not exist.", sourceFileName)); final Message<File> message = MessageBuilder.withPayload(file).build(); final MessageChannel inputChannel = ac.getBean("inputChannel", MessageChannel.class); inputChannel.send(message); Thread.sleep(2000); Assert.isTrue(SftpTestUtils.fileExists(template, destinationFileName), String.format("File '%s' does not exist.", destinationFileName)); System.out.println(String.format("Successfully transferred '%s' file to a " + "remote location under the name '%s'", sourceFileName, destinationFileName)); } finally { SftpTestUtils.cleanUp(template, destinationFileName); ac.close(); } }
public static void cleanUp(RemoteFileTemplate<LsEntry> template, final String... fileNames) { if (template != null) { template.execute((SessionCallback<LsEntry, Void>) session -> { for (int i = 0; i < fileNames.length; i++) { try { session.remove("si.sftp.sample/" + fileNames[i]); } catch (IOException e) {} } // should be empty session.rmdir("si.sftp.sample"); return null; }); } }
/** * @see #setFileNameExpression(Expression) */ @Override public boolean get(Message<?> message, InputStreamCallback callback) { Assert.notNull(this.fileNameProcessor, "A 'fileNameExpression' is needed to use get"); String remotePath = this.fileNameProcessor.processMessage(message); return this.get(remotePath, callback); }
@Override protected void onInit() { this.remoteFileTemplate.setBeanFactory(this.getBeanFactory()); this.remoteFileTemplate.afterPropertiesSet(); }
@SuppressWarnings("unchecked") @Before public void setUp() throws Exception { SessionFactory<Object> sessionFactory = mock(SessionFactory.class); this.template = new RemoteFileTemplate<Object>(sessionFactory); this.template.setRemoteDirectoryExpression(new LiteralExpression("/foo")); this.template.setBeanFactory(mock(BeanFactory.class)); this.template.afterPropertiesSet(); this.session = mock(Session.class); when(sessionFactory.getSession()).thenReturn(this.session); this.file = this.folder.newFile(); }
@Test public void testRawGETWithTemplate() throws Exception { RemoteFileTemplate<FTPFile> template = new RemoteFileTemplate<FTPFile>(this.ftpSessionFactory); template.setFileNameExpression(new SpelExpressionParser().parseExpression("payload")); template.setBeanFactory(mock(BeanFactory.class)); template.afterPropertiesSet(); final ByteArrayOutputStream baos1 = new ByteArrayOutputStream(); assertTrue(template.get(new GenericMessage<String>("ftpSource/ ftpSource1.txt"), (InputStreamCallback) stream -> FileCopyUtils.copy(stream, baos1))); assertEquals("source1", new String(baos1.toByteArray())); final ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); assertTrue(template.get(new GenericMessage<String>("ftpSource/ftpSource2.txt"), (InputStreamCallback) stream -> FileCopyUtils.copy(stream, baos2))); assertEquals("source2", new String(baos2.toByteArray())); }
@Test public void testFtpOutboundFlow() { IntegrationFlow flow = f -> f .handle(Ftp.outboundAdapter(sessionFactory(), FileExistsMode.FAIL) .useTemporaryFileName(false) .fileNameExpression("headers['" + FileHeaders.FILENAME + "']") .remoteDirectory("ftpTarget")); IntegrationFlowRegistration registration = this.flowContext.registration(flow).register(); String fileName = "foo.file"; Message<ByteArrayInputStream> message = MessageBuilder .withPayload(new ByteArrayInputStream("foo".getBytes(StandardCharsets.UTF_8))) .setHeader(FileHeaders.FILENAME, fileName) .build(); registration.getInputChannel().send(message); RemoteFileTemplate<FTPFile> template = new RemoteFileTemplate<>(sessionFactory()); FTPFile[] files = template.execute(session -> session.list(getTargetRemoteDirectory().getName() + "/" + fileName)); assertEquals(1, files.length); assertEquals(3, files[0].getSize()); registration.destroy(); }
template.setRemoteDirectoryExpression(new LiteralExpression("foo/")); template.setBeanFactory(mock(BeanFactory.class)); template.afterPropertiesSet(); TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway(template, "put", "payload"); FileTransferringMessageHandler<TestLsEntry> handler = new FileTransferringMessageHandler<TestLsEntry>(sessionFactory);
private String send(final Message<?> message, final String subDirectory, final FileExistsMode mode) { Assert.notNull(this.directoryExpressionProcessor, "'remoteDirectoryExpression' is required"); Assert.isTrue(!FileExistsMode.APPEND.equals(mode) || !this.useTemporaryFileName, "Cannot append when using a temporary file name"); Assert.isTrue(!FileExistsMode.REPLACE_IF_MODIFIED.equals(mode), "FilExistsMode.REPLACE_IF_MODIFIED can only be used for local files"); final StreamHolder inputStreamHolder = payloadToInputStream(message); if (inputStreamHolder != null) { try { return execute(session -> doSend(message, subDirectory, mode, inputStreamHolder, session)); } finally { try { inputStreamHolder.stream.close(); } catch (IOException e) { } } } else { // A null holder means a File payload that does not exist. if (this.logger.isWarnEnabled()) { this.logger.warn("File " + message.getPayload() + " does not exist"); } return null; } }
assertEquals("test remove .writing", e.getCause().getMessage()); @SuppressWarnings("unchecked") RemoteFileTemplate template = new RemoteFileTemplate(sessionFactory); File outFile = new File(this.tmpDir + "/f1" + template.getTemporaryFileSuffix()); assertFalse(outFile.exists());
private Object doNlst(Message<?> requestMessage) { String dir = this.fileNameProcessor != null ? this.fileNameProcessor.processMessage(requestMessage) : null; if (dir != null && !dir.endsWith(this.remoteFileTemplate.getRemoteFileSeparator())) { dir += this.remoteFileTemplate.getRemoteFileSeparator(); } final String fullDir = dir; List<?> payload = this.remoteFileTemplate.execute(session -> nlst(requestMessage, session, fullDir)); return getMessageBuilderFactory() .withPayload(payload) .setHeader(FileHeaders.REMOTE_DIRECTORY, dir); }
private Object doGet(final Message<?> requestMessage) { final String remoteFilePath = this.fileNameProcessor.processMessage(requestMessage); final String remoteFilename = getRemoteFilename(remoteFilePath); final String remoteDir = getRemoteDirectory(remoteFilePath, remoteFilename); Session<F> session = null; Object payload; if (this.options.contains(Option.STREAM)) { session = this.remoteFileTemplate.getSessionFactory().getSession(); try { payload = session.readRaw(remoteFilePath); } catch (IOException e) { throw new MessageHandlingException(requestMessage, "Failed to get the remote file [" + remoteFilePath + "] as a stream", e); } } else { payload = this.remoteFileTemplate.execute(session1 -> get(requestMessage, session1, remoteDir, remoteFilePath, remoteFilename, null)); } return getMessageBuilderFactory() .withPayload(payload) .setHeader(FileHeaders.REMOTE_DIRECTORY, remoteDir) .setHeader(FileHeaders.REMOTE_FILE, remoteFilename) .setHeader(IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE, session); }
@Override public String send(final Message<?> message, String subDirectory, FileExistsMode... mode) { FileExistsMode modeToUse = mode == null || mode.length < 1 || mode[0] == null ? FileExistsMode.REPLACE : mode[0]; return send(message, subDirectory, modeToUse); }
@Override protected Object doReceive() { AbstractFileInfo<F> file = poll(); if (file != null) { String remotePath = remotePath(file); Session<?> session = this.remoteFileTemplate.getSession(); try { return getMessageBuilderFactory() .withPayload(session.readRaw(remotePath)) .setHeader(IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE, session) .setHeader(FileHeaders.REMOTE_DIRECTORY, file.getRemoteDirectory()) .setHeader(FileHeaders.REMOTE_FILE, file.getFilename()) .setHeader(FileHeaders.REMOTE_FILE_INFO, this.fileInfoJson ? file.toJson() : file); } catch (IOException e) { throw new MessagingException("IOException when retrieving " + remotePath, e); } } return null; }
@Test public void testAppend() throws Exception { this.template.setUseTemporaryFileName(false); this.template.send(new GenericMessage<File>(this.file), FileExistsMode.APPEND); verify(this.session).append(Mockito.any(InputStream.class), Mockito.anyString()); }
this.remoteFileTemplate.setBeanFactory(getBeanFactory());
@Override protected void doChmod(RemoteFileTemplate<LsEntry> remoteFileTemplate, final String path, final int chmod) { remoteFileTemplate.executeWithClient((ClientCallbackWithoutResult<ChannelSftp>) client -> { try { client.chmod(chmod, path); } catch (SftpException e) { throw new GeneralSftpException("Failed to execute chmod", e); } }); }
protected String getTemporaryFileSuffix() { return this.remoteFileTemplate.getTemporaryFileSuffix(); }
@SuppressWarnings("unchecked") Session<TestLsEntry> session = mock(Session.class); RemoteFileTemplate<TestLsEntry> template = new RemoteFileTemplate<TestLsEntry>(sessionFactory); template.setRemoteDirectoryExpression(new LiteralExpression("foo/")); template.setBeanFactory(mock(BeanFactory.class)); template.afterPropertiesSet(); TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway(template, "mput", "payload"); gw.afterPropertiesSet();
@Test public void testDirtySession() throws Exception { @SuppressWarnings("unchecked") SessionFactory<Object> factory = mock(SessionFactory.class); @SuppressWarnings("unchecked") Session<Object> session = mock(Session.class); when(factory.getSession()).thenReturn(session); when(session.readRaw("foo")).thenReturn(new ByteArrayInputStream("".getBytes())); when(session.finalizeRaw()).thenReturn(true); CachingSessionFactory<Object> ccf = new CachingSessionFactory<Object>(factory); RemoteFileTemplate<Object> template = new RemoteFileTemplate<Object>(ccf); template.setFileNameExpression(new LiteralExpression("foo")); template.setBeanFactory(mock(BeanFactory.class)); template.afterPropertiesSet(); try { template.get(new GenericMessage<String>("foo"), (InputStreamCallback) stream -> { throw new RuntimeException("bar"); }); fail("Expected exception"); } catch (Exception e) { assertThat(e.getCause(), instanceOf(RuntimeException.class)); assertThat(e.getCause().getMessage(), equalTo("bar")); } verify(session).close(); }