3

I would like to use the SFTP Outbound Gateway to get a file via SFTP but I only find examples using XML config. How can this be done using Java config?

Update (Thanks to Artem Bilan help)

MyConfiguration class:

@Configuration
public class MyConfiguration {

    @Bean
    public SessionFactory<LsEntry> sftpSessionFactory() {
        DefaultSftpSessionFactory sftpSessionFactory = new DefaultSftpSessionFactory();
        sftpSessionFactory.setHost("myhost");
        sftpSessionFactory.setPort(22);
        sftpSessionFactory.setUser("uname");
        sftpSessionFactory.setPassword("pass");
        sftpSessionFactory.setAllowUnknownKeys(true);
        return new CachingSessionFactory<LsEntry>(sftpSessionFactory);
    }

    @Bean
    @ServiceActivator(inputChannel = "sftpChannel")
    public MessageHandler handler() {
        SftpOutboundGateway sftpOutboundGateway = new  SftpOutboundGateway(sftpSessionFactory(), "get", "#getPayload() == '/home/samadmin/test.endf'");
        sftpOutboundGateway.setLocalDirectory(new File("C:/test/gateway/"));
        return sftpOutboundGateway;
    }

}

My application class:

@SpringBootApplication
@EnableIntegration
public class TestIntegrationApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestIntegrationApplication.class, args);
    }
}

Configuration succeeds now but no SFTP occurs. Need to figure out how to request SFTP.

James
  • 2,876
  • 18
  • 72
  • 116

1 Answers1

5

Quoting Reference Manual:

@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler() {
    return new SftpOutboundGateway(ftpSessionFactory(), "ls");
}

Also pay attention to the Java DSL sample in the next section there.

EDIT

@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler() {
    SftpOutboundGateway sftpOutboundGateway = new  SftpOutboundGateway(sftpSessionFactory(), "get", "payload");
    sftpOutboundGateway.setLocalDirectory(new File("C:/test/gateway/"));
    return sftpOutboundGateway;
}

In case of GET SFTP command the expression ctor arg maybe like above - just a reference to the Message.getPayload() for all incoming messages.

In this case you should send to the sftpChannel a Message like:

new GenericMessage<>("/home/samadmin/test.endf");

So, that /home/samadmin/test.endf is a payload of that Message. When it arrives to the SftpOutboundGateway, that expression is evaluated against that message and getPayload() is called by SpEL. So, the GET command will be preformed with the desired path to the remote file.

An other message may have fully different path to some other file.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Is Java config for SFTP Outbound Gateway available in version 4.3.1? In the current GA (4.3.1), I was unable find a constructor with parameters supporting `new SftpOutboundGateway(sftpSessionFactory(), "ls")` where `sftpSessionFactory` is of type `SessionFactory` – James Sep 02 '16 at 17:00
  • Well, we have a bug in that doc. Agree. But that is a sample, some template anyway. You should choose an appropriate constructor for your use-case. I guess that should be like `SftpOutboundGateway(ftpSessionFactory(), "get", "'THE_PATH_TO_REMOTE_FILE'")`. – Artem Bilan Sep 02 '16 at 17:26
  • I'm receiving `org.springframework.expression.spel.SpelParseException: EL1070E:(pos 0): Problem parsing left operand` when trying to create the `MessageHandler` bean. I have two beans in my `@Configuration` class: the `MessageHandler` and `SessionFactory`. Am I missing something? – James Sep 02 '16 at 21:01
  • 1
    You are missing to share your code. The third ctor parameter is an `expression` to determine the remote path. In case of `LS` it is directory. For `GET` the path with file. That path can be determined against `requestMessage`, e.g. you can specify remote path in the `headers`. From here that expression can be like `headers['my_remote_file_path']`: http://docs.spring.io/spring-integration/reference/html/spel.html – Artem Bilan Sep 02 '16 at 21:05
  • Your expression `headers['/home/uname/test.txt']` looks strange. Feels like that `'/home/uname/test.txt'` is exactly a path to your file. For a simple use-case I'd suggest to use `expression = "payload"`, where `payload` of the request message on the `sftpChannel` is exactly a path to remote file. – Artem Bilan Sep 02 '16 at 22:07
  • You're right. The path is to a specific file. I'm not sure where to specify `expression = "payload"`. The `SftpOutboundGateway` constructor I used in the above code requires an expression `String` argument. If I pass `"expression = \"/home/samadmin/test.endf\""` for that argument, the file is not downloaded. The above code is my entire application configuration. Am I missing something? – James Sep 06 '16 at 14:02
  • M-m-m. You missing that `expression` in my comment is a ctor arg name. The `payload` is exactly SpEL expression which will be evaluated against each incoming `Message` as a root evaluation context object. In this case the `payload` really means `getPayload()` on the `Message` object. – Artem Bilan Sep 06 '16 at 14:04
  • Sorry. I still can't figure this out. Code added above. – James Sep 06 '16 at 17:30
  • Please, find an EDIT in my answer. – Artem Bilan Sep 06 '16 at 18:08
  • Thanks for the help and thanks to you and other contributors for the great work on the Spring Integration project. – James Sep 07 '16 at 20:59