0

I have a poller that is polling a remote dir in order to sftp the file across but i want to stop it if it doesn't find the file after x amount of attempts. Is there a simple config for this?

ApplicationContext.xml

        <int-sftp:inbound-channel-adapter id="sftpInboundAdaptor"
                                          session-factory="sftpSessionFactory"
                                          local-directory="${local.dir}"
                                          auto-create-local-directory="true"
                                          auto-startup="false"
                                          channel="SftpChannel"
                                          remote-directory="${remote.dir}"
                                          filename-pattern="XXXX"
                                          delete-remote-files="false"
                                          charset="UTF-8"
                                          remote-file-separator="/"
                                          local-filename-generator-expression="#this">
            <int:poller max-messages-per-poll="1" fixed-rate="30000" >
            </int:poller>
        </int-sftp:inbound-channel-adapter>



Main.class

     private static void sftpFile(String party) throws Exception {
            SourcePollingChannelAdapter adapter = (SourcePollingChannelAdapter) applicationContext.getBean("sftpInboundAdaptor");
            adapter.start();
            SftpDownloader sftpProcessor = (SftpDownloader) applicationContext.getBean("sftpDownloader");
            LOGGER.info((fileDownloaded ? "Successful" : "Failed") + " downloading file"");
        }




SftpDownloader.class

    public boolean receiveFile(String party, String fileType) throws SftpJobException {
            if (Constants.1.equals(fileType)) {
                return isFile1SftpSuccessful();
            } else if (Constants.2.equals(fileType)) {
                return isFile2SftpSuccessful(party);
            }
            return false;
        }

        private boolean isFile1SftpSuccessful() throws SftpJobException {
            return isValidFile((File) SftpChannel.receive().getPayload());
        }
            private boolean isValidFile(File received) throws SftpJobException{
            if (received.length() != 0) {
                LOGGER.info("File is: {}", received.toString());
                return true;
            } else {
                throw new SftpJobException("File size is 0, either no file exists an empty file was created. ")
            }
        }

I seems like it polls indefinitely when i look for the above file (doesn't exist) whereas i'd like to throw an exception if the file wasn't there.

Stefan101
  • 81
  • 1
  • 6
  • I would run this in an Executor with a timeout. Or, better yet, stop polling and think about reactive Spring and events. – duffymo Jul 13 '17 at 13:05

1 Answers1

0

See Smart Polling - you can detect the lack of a message and stop the poller.

Version 4.2 introduced the AbstractMessageSourceAdvice. Any Advice objects in the advice-chain that subclass this class, are applied to just the receive operation. Such classes implement the following methods:

beforeReceive(MessageSource<?> source)

This method is called before the MessageSource.receive() method. It enables you to examine and or reconfigure the source at this time. Returning false cancels this poll (similar to the PollSkipAdvice mentioned above).

Message<?> afterReceive(Message<?> result, MessageSource<?> source)

This method is called after the receive() method; again, you can reconfigure the source, or take any action perhaps depending on the result (which can be null if there was no message created by the source). You can even return a different message!

Community
  • 1
  • 1
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Unfortunately i'm using 4.1 and i can't upgrade :( – Stefan101 Jul 13 '17 at 14:35
  • So, you only have option to copy/paste solution into your own `Advice` implementation: https://github.com/spring-projects/spring-integration/blob/master/spring-integration-core/src/main/java/org/springframework/integration/aop/AbstractMessageSourceAdvice.java – Artem Bilan Jul 13 '17 at 14:55
  • That won't work; he also needs the corresponding change to `SourcePollingChannelAdapter` to only advise the `receive()` method and to call those methods before and after the poll. You could add a channel interceptor on the channel and start a timer; if no messages are sent to the channel after some period, stop the adapter. – Gary Russell Jul 13 '17 at 15:15
  • How do i actually stop the adaptor within the interceptor? I've got the timing logic in the postReceive but then how would i stop the adaptor? I.e im overriding the ChannelInterceptor and puting the logic in the overridden postReceive method. – Stefan101 Jul 13 '17 at 15:29
  • `@Autowire` `SourcePollingChannelAdapter` with the field being the adapter bean name (or `id` if using XML); then `adapter.stop()`. – Gary Russell Jul 13 '17 at 16:20
  • postReceive(Message> message, MessageChannel messageChannel) { File received = (File) message.getPayload(); long startTime = System.currentTimeMillis(); long elapsedTime = 0L; while (elapsedTime < 1*60*1000) { if (received.length() != 0) { return (Message>) received; } else { elapsedTime = (new Date()).getTime() - startTime; } } sftpInboundAdaptor.stop(); – Stefan101 Jul 14 '17 at 13:07
  • The above doesn't seem to be working. When i search for a file that isn't there it fails as it should but now when the file is there it fails as well – Stefan101 Jul 14 '17 at 13:09
  • Don't put code in comments; it's totally unreadable - edit your question instead. Of course, you need to keep some state and monitor the success/failure of polls; the while loop there breaks the polling mechanism. i.e. stop the adapter if, say, a minute has passed since the last successful poll. – Gary Russell Jul 14 '17 at 13:43