Skip to content

Commit 57c98e1

Browse files
committed
GH-9380: Add DefaultSftpSessionFactory.setSshClientConfigurer()
Fixes: #9380 Expose a `Consumer<SshClient> sshClientConfigurer` option for the `DefaultSftpSessionFactory` to further customize an internal `SshClient` instance.
1 parent e332ce9 commit 57c98e1

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-4
lines changed

spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/DefaultSftpSessionFactory.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Collection;
2525
import java.util.concurrent.locks.Lock;
2626
import java.util.concurrent.locks.ReentrantLock;
27+
import java.util.function.Consumer;
2728

2829
import org.apache.sshd.client.SshClient;
2930
import org.apache.sshd.client.auth.keyboard.UserInteraction;
@@ -79,7 +80,8 @@
7980
*
8081
* @since 2.0
8182
*/
82-
public class DefaultSftpSessionFactory implements SessionFactory<SftpClient.DirEntry>, SharedSessionCapable, DisposableBean {
83+
public class DefaultSftpSessionFactory
84+
implements SessionFactory<SftpClient.DirEntry>, SharedSessionCapable, DisposableBean {
8385

8486
private final Lock lock = new ReentrantLock();
8587

@@ -119,6 +121,9 @@ public class DefaultSftpSessionFactory implements SessionFactory<SftpClient.DirE
119121

120122
private volatile SftpClient sharedSftpClient;
121123

124+
private Consumer<SshClient> sshClientConfigurer = (sshClient) -> {
125+
};
126+
122127
public DefaultSftpSessionFactory() {
123128
this(false);
124129
}
@@ -283,6 +288,20 @@ public void setSftpVersionSelector(SftpVersionSelector sftpVersionSelector) {
283288
this.sftpVersionSelector = sftpVersionSelector;
284289
}
285290

291+
/**
292+
* Set a {@link Consumer} as a callback to further customize an internal {@link SshClient} instance.
293+
* For example, to set custom values for its properties using {@link PropertyResolverUtils#updateProperty} API.
294+
* @param sshClientConfigurer the {@link Consumer} to configure an internal {@link SshClient} instance.
295+
* @since 6.4
296+
* @see SshClient
297+
* @see PropertyResolverUtils#updateProperty
298+
*/
299+
public void setSshClientConfigurer(Consumer<SshClient> sshClientConfigurer) {
300+
Assert.state(this.isInnerClient, "Cannot mutate externally provided SshClient");
301+
Assert.notNull(sshClientConfigurer, "'sshClientConfigurer' must noy be null");
302+
this.sshClientConfigurer = sshClientConfigurer;
303+
}
304+
286305
@Override
287306
public SftpSession getSession() {
288307
SftpSession sftpSession;
@@ -392,6 +411,7 @@ public InputStream openInputStream() throws IOException {
392411
}
393412
}
394413
this.sshClient.setUserInteraction(this.userInteraction);
414+
this.sshClientConfigurer.accept(this.sshClient);
395415
}
396416
}
397417

@@ -424,7 +444,7 @@ protected SftpClient createSftpClient(
424444
}
425445

426446
@Override
427-
public void destroy() throws Exception {
447+
public void destroy() {
428448
if (this.isInnerClient && this.sshClient != null && this.sshClient.isStarted()) {
429449
this.sshClient.stop();
430450
}

spring-integration-sftp/src/test/java/org/springframework/integration/sftp/session/SftpSessionFactoryTests.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
import org.apache.sshd.client.channel.ClientChannel;
3232
import org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier;
3333
import org.apache.sshd.client.session.ClientSession;
34+
import org.apache.sshd.common.PropertyResolverUtils;
3435
import org.apache.sshd.common.SshException;
36+
import org.apache.sshd.core.CoreModuleProperties;
3537
import org.apache.sshd.server.SshServer;
3638
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
3739
import org.apache.sshd.sftp.client.SftpClient;
@@ -206,7 +208,7 @@ void concurrentSessionListDoesntCauseFailure() throws Exception {
206208
}
207209

208210
@Test
209-
void customTimeoutIsApplied() throws Exception {
211+
void customPropertiesAreApplied() throws Exception {
210212
try (SshServer server = SshServer.setUpDefaultServer()) {
211213
server.setPasswordAuthenticator((arg0, arg1, arg2) -> true);
212214
server.setPort(0);
@@ -221,10 +223,15 @@ void customTimeoutIsApplied() throws Exception {
221223
sftpSessionFactory.setPassword("pass");
222224
sftpSessionFactory.setAllowUnknownKeys(true);
223225
sftpSessionFactory.setTimeout(15_000);
226+
sftpSessionFactory.setSshClientConfigurer((sshClient) -> {
227+
sshClient.setNioWorkers(27);
228+
PropertyResolverUtils.updateProperty(sshClient, CoreModuleProperties.MAX_PACKET_SIZE.getName(), 48 * 1024);
229+
});
224230

225231
ClientChannel clientChannel = sftpSessionFactory.getSession().getClientInstance().getClientChannel();
226232

227233
assertThat(AbstractSftpClient.SFTP_CLIENT_CMD_TIMEOUT.getRequired(clientChannel)).hasSeconds(15);
234+
assertThat(CoreModuleProperties.MAX_PACKET_SIZE.getRequired(clientChannel)).isEqualTo(48 * 1024);
228235

229236
sftpSessionFactory.destroy();
230237
}
@@ -260,4 +267,5 @@ void clientSessionIsClosedOnSessionClose() throws Exception {
260267
sftpSessionFactory.destroy();
261268
}
262269
}
270+
263271
}

src/reference/antora/modules/ROOT/pages/sftp/session-factory.adoc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,13 @@ If `false`, a pre-populated `knownHosts` file is required.
107107

108108
`userInteraction`::A custom `org.apache.sshd.client.auth.keyboard.UserInteraction` to be used during authentication.
109109

110+
Starting with version 6.4, the `DefaultSftpSessionFactory` expose a `Consumer<SshClient>` configurer property to further customize an internal `SshClient`.
111+
For example, this is how to change a default number of NIO workers and packet size for the client:
112+
113+
[source, java]
114+
----
115+
sftpSessionFactory.setSshClientConfigurer((sshClient) -> {
116+
sshClient.setNioWorkers(27);
117+
PropertyResolverUtils.updateProperty(sshClient, CoreModuleProperties.MAX_PACKET_SIZE.getName(), 48 * 1024);
118+
});
119+
----

src/reference/antora/modules/ROOT/pages/whats-new.adoc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,10 @@ See xref:redis.adoc[Redis Support] for more information.
5959
=== Groovy Changes
6060

6161
The `ControlBusFactoryBean` (and respective `<int-groovy:control-bus>` XML tag) has been deprecated (for removal) in favor of new introduced `ControlBusFactoryBean` based on a new model implemented in the `ControlBusCommandRegistry`.
62-
See xref:control-bus.adoc[Control Bus] for more information.
62+
See xref:control-bus.adoc[Control Bus] for more information.
63+
64+
[[x6.4-sftp-changes]]
65+
=== SFTP Support Changes
66+
67+
The `DefaultSftpSessionFactory` now exposes a `Consumer<SshClient>` configurer property to further customize an internal `SshClient`.
68+
See xref:sftp/session-factory.adoc[SFTP Session Factory] for more information.

0 commit comments

Comments
 (0)