SFTP: Add channelConnectTimeout

While investigating an SI build failure, I noticed that there is
a timeout available for when connecting channels.

This won't resolve the build issue (where the session closed) but
worth adding as a property.
This commit is contained in:
Gary Russell
2019-05-09 12:01:00 -04:00
committed by Artem Bilan
parent bcff9d4089
commit 06140cb7ad
4 changed files with 41 additions and 6 deletions

View File

@@ -17,6 +17,7 @@
package org.springframework.integration.sftp.session;
import java.io.IOException;
import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.locks.Lock;
@@ -108,6 +109,8 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
private boolean allowUnknownKeys = false;
private Duration channelConnectTimeout;
private volatile JSchSessionWrapper sharedJschSession;
@@ -353,6 +356,16 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
this.allowUnknownKeys = allowUnknownKeys;
}
/**
* Set the connect timeout.
* @param timeout the timeout to set.
* @since 5.2
*/
public void setChannelConnectTimeout(Duration timeout) {
Assert.notNull(timeout, "'connectTimeout' cannot be null");
this.channelConnectTimeout = timeout;
}
@Override
public SftpSession getSession() {
JSchSessionWrapper jschSession = this.sharedJschSession;
@@ -367,6 +380,8 @@ public class DefaultSftpSessionFactory implements SessionFactory<LsEntry>, Share
freshJschSession = true;
}
sftpSession = new SftpSession(jschSession);
JavaUtils.INSTANCE
.acceptIfNotNull(this.channelConnectTimeout, sftpSession::setChannelConnectTimeout);
sftpSession.connect();
if (this.isSharedSession && freshJschSession) {
this.sharedJschSession = jschSession;

View File

@@ -19,6 +19,7 @@ package org.springframework.integration.sftp.session;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
@@ -51,12 +52,16 @@ public class SftpSession implements Session<LsEntry> {
private static final String SESSION_IS_NOT_CONNECTED = "session is not connected";
private static final Duration DEFAULT_CHANNEL_CONNECT_TIMEOUT = Duration.ofSeconds(5);
private final Log logger = LogFactory.getLog(this.getClass());
private final com.jcraft.jsch.Session jschSession;
private final JSchSessionWrapper wrapper;
private int channelConnectTimeout = (int) DEFAULT_CHANNEL_CONNECT_TIMEOUT.toMillis();
private volatile ChannelSftp channel;
private volatile boolean closed;
@@ -74,6 +79,16 @@ public class SftpSession implements Session<LsEntry> {
this.wrapper = wrapper;
}
/**
* Set the connect timeout.
* @param timeout the timeout to set.
* @since 5.2
*/
public void setChannelConnectTimeout(Duration timeout) {
Assert.notNull(timeout, "'timeout' cannot be null");
this.channelConnectTimeout = (int) timeout.toMillis();
}
@Override
public boolean remove(String path) throws IOException {
Assert.state(this.channel != null, SESSION_IS_NOT_CONNECTED);
@@ -146,7 +161,7 @@ public class SftpSession implements Session<LsEntry> {
}
@Override
public boolean finalizeRaw() throws IOException {
public boolean finalizeRaw() {
return true;
}
@@ -258,7 +273,7 @@ public class SftpSession implements Session<LsEntry> {
this.channel.lstat(path);
return true;
}
catch (SftpException e) {
catch (@SuppressWarnings("unused") SftpException e) {
// ignore
}
return false;
@@ -271,7 +286,7 @@ public class SftpSession implements Session<LsEntry> {
}
this.channel = (ChannelSftp) this.jschSession.openChannel("sftp");
if (this.channel != null && !this.channel.isConnected()) {
this.channel.connect();
this.channel.connect(this.channelConnectTimeout);
}
}
catch (JSchException e) {
@@ -295,7 +310,7 @@ public class SftpSession implements Session<LsEntry> {
this.channel.lstat(this.channel.getHome());
return true;
}
catch (Exception e) {
catch (@SuppressWarnings("unused") Exception e) {
return false;
}
}

View File

@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.willAnswer;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -380,7 +381,7 @@ public class SftpOutboundTests {
}
private void noopConnect(ChannelSftp channel1) throws JSchException {
doAnswer(invocation -> null).when(channel1).connect();
doNothing().when(channel1).connect(5000);
}
public static class TestSftpSessionFactory extends DefaultSftpSessionFactory {

View File

@@ -25,6 +25,7 @@ import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.time.Duration;
import java.util.Collections;
import org.apache.sshd.server.SshServer;
@@ -153,8 +154,11 @@ public class SftpSessionFactoryTests {
SshServer server = SshServer.setUpDefaultServer();
try {
DefaultSftpSessionFactory f = createServerAndClient(server);
f.setChannelConnectTimeout(Duration.ofSeconds(6));
f.setAllowUnknownKeys(true);
f.getSession().close();
SftpSession session = f.getSession();
assertThat(TestUtils.getPropertyValue(session, "channelConnectTimeout", Integer.class)).isEqualTo(6_000);
session.close();
}
finally {
server.stop(true);