INT-4303: (S)FTP MGET with FileExistsMode.IGNORE
JIRA: https://jira.spring.io/browse/INT-4303 Don't emit ignored files in the output message payload. Also, always preserve the timestamp when using `FileExistsMode.REPLACE_IF_MODIFIED`. Some code style polishing
This commit is contained in:
committed by
Artem Bilan
parent
4679c9bdbe
commit
0903df9676
@@ -1039,12 +1039,18 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
if (!appending && !tempFile.renameTo(localFile)) {
|
||||
throw new MessagingException("Failed to rename local file");
|
||||
}
|
||||
if (this.options.contains(Option.PRESERVE_TIMESTAMP)) {
|
||||
if (this.options.contains(Option.PRESERVE_TIMESTAMP)
|
||||
|| FileExistsMode.REPLACE_IF_MODIFIED.equals(fileExistsMode)) {
|
||||
localFile.setLastModified(getModified(fileInfo));
|
||||
}
|
||||
}
|
||||
else if (FileExistsMode.REPLACE_IF_MODIFIED.equals(fileExistsMode)) {
|
||||
logger.debug("Local file '" + localFile + "' has the same modified timestamp, ignored");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Local file '" + localFile + "' has the same modified timestamp, ignored");
|
||||
}
|
||||
if (this.command.equals(Command.MGET)) {
|
||||
localFile = null;
|
||||
}
|
||||
}
|
||||
else if (!FileExistsMode.IGNORE.equals(fileExistsMode)) {
|
||||
throw new MessageHandlingException(message, "Local file " + localFile + " already exists");
|
||||
@@ -1053,6 +1059,9 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Existing file skipped: " + localFile);
|
||||
}
|
||||
if (this.command.equals(Command.MGET)) {
|
||||
localFile = null;
|
||||
}
|
||||
}
|
||||
return localFile;
|
||||
}
|
||||
@@ -1098,9 +1107,10 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
*/
|
||||
String fileName = this.getRemoteFilename(fullFileName);
|
||||
String actualRemoteDirectory = this.getRemoteDirectory(fullFileName, fileName);
|
||||
File file = get(message, session, actualRemoteDirectory,
|
||||
fullFileName, fileName, lsEntry.getFileInfo());
|
||||
files.add(file);
|
||||
File file = get(message, session, actualRemoteDirectory, fullFileName, fileName, lsEntry.getFileInfo());
|
||||
if (file != null) {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -1141,9 +1151,10 @@ public abstract class AbstractRemoteFileOutboundGateway<F> extends AbstractReply
|
||||
*/
|
||||
String fileName = this.getRemoteFilename(fullFileName);
|
||||
String actualRemoteDirectory = this.getRemoteDirectory(fullFileName, fileName);
|
||||
File file = get(message, session, actualRemoteDirectory,
|
||||
fullFileName, fileName, lsEntry.getFileInfo());
|
||||
files.add(file);
|
||||
File file = get(message, session, actualRemoteDirectory, fullFileName, fileName, lsEntry.getFileInfo());
|
||||
if (file != null) {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
command="mget"
|
||||
command-options="-f -P"
|
||||
expression="payload"
|
||||
mode="IGNORE"
|
||||
local-directory-expression="@extraConfig.targetLocalDirectoryName + (#remoteDirectory ?: '')"
|
||||
local-filename-generator-expression="#remoteFileName.replaceFirst('ftpSource', 'localTarget')"
|
||||
reply-channel="output"/>
|
||||
|
||||
@@ -228,6 +228,11 @@ public class FtpServerOutboundTests extends FtpTestSupport {
|
||||
for (File file : localFiles) {
|
||||
assertThat(file.getPath().replaceAll(Matcher.quoteReplacement(File.separator), "/"), containsString(dir));
|
||||
}
|
||||
this.inboundMGet.send(new GenericMessage<Object>(dir + "*.txt"));
|
||||
result = this.output.receive(1000);
|
||||
assertNotNull(result);
|
||||
localFiles = (List<File>) result.getPayload();
|
||||
assertThat(localFiles.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -886,7 +886,7 @@ You can either do that in your custom code, or route a copy of the message to a
|
||||
|
||||
*mget*
|
||||
|
||||
_mget_ retrieves multiple remote files based on a pattern and supports the following option:
|
||||
_mget_ retrieves multiple remote files based on a pattern and supports the following options:
|
||||
|
||||
* -P - preserve the timestamps of the remote files
|
||||
|
||||
@@ -896,9 +896,13 @@ _mget_ retrieves multiple remote files based on a pattern and supports the follo
|
||||
|
||||
The message payload resulting from an _mget_ operation is a `List<File>` object - a List of File objects, each representing a retrieved file.
|
||||
|
||||
IMPORTANT: Startng with _version 5.0_, if the `FileExistsMode` is `IGNORE`, the payload of the output message will no longer contain files that were not fetched due to the file already existing.
|
||||
Previously, the array contained all files, including those that already existed.
|
||||
|
||||
The expression used to determine the remote path should produce a result that ends with `*` - e.g. `foo/*` will fetch the complete tree under `foo`.
|
||||
|
||||
Starting with _version 5.0_, a recursive `MGET`, combined with the new `FileExistsMode.REPLACE_IF_MODIFIED` mode, can be used to periodically synchronize an entire remote directory tree locally.
|
||||
This mode will set the local file last modified timestamp with the remote timestamp, regardless of the `-P` (preserve timestamp) option.
|
||||
|
||||
.Notes for when using recursion (`-R`)
|
||||
[IMPORTANT]
|
||||
|
||||
@@ -908,7 +908,7 @@ You can either do that in your custom code, or route a copy of the message to a
|
||||
|
||||
*mget*
|
||||
|
||||
_mget_ retrieves multiple remote files based on a pattern and supports the following option:
|
||||
_mget_ retrieves multiple remote files based on a pattern and supports the following options:
|
||||
|
||||
* -P - preserve the timestamps of the remote files
|
||||
|
||||
@@ -918,9 +918,14 @@ _mget_ retrieves multiple remote files based on a pattern and supports the follo
|
||||
|
||||
The message payload resulting from an _mget_ operation is a `List<File>` object - a List of File objects, each representing a retrieved file.
|
||||
|
||||
IMPORTANT: Startng with _version 5.0_, if the `FileExistsMode` is `IGNORE`, the payload of the output message will no longer contain files that were not fetched due to the file already existing.
|
||||
Previously, the array contained all files, including those that already existed.
|
||||
|
||||
|
||||
The expression used to determine the remote path should produce a result that ends with `*` - e.g. `foo/*` will fetch the complete tree under `foo`.
|
||||
|
||||
Starting with _version 5.0_, a recursive `MGET`, combined with the new `FileExistsMode.REPLACE_IF_MODIFIED` mode, can be used to periodically synchronize an entire remote directory tree locally.
|
||||
This mode will set the local file last modified timestamp to the remote file timestamp, regardless of the `-P` (preserve timestamp) option.
|
||||
|
||||
.Notes for when using recursion (`-R`)
|
||||
[IMPORTANT]
|
||||
|
||||
Reference in New Issue
Block a user