INT-1614 polishing
This commit is contained in:
@@ -19,6 +19,8 @@ package org.springframework.integration.ftp.config;
|
||||
import org.springframework.integration.file.config.AbstractRemoteFileInboundChannelAdapterParser;
|
||||
|
||||
/**
|
||||
* Parser for the FTP 'inbound-channel-adapter' element.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,8 @@ import org.apache.commons.net.ftp.FTPFile;
|
||||
import org.springframework.integration.file.filters.AbstractRegexPatternFileListFilter;
|
||||
|
||||
/**
|
||||
* Implementation of {@link AbstractRegexPatternFileListFilter} for FTP.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,8 @@ import org.apache.commons.net.ftp.FTPFile;
|
||||
import org.springframework.integration.file.filters.AbstractSimplePatternFileListFilter;
|
||||
|
||||
/**
|
||||
* Implementation of {@link AbstractSimplePatternFileListFilter} for FTP.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
@@ -23,10 +23,12 @@ import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer;
|
||||
|
||||
/**
|
||||
* An FTP-adapter implementation of {@link org.springframework.integration.file.synchronization.AbstractInboundRemoteFileSystemSychronizer}
|
||||
* An implementation of {@link AbstractInboundFileSynchronizer} for FTP.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
* @author Josh Long
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FtpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<FTPFile> {
|
||||
|
||||
@@ -40,12 +42,12 @@ public class FtpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<
|
||||
|
||||
@Override
|
||||
protected boolean isFile(FTPFile file) {
|
||||
return file.isFile();
|
||||
return file != null && file.isFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFilename(FTPFile file) {
|
||||
return file.getName();
|
||||
return (file != null ? file.getName() : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,11 +26,12 @@ import org.springframework.integration.file.remote.synchronizer.AbstractInboundF
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
* @author Josh Long
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FtpInboundFileSynchronizingMessageSource extends AbstractInboundFileSynchronizingMessageSource<FTPFile> {
|
||||
|
||||
public FtpInboundFileSynchronizingMessageSource( AbstractInboundFileSynchronizer<FTPFile> synchronizer) {
|
||||
public FtpInboundFileSynchronizingMessageSource(AbstractInboundFileSynchronizer<FTPFile> synchronizer) {
|
||||
super(synchronizer);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,12 +30,13 @@ import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.file.remote.session.Session;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for FTP SessionFactory implementations.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements SessionFactory {
|
||||
|
||||
@@ -56,8 +57,6 @@ public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements
|
||||
|
||||
protected String remoteWorkingDirectory = DEFAULT_REMOTE_WORKING_DIRECTORY;
|
||||
|
||||
|
||||
|
||||
protected int clientMode = FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE;
|
||||
|
||||
protected int fileType = FTP.BINARY_FILE_TYPE;
|
||||
@@ -127,20 +126,6 @@ public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements
|
||||
this.clientMode = clientMode;
|
||||
}
|
||||
|
||||
protected abstract T createSingleInstanceOfClient();
|
||||
|
||||
/**
|
||||
* this is a hook to setup the state of the {@link org.apache.commons.net.ftp.FTPClient} impl *after* the
|
||||
* implementation's {@link org.apache.commons.net.ftp.FTPClient#connect(String)} method's been called but before any
|
||||
* action's been taken.
|
||||
*
|
||||
* @param t the ftp client instance on which to act
|
||||
* @throws IOException if anything should go wrong
|
||||
*/
|
||||
protected void onAfterConnect(T t) throws IOException {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
public Session getSession() {
|
||||
try {
|
||||
T client = this.createClient();
|
||||
@@ -154,47 +139,39 @@ public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements
|
||||
}
|
||||
}
|
||||
|
||||
T createClient() throws SocketException, IOException {
|
||||
T client = createSingleInstanceOfClient();
|
||||
client.configure(config);
|
||||
|
||||
if (!StringUtils.hasText(username)) {
|
||||
throw new MessagingException("username is required");
|
||||
}
|
||||
|
||||
client.connect(host);
|
||||
onAfterConnect(client);
|
||||
|
||||
private T createClient() throws SocketException, IOException {
|
||||
T client = this.createClientInstance();
|
||||
Assert.notNull(client, "client must not be null");
|
||||
client.configure(this.config);
|
||||
Assert.hasText(this.username, "username is required");
|
||||
client.connect(this.host);
|
||||
this.afterConnect(client);
|
||||
if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
|
||||
throw new MessagingException("Connecting to server [" + host + ":" +
|
||||
port + "] failed, please check the connection");
|
||||
throw new MessagingException("Connecting to server [" +
|
||||
this.host + ":" + this.port + "] failed. Please check the connection.");
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Connected to server [" + host + ":" + port + "]");
|
||||
logger.debug("Connected to server [" + this.host + ":" + this.port + "]");
|
||||
}
|
||||
|
||||
if (!client.login(username, password)) {
|
||||
throw new MessagingException(
|
||||
"Login failed. Please check the username and password.");
|
||||
}
|
||||
|
||||
this.updateClientMode(client);
|
||||
client.setFileType(this.fileType);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("login successful");
|
||||
}
|
||||
|
||||
if (!remoteWorkingDirectory.equals(client.printWorkingDirectory()) &&
|
||||
!client.changeWorkingDirectory(remoteWorkingDirectory)) {
|
||||
if (!this.remoteWorkingDirectory.equals(client.printWorkingDirectory()) &&
|
||||
!client.changeWorkingDirectory(this.remoteWorkingDirectory)) {
|
||||
throw new MessagingException("Could not change directory to '" +
|
||||
remoteWorkingDirectory + "'. Please check the path.");
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("working directory is: " +
|
||||
client.printWorkingDirectory());
|
||||
logger.debug("working directory is: " + client.printWorkingDirectory());
|
||||
}
|
||||
if (client != null) {
|
||||
this.postProcessClient(client);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
@@ -203,7 +180,7 @@ public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements
|
||||
* Sets the mode of the connection. Only local modes are supported.
|
||||
*/
|
||||
private void updateClientMode(FTPClient client) {
|
||||
switch (clientMode) {
|
||||
switch (this.clientMode) {
|
||||
case FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE:
|
||||
client.enterLocalActiveMode();
|
||||
break;
|
||||
@@ -215,4 +192,22 @@ public abstract class AbstractFtpSessionFactory<T extends FTPClient> implements
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract T createClientInstance();
|
||||
|
||||
/**
|
||||
* this is a hook to setup the state of the {@link org.apache.commons.net.ftp.FTPClient} impl *after* the
|
||||
* implementation's {@link org.apache.commons.net.ftp.FTPClient#connect(String)} method's been called but before any
|
||||
* action's been taken.
|
||||
*
|
||||
* @param t the ftp client instance on which to act
|
||||
* @throws IOException if anything should go wrong
|
||||
*/
|
||||
protected void afterConnect(T t) throws IOException {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
protected void postProcessClient(T t) throws IOException {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ package org.springframework.integration.ftp.session;
|
||||
|
||||
import org.apache.commons.net.ftp.FTPClient;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of FtpClientFactory.
|
||||
* Default implementation of FTP SessionFactory.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
* @author Josh Long
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DefaultFtpSessionFactory extends AbstractFtpSessionFactory<FTPClient> {
|
||||
|
||||
@Override
|
||||
protected FTPClient createSingleInstanceOfClient() {
|
||||
protected FTPClient createClientInstance() {
|
||||
return new FTPClient();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,10 +27,12 @@ import org.apache.commons.net.ftp.FTPSClient;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* provides a working FTPS implementation. Based heavily on {@link org.springframework.integration.ftp.session.DefaultFtpSessionFactory}
|
||||
* SessionFactory for FTPS.
|
||||
*
|
||||
* @author Josh Long
|
||||
* @author Iwein Fuld
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DefaultFtpsSessionFactory extends AbstractFtpSessionFactory<FTPSClient> {
|
||||
|
||||
@@ -108,14 +110,26 @@ public class DefaultFtpsSessionFactory extends AbstractFtpSessionFactory<FTPSCli
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAfterConnect(FTPSClient ftpsClient) throws IOException {
|
||||
protected FTPSClient createClientInstance() {
|
||||
try {
|
||||
if (StringUtils.hasText(this.protocol)) {
|
||||
return new FTPSClient(this.protocol, this.implicit);
|
||||
}
|
||||
return new FTPSClient(this.implicit);
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterConnect(FTPSClient ftpsClient) throws IOException {
|
||||
ftpsClient.execPBSZ(0);
|
||||
ftpsClient.execPROT(this.prot);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FTPSClient createClient() throws IOException {
|
||||
FTPSClient ftpsClient = super.createClient();
|
||||
protected void postProcessClient(FTPSClient ftpsClient) throws IOException {
|
||||
if (StringUtils.hasText(this.authValue)) {
|
||||
ftpsClient.setAuthValue(authValue);
|
||||
}
|
||||
@@ -146,20 +160,6 @@ public class DefaultFtpsSessionFactory extends AbstractFtpSessionFactory<FTPSCli
|
||||
if (this.wantsClientAuth != null) {
|
||||
ftpsClient.setWantClientAuth(this.wantsClientAuth);
|
||||
}
|
||||
return ftpsClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FTPSClient createSingleInstanceOfClient() {
|
||||
try {
|
||||
if (StringUtils.hasText(this.protocol)) {
|
||||
return new FTPSClient(this.protocol, this.implicit);
|
||||
}
|
||||
return new FTPSClient(this.implicit);
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ import org.springframework.integration.file.remote.session.Session;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of {@link Session} for FTP.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -78,7 +80,7 @@ class FtpSession implements Session {
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("failed to disconnect FTPClient", e);
|
||||
logger.warn("failed to retrieve file", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -99,7 +101,7 @@ class FtpSession implements Session {
|
||||
try {
|
||||
this.client.disconnect();
|
||||
}
|
||||
catch (IOException e) {
|
||||
catch (Exception e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("failed to disconnect FTPClient", e);
|
||||
}
|
||||
|
||||
@@ -99,11 +99,12 @@ public class FtpInboundRemoteFileSystemSynchronizerTest {
|
||||
assertTrue(new File("test/a.test").exists());
|
||||
assertTrue(new File("test/b.test").exists());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class TestFtpSessionFactory extends AbstractFtpSessionFactory<FTPClient> {
|
||||
|
||||
@Override
|
||||
protected FTPClient createSingleInstanceOfClient() {
|
||||
protected FTPClient createClientInstance() {
|
||||
try {
|
||||
when(ftpClient.getReplyCode()).thenReturn(250);
|
||||
when(ftpClient.login("kermit", "frog")).thenReturn(true);
|
||||
|
||||
@@ -114,11 +114,12 @@ public class FtpSendingMessageHandlerTest {
|
||||
handler.handleMessage(new GenericMessage<File>(new File("template.mf")));
|
||||
assertTrue(file.exists());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static class TestFtpSessionFactory extends AbstractFtpSessionFactory<FTPClient> {
|
||||
|
||||
@Override
|
||||
protected FTPClient createSingleInstanceOfClient() {
|
||||
protected FTPClient createClientInstance() {
|
||||
try {
|
||||
when(ftpClient.getReplyCode()).thenReturn(250);
|
||||
when(ftpClient.login("kermit", "frog")).thenReturn(true);
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<LsEntry> {
|
||||
public class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<LsEntry> {
|
||||
|
||||
public SftpInboundFileSynchronizer(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
@@ -43,7 +43,7 @@ class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<LsEntr
|
||||
|
||||
@Override
|
||||
protected String getFilename(LsEntry file) {
|
||||
return file.getFilename();
|
||||
return (file != null ? file.getFilename() : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class SftpSession implements Session {
|
||||
}
|
||||
catch (SftpException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("rm failed", e);
|
||||
logger.warn("failed to remove file", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class SftpSession implements Session {
|
||||
}
|
||||
catch (SftpException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("ls failed", e);
|
||||
logger.warn("failed to list files", e);
|
||||
}
|
||||
}
|
||||
return new LsEntry[0];
|
||||
@@ -97,7 +97,7 @@ class SftpSession implements Session {
|
||||
}
|
||||
catch (SftpException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("get failed", e);
|
||||
logger.warn("failed to retrieve file", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -110,7 +110,7 @@ class SftpSession implements Session {
|
||||
}
|
||||
catch (SftpException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("put failed", e);
|
||||
logger.warn("failed to copy file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user