I have a scenario which I'm not sure if I am setting up correctly in Integration Flow. The need is to:
SftpPersistentAcceptOnceFileListFilter
For the last point I have found in another answer that I could try an ExpressionEvaluatingRequestHandlerAdvice
. I have came up with the following configuration, but adding the Advice
has broken the flow completely (no message is flowing through)
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setSuccessChannel(out);
advice.setFailureChannel(err);
advice.setTrapException(true);
IntegrationFlow integrationFlow = IntegrationFlows
.from(Sftp.inboundAdapter(cachingSessionFactory)
.remoteDirectory("sftpSource")
.deleteRemoteFiles(false)
.preserveTimestamp(true)
.localDirectory(getTargetLocalDirectory()), e -> e.id("sftpInboundAdapter")
.poller(Pollers.fixedDelay(100)
.maxMessagesPerPoll(3)
.advice(advice)))
.channel(out)
.get();
The requirement for skipping a filed file transfer came out from a real world scenario, where our SFTP server refused to transfer an empty file. To simulate this I have added spies to the SessionFactory
:
CachingSessionFactory<ChannelSftp.LsEntry> cachingSessionFactory = Mockito.spy(sessionFactory());
CachingSessionFactory.CachedSession session = (CachingSessionFactory.CachedSession) Mockito.spy(cachingSessionFactory.getSession());
doReturn(session).when(cachingSessionFactory).getSession();
doThrow(new RuntimeException("test exception")).when(session).read(contains("sftpSource2.txt"), any(OutputStream.class));
and the test code:
Message<?> message = out.receive(1000);
assertThat(message).isNotNull();
Object payload = message.getPayload();
assertThat(payload).isInstanceOf(File.class);
File file = (File) payload;
assertThat(file.getName()).isEqualTo(" sftpSource1.txt");
assertThat(file.getAbsolutePath()).contains("localTarget");
message = out.receive(1000);
assertThat(message).isNull();
message = err.receive(1000);
System.out.println("error was:" + message.getPayload());
message = out.receive(1000);
assertThat(message).isNotNull();
file = (File) message.getPayload();
assertThat(file.getName()).isIn("sftpSource3.txt");
assertThat(file.getAbsolutePath()).contains("localTarget");
What I am confused about is - when I added the advice
to the Poller
should I remove .errorChannel(err)
from the Poller
? But if the advice is handling where the message ends up, shouldn't I also remove .channel(out)
on the integrationFlow
? Without it the IntegrationFlow doesn't build, with error outputChannel is required
.
My second worry is - if advice.setTrapException(true);
does it mean SftpPersistentAcceptOnceFileListFilter
will mark the file as successfully processed? (the filter isn't present in the example code, but I will require it in real code).
The ExpressionEvaluatingRequestHandlerAdvice
is for consumer endpoints, not a source polling channel adapters. So, you cannot handle errors from the poller using that advice.
Indeed you cannot have an IntegrationFlow
just with a SourcePollingChannelAdapter
- you need to add that channel(out)
either way.
Not clear by your current configuration where you transfer those files. So, probably you are talking about an error for handling those files, there that ExpressionEvaluatingRequestHandlerAdvice
would make sense over there. This way indeed all your remote files would be transferred to the local dir and marked in the SftpPersistentAcceptOnceFileListFilter
as watched. Just because you won't throw an exception from the handler back to the SFTP Inbound Channel Adapter.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.