Skip to content

Commit

Permalink
GH-9427: Improve nullability for remote path expression (#9434)
Browse files Browse the repository at this point in the history
Fixes: #9427

Issue link: #9427

The `expression` of the `AbstractRemoteFileOutboundGateway` could be `null` and
ignored for some expressions making a DSL factories inconsistent

* Improve `AbstractRemoteFileOutboundGateway` constructor JavaDocs explaining
`expression` argument in more details
* Add `@Nullable` for this `expression` arg in all the `AbstractRemoteFileOutboundGateway` implementations
* Add new DSL factory method for `outboundGateway()` without this `expression` for those commands when it is not needed
  • Loading branch information
artembilan authored Aug 30, 2024
1 parent dc02dec commit c27cc4b
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,14 @@ public AbstractRemoteFileOutboundGateway(RemoteFileTemplate<F> remoteFileTemplat

/**
* Construct an instance with the supplied session factory,
* a command ('ls', 'get' etc.), and an expression to determine the filename.
* a command ('ls', 'get' etc.), and an expression to determine the remote path (file or directory).
* The expression is treated as a remote directory for {@code ls} and {@code nlst} commands
* and can be {@code null} if remote file protocol supports it with a meaning of root directory (or use home).
* The {@code put} and {@code mput} commands ignore this expression and fully rely on the payload.
* If expression is not provided, it falls back to the {@code payload}.
* @param sessionFactory the session factory.
* @param command the command.
* @param expression the filename expression.
* @param expression the remote path.
*/
public AbstractRemoteFileOutboundGateway(SessionFactory<F> sessionFactory, String command,
@Nullable String expression) {
Expand All @@ -166,10 +170,14 @@ public AbstractRemoteFileOutboundGateway(SessionFactory<F> sessionFactory, Strin

/**
* Construct an instance with the supplied session factory,
* a command ('ls', 'get' etc.), and an expression to determine the filename.
* a command ('ls', 'get' etc.), and an expression to determine the remote path (file or directory).
* The expression is treated as a remote directory for {@code ls} and {@code nlst} commands
* and can be {@code null} if remote file protocol supports it with a meaning of root directory (or use home).
* The {@code put} and {@code mput} commands ignore this expression and fully rely on the payload.
* If expression is not provided, it falls back to the {@code payload}.
* @param sessionFactory the session factory.
* @param command the command.
* @param expression the filename expression.
* @param expression the remote path.
*/
public AbstractRemoteFileOutboundGateway(SessionFactory<F> sessionFactory, Command command,
@Nullable String expression) {
Expand All @@ -180,10 +188,14 @@ public AbstractRemoteFileOutboundGateway(SessionFactory<F> sessionFactory, Comma

/**
* Construct an instance with the supplied remote file template,
* a command ('ls', 'get' etc.), and an expression to determine the filename.
* a command ('ls', 'get' etc.), and an expression to determine the remote path (file or directory).
* The expression is treated as a remote directory for {@code ls} and {@code nlst} commands
* and can be {@code null} if remote file protocol supports it with a meaning of root directory (or use home).
* The {@code put} and {@code mput} commands ignore this expression and fully rely on the payload.
* If expression is not provided, it falls back to the {@code payload}.
* @param remoteFileTemplate the remote file template.
* @param command the command.
* @param expression the filename expression.
* @param expression the remote path.
*/
public AbstractRemoteFileOutboundGateway(RemoteFileTemplate<F> remoteFileTemplate, String command,
@Nullable String expression) {
Expand All @@ -193,10 +205,14 @@ public AbstractRemoteFileOutboundGateway(RemoteFileTemplate<F> remoteFileTemplat

/**
* Construct an instance with the supplied remote file template,
* a command ('ls', 'get' etc.), and an expression to determine the filename.
* a command ('ls', 'get' etc.), and an expression to determine the remote path (file or directory).
* The expression is treated as a remote directory for {@code ls} and {@code nlst} commands
* and can be {@code null} if remote file protocol supports it with a meaning of root directory (or use home).
* The {@code put} and {@code mput} commands ignore this expression and fully rely on the payload.
* If expression is not provided, it falls back to the {@code payload}.
* @param remoteFileTemplate the remote file template.
* @param command the command.
* @param expressionArg the filename expression.
* @param expressionArg the remote path.
*/
public AbstractRemoteFileOutboundGateway(RemoteFileTemplate<F> remoteFileTemplate, Command command,
@Nullable String expressionArg) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,44 +132,86 @@ public static FtpMessageHandlerSpec outboundAdapter(FtpRemoteFileTemplate ftpRem
return new FtpMessageHandlerSpec(ftpRemoteFileTemplate, fileExistsMode);
}

/**
* Produce a {@link FtpOutboundGatewaySpec} based on the {@link SessionFactory},
* {@link AbstractRemoteFileOutboundGateway.Command}.
* @param sessionFactory the {@link SessionFactory}.
* @param command the command to perform on the FTP.
* @return the {@link FtpOutboundGatewaySpec}
* @since 6.4
*/
public static FtpOutboundGatewaySpec outboundGateway(SessionFactory<FTPFile> sessionFactory,
AbstractRemoteFileOutboundGateway.Command command) {

return outboundGateway(sessionFactory, command.getCommand(), null);
}

/**
* Produce a {@link FtpOutboundGatewaySpec} based on the {@link SessionFactory},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the
* remoteFilePath.
* remote path.
* @param sessionFactory the {@link SessionFactory}.
* @param command the command to perform on the FTP.
* @param expression the remoteFilePath SpEL expression.
* @param expression the remote path SpEL expression.
* @return the {@link FtpOutboundGatewaySpec}
*/
public static FtpOutboundGatewaySpec outboundGateway(SessionFactory<FTPFile> sessionFactory,
AbstractRemoteFileOutboundGateway.Command command, String expression) {
AbstractRemoteFileOutboundGateway.Command command, @Nullable String expression) {

return outboundGateway(sessionFactory, command.getCommand(), expression);
}

/**
* Produce a {@link FtpOutboundGatewaySpec} based on the {@link SessionFactory},
* {@link AbstractRemoteFileOutboundGateway.Command}.
* @param sessionFactory the {@link SessionFactory}.
* @param command the command to perform on the FTP.
* @return the {@link FtpOutboundGatewaySpec}
* @since 6.4
* @see RemoteFileTemplate
*/
public static FtpOutboundGatewaySpec outboundGateway(SessionFactory<FTPFile> sessionFactory, String command) {
return outboundGateway(sessionFactory, command, null);
}

/**
* Produce a {@link FtpOutboundGatewaySpec} based on the {@link SessionFactory},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the
* remoteFilePath.
* remote path.
* @param sessionFactory the {@link SessionFactory}.
* @param command the command to perform on the FTP.
* @param expression the remoteFilePath SpEL expression.
* @param expression the remote path SpEL expression.
* @return the {@link FtpOutboundGatewaySpec}
* @see RemoteFileTemplate
*/
public static FtpOutboundGatewaySpec outboundGateway(SessionFactory<FTPFile> sessionFactory,
String command, String expression) {
String command, @Nullable String expression) {

return new FtpOutboundGatewaySpec(new FtpOutboundGateway(sessionFactory, command, expression));
}

/**
* Produce a {@link FtpOutboundGatewaySpec} based on the {@link RemoteFileTemplate},
* {@link AbstractRemoteFileOutboundGateway.Command}.
* @param remoteFileTemplate the {@link RemoteFileTemplate}.
* @param command the command to perform on the FTP.
* @return the {@link FtpOutboundGatewaySpec}
* @since 6.4
* @see RemoteFileTemplate
*/
public static FtpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<FTPFile> remoteFileTemplate,
AbstractRemoteFileOutboundGateway.Command command) {

return outboundGateway(remoteFileTemplate, command, null);
}

/**
* Produce a {@link FtpOutboundGatewaySpec} based on the {@link RemoteFileTemplate},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the
* remoteFilePath.
* remote path.
* @param remoteFileTemplate the {@link RemoteFileTemplate}.
* @param command the command to perform on the FTP.
* @param expression the remoteFilePath SpEL expression.
* @param expression the remote path SpEL expression.
* @return the {@link FtpOutboundGatewaySpec}
* @see RemoteFileTemplate
*/
Expand All @@ -179,18 +221,33 @@ public static FtpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<FTPFile>
return outboundGateway(remoteFileTemplate, command.getCommand(), expression);
}

/**
* Produce a {@link FtpOutboundGatewaySpec} based on the {@link RemoteFileTemplate},
* {@link AbstractRemoteFileOutboundGateway.Command}.
* @param remoteFileTemplate the {@link RemoteFileTemplate}.
* @param command the command to perform on the FTP.
* @return the {@link FtpOutboundGatewaySpec}
* @since 6.4
* @see RemoteFileTemplate
*/
public static FtpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<FTPFile> remoteFileTemplate,
String command) {

return outboundGateway(remoteFileTemplate, command, null);
}

/**
* Produce a {@link FtpOutboundGatewaySpec} based on the {@link RemoteFileTemplate},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the
* remoteFilePath.
* remote path.
* @param remoteFileTemplate the {@link RemoteFileTemplate}.
* @param command the command to perform on the FTP.
* @param expression the remoteFilePath SpEL expression.
* @param expression the remote path SpEL expression.
* @return the {@link FtpOutboundGatewaySpec}
* @see RemoteFileTemplate
*/
public static FtpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<FTPFile> remoteFileTemplate,
String command, String expression) {
String command, @Nullable String expression) {

return new FtpOutboundGatewaySpec(new FtpOutboundGateway(remoteFileTemplate, command, expression));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2024 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.
Expand Down Expand Up @@ -41,6 +41,7 @@
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.ftp.session.FtpFileInfo;
import org.springframework.integration.ftp.session.FtpRemoteFileTemplate;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;

/**
Expand Down Expand Up @@ -85,25 +86,27 @@ public FtpOutboundGateway(RemoteFileTemplate<FTPFile> remoteFileTemplate,

/**
* Construct an instance with the supplied session factory, a command ('ls', 'get'
* etc), and an expression to determine the filename.
* etc.), and an expression to determine the remote path.
* @param sessionFactory the session factory.
* @param command the command.
* @param expression the filename expression.
* @param expression the remote path expression.
*/
public FtpOutboundGateway(SessionFactory<FTPFile> sessionFactory, String command, String expression) {
public FtpOutboundGateway(SessionFactory<FTPFile> sessionFactory, String command, @Nullable String expression) {
this(new FtpRemoteFileTemplate(sessionFactory), command, expression);
((FtpRemoteFileTemplate) getRemoteFileTemplate()).setExistsMode(FtpRemoteFileTemplate.ExistsMode.NLST);
remoteFileTemplateExplicitlySet(false);
}

/**
* Construct an instance with the supplied remote file template, a command ('ls',
* 'get' etc), and an expression to determine the filename.
* 'get' etc.), and an expression to determine the remote path.
* @param remoteFileTemplate the remote file template.
* @param command the command.
* @param expression the filename expression.
* @param expression the remote path expression.
*/
public FtpOutboundGateway(RemoteFileTemplate<FTPFile> remoteFileTemplate, String command, String expression) {
public FtpOutboundGateway(RemoteFileTemplate<FTPFile> remoteFileTemplate, String command,
@Nullable String expression) {

super(remoteFileTemplate, command, expression);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2023 the original author or authors.
* Copyright 2014-2024 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.
Expand Down Expand Up @@ -132,6 +132,20 @@ public static SftpMessageHandlerSpec outboundAdapter(SftpRemoteFileTemplate sftp
return new SftpMessageHandlerSpec(sftpRemoteFileTemplate, fileExistsMode);
}

/**
* Produce a {@link SftpOutboundGatewaySpec} based on the {@link SessionFactory},
* {@link AbstractRemoteFileOutboundGateway.Command}.
* @param sessionFactory the {@link SessionFactory}.
* @param command the command to perform on the FTP.
* @return the {@link SftpOutboundGatewaySpec}
* @since 6.4
*/
public static SftpOutboundGatewaySpec outboundGateway(SessionFactory<SftpClient.DirEntry> sessionFactory,
AbstractRemoteFileOutboundGateway.Command command) {

return outboundGateway(sessionFactory, command, null);
}

/**
* Produce a {@link SftpOutboundGatewaySpec} based on the {@link SessionFactory},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the
Expand All @@ -142,11 +156,26 @@ public static SftpMessageHandlerSpec outboundAdapter(SftpRemoteFileTemplate sftp
* @return the {@link SftpOutboundGatewaySpec}
*/
public static SftpOutboundGatewaySpec outboundGateway(SessionFactory<SftpClient.DirEntry> sessionFactory,
AbstractRemoteFileOutboundGateway.Command command, String expression) {
AbstractRemoteFileOutboundGateway.Command command, @Nullable String expression) {

return outboundGateway(sessionFactory, command.getCommand(), expression);
}

/**
* Produce a {@link SftpOutboundGatewaySpec} based on the {@link SessionFactory},
* {@link AbstractRemoteFileOutboundGateway.Command}.
* @param sessionFactory the {@link SessionFactory}.
* @param command the command to perform on the FTP.
* @return the {@link SftpOutboundGatewaySpec}
* @since 6.4
* @see RemoteFileTemplate
*/
public static SftpOutboundGatewaySpec outboundGateway(SessionFactory<SftpClient.DirEntry> sessionFactory,
String command) {

return outboundGateway(sessionFactory, command, null);
}

/**
* Produce a {@link SftpOutboundGatewaySpec} based on the {@link SessionFactory},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the
Expand All @@ -158,26 +187,56 @@ public static SftpOutboundGatewaySpec outboundGateway(SessionFactory<SftpClient.
* @see RemoteFileTemplate
*/
public static SftpOutboundGatewaySpec outboundGateway(SessionFactory<SftpClient.DirEntry> sessionFactory,
String command, String expression) {
String command, @Nullable String expression) {

return new SftpOutboundGatewaySpec(new SftpOutboundGateway(sessionFactory, command, expression));
}

/**
* Produce a {@link SftpOutboundGatewaySpec} based on the {@link RemoteFileTemplate},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the remoteFilePath.
* {@link AbstractRemoteFileOutboundGateway.Command}.
* @param remoteFileTemplate the {@link RemoteFileTemplate} to be based on.
* @param command the command to perform on the SFTP.
* @param expression the remoteFilePath SpEL expression.
* @return the {@link SftpOutboundGatewaySpec}
* @since 6.4
* @see RemoteFileTemplate
*/
public static SftpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<SftpClient.DirEntry> remoteFileTemplate,
AbstractRemoteFileOutboundGateway.Command command, String expression) {
AbstractRemoteFileOutboundGateway.Command command) {

return outboundGateway(remoteFileTemplate, command, null);
}

/**
* Produce a {@link SftpOutboundGatewaySpec} based on the {@link RemoteFileTemplate},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the remote path.
* @param remoteFileTemplate the {@link RemoteFileTemplate} to be based on.
* @param command the command to perform on the SFTP.
* @param expression the remote path SpEL expression.
* @return the {@link SftpOutboundGatewaySpec}
* @see RemoteFileTemplate
*/
public static SftpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<SftpClient.DirEntry> remoteFileTemplate,
AbstractRemoteFileOutboundGateway.Command command, @Nullable String expression) {

return outboundGateway(remoteFileTemplate, command.getCommand(), expression);
}

/**
* Produce a {@link SftpOutboundGatewaySpec} based on the {@link RemoteFileTemplate},
* {@link AbstractRemoteFileOutboundGateway.Command}.
* @param remoteFileTemplate the {@link RemoteFileTemplate} to be based on.
* @param command the command to perform on the SFTP.
* @return the {@link SftpOutboundGatewaySpec}
* @since 6.4
* @see RemoteFileTemplate
*/
public static SftpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<SftpClient.DirEntry> remoteFileTemplate,
String command) {

return outboundGateway(remoteFileTemplate, command, null);
}

/**
* Produce a {@link SftpOutboundGatewaySpec} based on the {@link RemoteFileTemplate},
* {@link AbstractRemoteFileOutboundGateway.Command} and {@code expression} for the remoteFilePath.
Expand All @@ -188,7 +247,7 @@ public static SftpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<SftpCli
* @see RemoteFileTemplate
*/
public static SftpOutboundGatewaySpec outboundGateway(RemoteFileTemplate<SftpClient.DirEntry> remoteFileTemplate,
String command, String expression) {
String command, @Nullable String expression) {

return new SftpOutboundGatewaySpec(new SftpOutboundGateway(remoteFileTemplate, command, expression));
}
Expand Down
Loading

0 comments on commit c27cc4b

Please sign in to comment.