Skip to content

Allow for MV command to use remote directory + remote file name => new file name (in the same remote directory) #3647

@mauromol

Description

@mauromol

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 = /sourcepath
  • expression = example.txt
  • rename-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.txt
  • remoteFilename is example.txt as well
  • remoteDir is null, because it tries to extract the path by removing the remoteFileName from remoteFilePath (ignoring my remote-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')))"  />

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions