-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Expected Behavior
I would like to do something like this (I'm using SFTP, but I think this is common to other remote file gateways):
<int-sftp:outbound-gateway
session-factory="mySftpSessionFactory"
request-channel="myRequestChannel"
reply-channel="nullChannel"
command="mv"
remote-directory-expression="headers[T(org.springframework.integration.file.FileHeaders).REMOTE_DIRECTORY]"
expression="headers[T(org.springframework.integration.file.FileHeaders).REMOTE_FILE]"
rename-expression="headers[T(org.springframework.integration.file.FileHeaders).REMOTE_FILE].concat('.done')" />
That is: consider the file located under remote-directory-expression
, with simple name given by expression
, and rename it to rename-expression
, which is a simple name (not a full path), hence keeping the renamed file in in the same source directory.
i.e.: for file "example.txt" in /sourcepath to be renamed to "example.txt.done" they would be:
remote-directory-expression
= /sourcepathexpression
= example.txtrename-expression
= example.txt.done
Current Behavior
expression
must be a full path, as well as rename-expression
, while remote-directory-expression
seems to be simply ignored. This causes the above to lead to a "file does not exist" error.
In org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.doMv(Message<?>)
(I'm using Spring Integration 5.4.11) I see this:
String remoteFilePath = obtainRemoteFilePath(requestMessage);
String remoteFilename = getRemoteFilename(remoteFilePath);
String remoteDir = getRemoteDirectory(remoteFilePath, remoteFilename);
String remoteFileNewPath = this.renameProcessor.processMessage(requestMessage);
By debugging I see that:
remoteFilePath
is example.txtremoteFilename
is example.txt as wellremoteDir
is null, because it tries to extract the path by removing theremoteFileName
fromremoteFilePath
(ignoring myremote-directory-expression
)remoteFileNewPath
is example.txt.done
Perhaps, if that code used remote-directory-expression
in case remoteDir
is null
, and possibly concatenate that remoteDir
with remoteFileNewPath
in case the latter is not a full path, could bring the desired result without breaking backward compatibility.
Context
I'm trying to rename a file I have previously read with a <int-sftp:inbound-streaming-channel-adapter>
on transaction commit. The inbound adapter only allows for file deletion after read, not file rename/move, and I'm not sure whether the action is executed immediately after reading the source file or at the end of the flow if no exception is got back by downstream components (as I want in my case).
Anyway, in my case I would like to just add a suffix to the file name, without moving it anywhere, so I'd like to limit processing as much as possible, in particular to avoid to make concatenations just to reference a file for which I already know both the remote directory and its simple file name.
Unless I'm missing a better way to do this, the alternative way to achieve this right now is to write the following (which seems a bit ugly to me):
<int-sftp:outbound-gateway
session-factory="mySftpSessionFactory"
request-channel="myRequestChannel"
reply-channel="nullChannel"
command="mv"
expression="headers[T(org.springframework.integration.file.FileHeaders).REMOTE_DIRECTORY].concat('/'.concat(headers[T(org.springframework.integration.file.FileHeaders).REMOTE_FILE]))"
rename-expression="headers[T(org.springframework.integration.file.FileHeaders).REMOTE_DIRECTORY].concat('/'.concat(headers[T(org.springframework.integration.file.FileHeaders).REMOTE_FILE].concat('.done')))" />