INT-4344: AbstRemoteFileOutGw: Add assert for NPE
JIRA: https://jira.spring.io/browse/INT-4344 The `FtpOutboundGateway` provides ctors without expression for remote path. In this case it is treated as a `working directory` but only for the `LS`, `NLST`, `PUT` and `MPUT` commands. * Add assertion in the `AbstractRemoteFileOutboundGateway` to discard configuration for all other commands when `expression` is `null` **Cherry-pick to 4.3.x** Conflicts: spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java Resolved.
This commit is contained in:
committed by
Gary Russell
parent
6ec34c114c
commit
7d24b8ec67
@@ -307,11 +307,20 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
Assert.notNull(remoteFileTemplate, "'remoteFileTemplate' cannot be null");
|
||||
this.remoteFileTemplate = remoteFileTemplate;
|
||||
this.command = command;
|
||||
Expression parsedExpression = new SpelExpressionParser().parseExpression(expression);
|
||||
this.fileNameProcessor = new ExpressionEvaluatingMessageProcessor<String>(
|
||||
parsedExpression);
|
||||
if (expression == null) {
|
||||
Assert.state(Command.LS.equals(this.command)
|
||||
|| Command.PUT.equals(this.command)
|
||||
|| Command.MPUT.equals(this.command),
|
||||
"Only LS, PUT and MPUT commands can rely on the working directory.\n" +
|
||||
"All other commands must be supplied with the filename expression");
|
||||
this.fileNameProcessor = null;
|
||||
}
|
||||
else {
|
||||
Expression parsedExpression = new SpelExpressionParser().parseExpression(expression);
|
||||
this.fileNameProcessor = new ExpressionEvaluatingMessageProcessor<String>(parsedExpression);
|
||||
setPrimaryExpression(parsedExpression);
|
||||
}
|
||||
this.messageSessionCallback = null;
|
||||
setPrimaryExpression(parsedExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,10 +512,14 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
"Cannot use " + Option.SUBDIRS.toString() + " when using 'mget' use "
|
||||
+ Option.RECURSIVE.toString() + " to obtain files in subdirectories");
|
||||
}
|
||||
if (this.fileNameProcessor != null && getBeanFactory() != null) {
|
||||
this.fileNameProcessor.setBeanFactory(this.getBeanFactory());
|
||||
this.renameProcessor.setBeanFactory(this.getBeanFactory());
|
||||
this.remoteFileTemplate.setBeanFactory(this.getBeanFactory());
|
||||
|
||||
if (getBeanFactory() != null) {
|
||||
if (this.fileNameProcessor != null) {
|
||||
this.fileNameProcessor.setBeanFactory(getBeanFactory());
|
||||
}
|
||||
|
||||
this.renameProcessor.setBeanFactory(getBeanFactory());
|
||||
this.remoteFileTemplate.setBeanFactory(getBeanFactory());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,7 +555,9 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
}
|
||||
|
||||
private Object doLs(Message<?> requestMessage) {
|
||||
String dir = this.fileNameProcessor.processMessage(requestMessage);
|
||||
String dir = this.fileNameProcessor != null
|
||||
? this.fileNameProcessor.processMessage(requestMessage)
|
||||
: null;
|
||||
if (dir != null && !dir.endsWith(this.remoteFileTemplate.getRemoteFileSeparator())) {
|
||||
dir += this.remoteFileTemplate.getRemoteFileSeparator();
|
||||
}
|
||||
|
||||
@@ -821,7 +821,7 @@ public class RemoteFileOutboundGatewayTests {
|
||||
template.setRemoteDirectoryExpression(new LiteralExpression("foo/"));
|
||||
template.setBeanFactory(mock(BeanFactory.class));
|
||||
template.afterPropertiesSet();
|
||||
TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway(template, "put", null);
|
||||
TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway(template, "put", "payload");
|
||||
FileTransferringMessageHandler<TestLsEntry> handler = new FileTransferringMessageHandler<TestLsEntry>(sessionFactory);
|
||||
handler.setRemoteDirectoryExpressionString("'foo/'");
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
@@ -856,7 +856,7 @@ public class RemoteFileOutboundGatewayTests {
|
||||
template.setRemoteDirectoryExpression(new LiteralExpression("foo/"));
|
||||
template.setBeanFactory(mock(BeanFactory.class));
|
||||
template.afterPropertiesSet();
|
||||
TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway(template, "put", null);
|
||||
TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway(template, "put", "payload");
|
||||
FileTransferringMessageHandler<TestLsEntry> handler = new FileTransferringMessageHandler<TestLsEntry>(sessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression("foo/"));
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
@@ -917,7 +917,7 @@ public class RemoteFileOutboundGatewayTests {
|
||||
template.setRemoteDirectoryExpression(new LiteralExpression("foo/"));
|
||||
template.setBeanFactory(mock(BeanFactory.class));
|
||||
template.afterPropertiesSet();
|
||||
TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway(template, "mput", null);
|
||||
TestRemoteFileOutboundGateway gw = new TestRemoteFileOutboundGateway(template, "mput", "payload");
|
||||
gw.afterPropertiesSet();
|
||||
when(sessionFactory.getSession()).thenReturn(session);
|
||||
final AtomicReference<String> written = new AtomicReference<String>();
|
||||
|
||||
@@ -86,8 +86,8 @@ public class FtpOutboundGateway extends AbstractRemoteFileOutboundGateway<FTPFil
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the supplied session factory, a command ('ls', 'get'
|
||||
* etc).
|
||||
* Construct an instance with the supplied session factory
|
||||
* and command ('ls', 'nlst', 'put' or 'mput').
|
||||
* <p> The {@code remoteDirectory} expression is {@code null} assuming to use
|
||||
* the {@code workingDirectory} from the FTP Client.
|
||||
* @param sessionFactory the session factory.
|
||||
@@ -99,8 +99,8 @@ public class FtpOutboundGateway extends AbstractRemoteFileOutboundGateway<FTPFil
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with the supplied remote file template, a command ('ls',
|
||||
* 'get' etc).
|
||||
* Construct an instance with the supplied remote file template
|
||||
* and command ('ls', 'nlst', 'put' or 'mput').
|
||||
* <p> The {@code remoteDirectory} expression is {@code null} assuming to use
|
||||
* the {@code workingDirectory} from the FTP Client.
|
||||
* @param remoteFileTemplate the remote file template.
|
||||
|
||||
@@ -684,8 +684,9 @@ directories, which is achievable using the `FileInfo` objects.
|
||||
|
||||
Starting with _version 4.3_, the `FtpSession` supports `null` for the `list()` and `listNames()` methods,
|
||||
therefore the `expression` attribute can be omitted.
|
||||
From Java perspective there are two new constructor without `expression` argument for convenience.
|
||||
The `null` for `LS` command is treated as an Client working directory according to the FTP protocol.
|
||||
For Java configuration, there are two constructors without an `expression` argument for convenience.
|
||||
`null` for `LS`, `PUT` and `MPUT` commands is treated as the Client working directory according to the FTP protocol.
|
||||
All other commands must be supplied with the `expression` to evaluate remote path against request message.
|
||||
The working directory can be set via the `FTPClient.changeWorkingDirectory()` function when you extend the `DefaultFtpSessionFactory` and implement `postProcessClientAfterConnect()` callback.
|
||||
|
||||
*get*
|
||||
|
||||
Reference in New Issue
Block a user