Spring Integration - Stop Inbound Adapter after files have been copied

230 Views Asked by At

I am doing a local file copy using Spring integration. My class is presented later in this post.

I initiate the file copy by issuing an adapter.start() from another class. That works fine, and the adapter (localFileTransferAdapter) runs once (based on the FireOnceTrigger) copying all the files I expect. But I then want to stop the adapter after all the files have been copied.

What can I do to detect that the adapter has copied the files so I can then stop the adapter? The FireOnceTrigger will never fire again - but the adapter still shows running when I query it from the class I use to start the adapter. I could wait some number of seconds and stop the adapter - but it could stop the adapter in the middle of copying files if there are many large files to copy - which I don't want to happen.

I've reviewed How to stop polling after a message is received? Spring Integration but it does not appear to match my use case.

Thanks in advance for for any assistance.

public class LocalFileTransfer {

    @Value("${source.directory:c:/source}")
    private String sourceDirectory;

    @Value("${target.directory:c:/target}")
    private String targetDirectory;

    @Bean
    public MessageSource<File> sourceDirectory() {
        FileReadingMessageSource messageSource = new FileReadingMessageSource();
        messageSource.setDirectory(new File(sourceDirectory));
        return messageSource;
    }

    @Bean
    public IntegrationFlow fileMover() {
        return IntegrationFlows.from(sourceDirectory(),
                c -> c.autoStartup(false)
                        .id("localFileTransferAdapter")
                        .poller(Pollers.trigger(new FireOnceTrigger())
                .maxMessagesPerPoll(-1)))
                .filter(source -> ((File) source).getName().endsWith(".txt"))
                .log(LoggingHandler.Level.ERROR, "localfile.category", m -> m.getPayload())
                .log(LoggingHandler.Level.ERROR, "localfile.category", m -> m.getHeaders())
                .handle(targetDirectory())
                .get();
    }
    @Bean
    public MessageHandler targetDirectory() {
        FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(targetDirectory));
        handler.setFileExistsMode(FileExistsMode.REPLACE);
        handler.setExpectReply(false);
        return handler;
   }
}
1

There are 1 best solutions below

0
On

You are on the right track with the FireOnceTrigger and maxMessagesPerPoll(-1). Also that answer with an AbstractMessageSourceAdvice sample fully fits to your scenario.

In the MessageSourceMutator.afterReceive() you just check for the null of result argument and call a stop() of that localFileTransferAdapter.

Since everything happens on the same thread, you are safe to call stop just when you meet a null: no need to introduce some delay and the channel adapter doesn't exist until it finishes producing messages in that one poll cycle.