INT-3919: FTP: Allow null for Remote Directory
JIRA: https://jira.spring.io/browse/INT-3919 Since `FtpClient` supports `null` for the `LS` command, treating it as a current `working directory`, there is no reason to forbid `null` from the FTP adapters end-user perspective. * Allow `null` for the `FtpSession` `list()` and `listNames()` methods * Allow `null` in the `remote-directory` for the `<int-ftp:inbound-channel-adapter>` * Allow `null` in the `expression` for the `FtpOutboundGateway` Polishing - send error if error on async output Cover `onFailure()` from `onSuccess()` with the `errorChannel` Address PR Comments * Get rid of `null` population for the `remoteDirectoryExpression` in the `AbstractPollingInboundChannelAdapterParser` * Populate `new LiteralExpression(null)` from the `FtpInboundFileSynchronizer` ctor * Introduce `buildRemotePath(parent, child)` function in the `AbstractRemoteFileOutboundGateway` with the `null` logic for `parent` * Rework `mGetWithoutRecursion()` to use `LS` command and allow `null` for the dir. * Fix tests according the new `mGetWithoutRecursion()` logic Polishing
This commit is contained in:
committed by
Gary Russell
parent
2fad35d9b8
commit
7595e4f142
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -82,6 +82,32 @@ public class FtpOutboundGateway extends AbstractRemoteFileOutboundGateway<FTPFil
|
||||
super(remoteFileTemplate, command, expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the supplied session factory, a command ('ls', 'get'
|
||||
* etc).
|
||||
* <p> The {@code remoteDirectory} expression is {@code null} assuming to use
|
||||
* the {@code workingDirectory} from the FTP Client.
|
||||
* @param sessionFactory the session factory.
|
||||
* @param command the command.
|
||||
* @since 4.3
|
||||
*/
|
||||
public FtpOutboundGateway(SessionFactory<FTPFile> sessionFactory, String command) {
|
||||
this(sessionFactory, command, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the supplied remote file template, a command ('ls',
|
||||
* 'get' etc).
|
||||
* <p> The {@code remoteDirectory} expression is {@code null} assuming to use
|
||||
* the {@code workingDirectory} from the FTP Client.
|
||||
* @param remoteFileTemplate the remote file template.
|
||||
* @param command the command.
|
||||
* @since 4.3
|
||||
*/
|
||||
public FtpOutboundGateway(RemoteFileTemplate<FTPFile> remoteFileTemplate, String command) {
|
||||
this(remoteFileTemplate, command, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComponentType() {
|
||||
return "ftp:outbound-gateway";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.ftp.inbound;
|
||||
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.integration.file.remote.session.Session;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer;
|
||||
@@ -40,9 +41,9 @@ public class FtpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<
|
||||
*/
|
||||
public FtpInboundFileSynchronizer(SessionFactory<FTPFile> sessionFactory) {
|
||||
super(sessionFactory);
|
||||
setRemoteDirectoryExpression(new LiteralExpression(null));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isFile(FTPFile file) {
|
||||
return file != null && file.isFile();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.integration.ftp.session;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -40,8 +39,6 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements SessionFactory<FTPFile> {
|
||||
|
||||
public static final String DEFAULT_REMOTE_WORKING_DIRECTORY = "/";
|
||||
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
protected FTPClientConfig config;
|
||||
@@ -172,7 +169,7 @@ public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements
|
||||
}
|
||||
}
|
||||
|
||||
private T createClient() throws SocketException, IOException {
|
||||
private T createClient() throws IOException {
|
||||
final T client = this.createClientInstance();
|
||||
Assert.notNull(client, "client must not be null");
|
||||
client.configure(this.config);
|
||||
@@ -200,7 +197,7 @@ public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements
|
||||
|
||||
// Login
|
||||
if (!client.login(username, password)) {
|
||||
throw new IllegalStateException("Login failed. The respponse from the server is: " +
|
||||
throw new IllegalStateException("Login failed. The response from the server is: " +
|
||||
client.getReplyString());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,6 +36,7 @@ import org.springframework.util.Assert;
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FtpSession implements Session<FTPFile> {
|
||||
@@ -55,22 +56,21 @@ public class FtpSession implements Session<FTPFile> {
|
||||
@Override
|
||||
public boolean remove(String path) throws IOException {
|
||||
Assert.hasText(path, "path must not be null");
|
||||
boolean completed = this.client.deleteFile(path);
|
||||
if (!completed) {
|
||||
if (!this.client.deleteFile(path)) {
|
||||
throw new IOException("Failed to delete '" + path + "'. Server replied with: " + client.getReplyString());
|
||||
}
|
||||
return completed;
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FTPFile[] list(String path) throws IOException {
|
||||
Assert.hasText(path, "path must not be null");
|
||||
return this.client.listFiles(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] listNames(String path) throws IOException {
|
||||
Assert.hasText(path, "path must not be null");
|
||||
return this.client.listNames(path);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public class FtpSession implements Session<FTPFile> {
|
||||
throw new IOException("Failed to copy '" + path +
|
||||
"'. Server replied with: " + this.client.getReplyString());
|
||||
}
|
||||
logger.info("File has been successfully transfered from: " + path);
|
||||
logger.info("File has been successfully transferred from: " + path);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,7 +93,8 @@ public class FtpSession implements Session<FTPFile> {
|
||||
}
|
||||
InputStream inputStream = this.client.retrieveFileStream(source);
|
||||
if (inputStream == null) {
|
||||
throw new IOException("Failed to obtain InputStream for remote file " + source + ": " + this.client.getReplyCode());
|
||||
throw new IOException("Failed to obtain InputStream for remote file " + source + ": "
|
||||
+ this.client.getReplyCode());
|
||||
}
|
||||
return inputStream;
|
||||
}
|
||||
@@ -123,7 +124,7 @@ public class FtpSession implements Session<FTPFile> {
|
||||
+ "'. Server replied with: " + this.client.getReplyString());
|
||||
}
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("File has been successfully transfered to: " + path);
|
||||
logger.info("File has been successfully transferred to: " + path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +197,8 @@ public class FtpSession implements Session<FTPFile> {
|
||||
Assert.hasText(path, "'path' must not be empty");
|
||||
|
||||
String currentWorkingPath = this.client.printWorkingDirectory();
|
||||
Assert.state(currentWorkingPath != null, "working directory cannot be determined, therefore exists check can not be completed");
|
||||
Assert.state(currentWorkingPath != null,
|
||||
"working directory cannot be determined, therefore exists check can not be completed");
|
||||
boolean exists = false;
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user