Skip to content

Commit 10e79ba

Browse files
committed
GH-8713: Add support for custom SftpClient
Fixes #8713 * Introduce `DefaultSftpSessionFactory.createSftpClient()` factory method which can be overridden for any custom `SftpClient` use-case * Add changes to the docs * Some code clean up **Cherry-pick to `6.1.x`**
1 parent eafedaa commit 10e79ba

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

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

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@
5353

5454
/**
5555
* Factory for creating {@link SftpSession} instances.
56+
* <p>
57+
* The {@link #createSftpClient(ClientSession, SftpVersionSelector, SftpErrorDataHandler)}
58+
* can be overridden to provide a custom {@link SftpClient}.
59+
* The {@link ConcurrentSftpClient} is used by default.
5660
*
5761
* @author Josh Long
5862
* @author Mario Gray
@@ -65,6 +69,7 @@
6569
* @author Krzysztof Debski
6670
* @author Auke Zaaiman
6771
* @author Christian Tzolov
72+
* @author Adama Sorho
6873
*
6974
* @since 2.0
7075
*/
@@ -282,9 +287,7 @@ public SftpSession getSession() {
282287
try {
283288
boolean freshSftpClient = false;
284289
if (sftpClient == null || !sftpClient.isOpen()) {
285-
sftpClient =
286-
new ConcurrentSftpClient(initClientSession(), this.sftpVersionSelector,
287-
SftpErrorDataHandler.EMPTY);
290+
sftpClient = createSftpClient(initClientSession(), this.sftpVersionSelector, SftpErrorDataHandler.EMPTY);
288291
freshSftpClient = true;
289292
}
290293
sftpSession = new SftpSession(sftpClient);
@@ -293,8 +296,8 @@ public SftpSession getSession() {
293296
this.sharedSftpClient = sftpClient;
294297
}
295298
}
296-
catch (Exception e) {
297-
throw new IllegalStateException("failed to create SFTP Session", e);
299+
catch (Exception ex) {
300+
throw new IllegalStateException("failed to create SFTP Session", ex);
298301
}
299302
finally {
300303
if (this.sharedSessionLock != null) {
@@ -397,15 +400,32 @@ public void resetSharedSession() {
397400
this.sharedSftpClient = null;
398401
}
399402

403+
/**
404+
* Can be overridden to provide a custom {@link SftpClient} to {@link #getSession()}.
405+
* @param clientSession the {@link ClientSession}
406+
* @param initialVersionSelector the initial {@link SftpVersionSelector}
407+
* @param errorDataHandler the {@link SftpErrorDataHandler} to handle incoming data
408+
* through the error stream.
409+
* @return {@link SftpClient}
410+
* @throws IOException if failed to initialize
411+
* @since 6.1.3
412+
*/
413+
protected SftpClient createSftpClient(
414+
ClientSession clientSession, SftpVersionSelector initialVersionSelector,
415+
SftpErrorDataHandler errorDataHandler) throws IOException {
416+
417+
return new ConcurrentSftpClient(clientSession, initialVersionSelector, errorDataHandler);
418+
}
419+
400420
/**
401421
* The {@link DefaultSftpClient} extension to lock the {@link #send(int, Buffer)}
402422
* for concurrent interaction.
403423
*/
404-
private static class ConcurrentSftpClient extends DefaultSftpClient {
424+
protected static class ConcurrentSftpClient extends DefaultSftpClient {
405425

406426
private final Lock sendLock = new ReentrantLock();
407427

408-
ConcurrentSftpClient(ClientSession clientSession, SftpVersionSelector initialVersionSelector,
428+
protected ConcurrentSftpClient(ClientSession clientSession, SftpVersionSelector initialVersionSelector,
409429
SftpErrorDataHandler errorDataHandler) throws IOException {
410430

411431
super(clientSession, initialVersionSelector, errorDataHandler);

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,26 @@ When using this feature, you must wrap the session factory in a caching session
3838
3939
If the cache is reset, the session is disconnected only when the last channel is closed.
4040
41-
The connection is refreshed if it is found to be disconnected when a new operation obtains a session.
41+
The connection is refreshed if it to be disconnected when a new operation obtains a session.
4242
=====
4343

4444
Now all you need to do is inject this SFTP session factory into your adapters.
4545

4646
NOTE: A more practical way to provide values for the SFTP session factory is to use Spring's https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-placeholderconfigurer[property placeholder support].
4747

48+
Starting with version 6.1.3, the `DefaultSftpSessionFactory` introduces a `createSftpClient(...)` to support a custom `SftpClient`.
49+
See a sample below of how to override `createSftpChannelSubsystem()` method in your custom `SftpClient` to add, for example, some custom `RequestHandler` for SFTP sub-system requests and replies:
50+
51+
[source, java]
52+
----
53+
@Override
54+
protected ChannelSubsystem createSftpChannelSubsystem(ClientSession clientSession) {
55+
ChannelSubsystem sftpChannelSubsystem = super.createSftpChannelSubsystem(clientSession);
56+
sftpChannelSubsystem.addRequestHandler((channel, request, wantReply, buffer) -> ...);
57+
return sftpChannelSubsystem;
58+
}
59+
----
60+
4861
[[sftp-session-factory-properties]]
4962
== Configuration Properties
5063

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,9 @@ See xref:mongodb.adoc#mongodb-message-store[MongoDB Message Store] for an exampl
7272

7373
`FtpLastModifiedFileListFilter`, `SftpLastModifiedFileListFilter` and `SmbLastModifiedFileListFilter` have been introduced to allow files filtering based on a last-modified strategy respectively for `FTP`, `SFTP` and `SMB`.
7474
See xref:ftp/inbound.adoc#ftp-inbound[FTP Inbound Channel Adapter], xref:sftp/inbound.adoc#sftp-inbound[SFTP Inbound Channel Adapter], and xref:smb.adoc#smb-inbound[SMB Inbound Channel Adapter] for more information.
75+
76+
[[x6.2-sftp-changes]]
77+
=== SFTP Support Changes
78+
79+
A new `DefaultSftpSessionFactory.createSftpClient(...)` method has been introduced to support a custom `SftpClient` when overridden.
80+
See xref:sftp/session-factory.adoc#sftp-session-factory[SFTP Session Factory] for more information.

0 commit comments

Comments
 (0)