I am using a FileReadingMessageSource
with a custom FileLocker
:
@Component
public class JdbcFileLocker implements FileLocker {
...
@Autowired
JdbcFileLocker jdbcFileLocker;
@Bean
@InboundChannelAdapter(value = "fileInputChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
FileReadingMessageSource source = new FileReadingMessageSource();
source.setDirectory(new File("/workspace/in"));
source.setFilter(new SimplePatternFileListFilter("input"));
source.getScanner().setLocker(jdbcFileLocker);
return source;
}
Now I want to use the FileLocker jdbcFileLocker
to unlock the file after handling it in the FileWritingMessageHandler
:
@Bean
@ServiceActivator(inputChannel = "fileInputChannel")
public MessageHandler fileWritingMessageHandler() {
FileWritingMessageHandler fileWritingMessageHandler =
new FileWritingMessageHandler(new File("/workspace/out"));
Do I have to unlock the file in my own @ServiceActivator
or can I give my FileLocker
somehow to the FileWritingMessageHandler?
EDIT: Adding an ExpressionEvaluatingRequestHandlerAdvice
@Bean
ExpressionEvaluatingRequestHandlerAdvice unlockAdvice() {
ExpressionEvaluatingRequestHandlerAdvice advice =
new ExpressionEvaluatingRequestHandlerAdvice();
advice.setSuccessChannel(unlockChannel);
return advice;
}
So I can add this Advice
to my FileWritingMessageHandler
:
@Autowired
ExpressionEvaluatingRequestHandlerAdvice unlockAdvice;
@Bean
@ServiceActivator(inputChannel = "fileInputChannel")
public MessageHandler fileWritingMessageHandler() {
FileWritingMessageHandler handler =
new FileWritingMessageHandler(new File("/workspace/out"));
handler.setFileExistsMode(FileExistsMode.REPLACE);
handler.setDeleteSourceFiles(true);
handler.setExpectReply(false);
handler.setFileNameGenerator(message -> "output");
handler.setAdviceChain(List.of(unlockAdvice));
return handler;
}
The unlocking is then handled by a @ServiceActivator
listening to the unlockChannel
.
First of all consider to use fileWritingMessageHandler.setExpectReply(false)
. Since by default a FileWritingMessageHandler
behaves as a gateway and is going to try to produce a reply which is not handled in your flow and therefore some error is going to be thrown to your poller.
For your FileLocker
use-case see an ExpressionEvaluatingRequestHandlerAdvice
on your fileWritingMessageHandler
service activator. Its onSuccessExpression
could do an unlocking which is really going to be done after the FileWritingMessageHandler
finishes its process. See docs for more info: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#message-handler-advice-chain
Another is to have a fileInputChannel
as a PublishSubscribeChannel
without changing a configuration for the current fileWritingMessageHandler
. But you add another service activator subscriber to that channel which is going to perform FileLocker.unlock()
logic. To ensure that second subscriber is called after the first, consider to add an @Order(100)
for your unlocker service activator. Also see docs: https://docs.spring.io/spring-integration/docs/current/reference/html/core.html#channel-implementations-publishsubscribechannel