springftpmessagespring-integrationpoller

Spring Integration FTP - poll without transfer?


I'd like to utilize Spring Integration to initiate messages about files that appear in a remote location, without actually transferring them. All I require is the generation of a Message with, say, header values indicating the path to the file and filename.

What's the best way to accomplish this? I've tried stringing together an FTP inbound channel adapter with a service activator to write the header values I need, but this causes the file to be transferred to a local temp directory, and by the time the service activator sees it, the message consists of a java.io.File that refers to the local file and the remote path info is gone. It is possible to transform the message prior to this local transfer occurring?


Solution

  • We have similar problem and we solved it with filters. On inbound-channel-adapter you can set custom filter implementation. So before polling your filter will be called and you will have all informations about files, from which you can decide will that file be downloaded or not, for example;

    <int-sftp:inbound-channel-adapter id="test"
                                      session-factory="sftpSessionFactory"
                                      channel="testChannel"
                                      remote-directory="${sftp.remote.dir}"
                                      local-directory="${sftp.local.dir}"
                                      filter="customFilter"
                                      delete-remote-files="false">
        <int:poller trigger="pollingTrigger" max-messages-per-poll="${sftp.max.msg}"/>
    </int-sftp:inbound-channel-adapter>
    
    <beans:bean id="customFilter" class="your.class.location.SftpRemoteFilter"/>
    

    Filter class is just implementation of the FileListFilter interface. Here it is dummy filter implementation.

    public class SftpRemoteFilter implements FileListFilter<LsEntry> {
    
        private static final Logger log = LoggerFactory.getLogger(SftpRemoteFilter.class);
    
        @Override
        public final List<LsEntry> filterFiles(LsEntry[] files) {
           log.info("Here is files.");
           //Do something smart
           return Collections.emptyList();
        }
    }
    

    But if you want to do that as you described, I think it is possible to do it by setting headers on payloads and then using same headers when you are using that payload, but in that case you should use Message<File> instead File in your service activator method.