Search code examples
spring-integrationspring-integration-sftp

SftpOutboundGateway MGet change remote directory at runtime


I want trying to use MGet command to pull files from multiple remote directories and want to store it in separate local directories. But the files are not getting downloaded and no error is thrown.

Below is the sample code i am using.

//SFTP Config

@ServiceActivator(inputChannel = "sftpChannelMGetTest")
public MessageHandler mGetHandlerTest() {
ExpressionParser parser = new SpelExpressionParser();

        SftpOutboundGateway gateway = new SftpOutboundGateway(sftpSessionFactory(), "mget", parser.parseExpression("headers['remoteDirectory']").getExpressionString());
        gateway.setLocalDirectoryExpression(parser.parseExpression("headers['localDirectory']"));
        gateway.setFileExistsMode(FileExistsMode.REPLACE);
        gateway.setRemoteDirectoryExpression(parser.parseExpression("headers['remoteDirectory']"));
    
        return gateway;
    }
//MessagingGateway config


@Payload("new java.util.Date()")
@Gateway(requestChannel = "sftpChannelMGetTest")
List<File> getAllFilesTest(@Header("remoteDirectory") String remoteDir, @Header("localDirectory") String localDir);
//Service Call

public void getAllFilesTest() {
        List<File> allFiles = gateway.getAllFilesTest("/home/pi/sftp/patient/", "src/main/resources/files/mget/test/");
        System.out.println(allFiles);
}

If I provide hardcoded values for the one remote directory and one local directory, and remove the headers option from messaging gateway method, the files are able to download.


Solution

  • The setRemoteDirectoryExpression() is out of use for MGET command:

    /**
     * Set the remote directory expression used to determine the remote directory to which
     * files will be sent.
     * @param remoteDirectoryExpression the remote directory expression.
     * @since 5.2
     * @see RemoteFileTemplate#setRemoteDirectoryExpression
     */
    public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) {
    

    The expression in the ctor is the one used to determine the remote dir to perform MGET.

    See docs about that operation: https://docs.spring.io/spring-integration/reference/sftp/outbound-gateway.html#using-the-mget-command

    And pay attention to the * note:

    The expression you use determine the remote path should produce a result that ends with * for example myfiles/* fetches the complete tree under myfiles.

    So, the config supposes to be like this:

    new SftpOutboundGateway(sftpSessionFactory(), "mget", "headers['remoteDirectory']");
    

    and usage is like this:

    gateway.getAllFilesTest("/home/pi/sftp/patient/*", "src/main/resources/files/mget/test/")