英文:
spring integration advice afterReceive method not called in unit test
问题
你的问题是你的EmptyFolderAdvice类中的afterReceive方法从未被调用。这可能是由于配置或测试问题引起的。以下是一些建议来排查问题:
-
确保你的配置文件
FlowConfiguration
中正确地配置了emptyFolderAdvice()
作为定期调度器(PollerMetadata
)的建议(advice)。你的配置看起来是正确的,但要确保没有其他地方覆盖了这个配置。 -
在你的测试类
StopApplicationTest
中,确保EmptyFolderAdvice
类的bean(advice
)被正确注入。你可以在测试方法中添加一些日志或断言来确认它是否已成功注入。 -
确保你的测试方法的消息(message)实际上被发送到了
inputChannel
。你可以添加日志来检查消息是否被发送,并确保在发送消息之后等待一些时间以确保方法被调用。 -
如果仍然存在问题,检查是否有其他配置或切面可能会影响建议(advice)的调用。可能会有其他方面或拦截器干扰了建议的执行。
通过检查这些方面,你应该能够找到为什么EmptyFolderAdvice
的afterReceive
方法没有被调用的原因。如果问题仍然存在,请提供更多详细信息,以便我可以提供更多帮助。
英文:
Hello i'am trying to add an advice to handle the case of empty files in a directory , the use case is when the directory is empty we should stop the application which is a springbok application .
here is my configuration file :
@Configuration
public class FlowConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(FlowConfiguration.class);
@Bean("creFileInboundChannel")
MessageChannel fileInputChannel() {
return new DirectChannel();
}
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers.fixedRate(1000)
.advice(emptyFolderAdvice())
.get();
}
@Bean
DirectoryScanner directoryScanner(@Value("${inbound.filename.regex:.*}") String regex) {
RecursiveDirectoryScanner scanner = new RecursiveDirectoryScanner();
CompositeFileListFilter filter = new CompositeFileListFilter<>(
Arrays.asList(new AcceptOnceFileListFilter<>(),
new RegexPatternFileListFilter(regex))
);
scanner.setFilter(filter);
return scanner;
}
@Bean
@InboundChannelAdapter(value = "creFileInboundChannel", poller = @Poller(fixedDelay = "1000"))
MessageSource<File> fileReadingMessageSource(DirectoryScanner directoryScanner, CreConfiguration creConfiguration) {
FileReadingMessageSource source = new FileReadingMessageSource();
source.setDirectory(new File(creConfiguration.getInputDir()));
source.setScanner(directoryScanner);
return source;
}
@Bean
@ServiceActivator(inputChannel = "creOutputChannel")
MessageHandler logOutputCreFileHandler() {
return message -> {
if (message.getPayload() instanceof Optional) {
Optional<File> filteredFile = (Optional<File>) message.getPayload();
if (filteredFile.isPresent()) {
LOGGER.info("end of process {}, writing file in the output directory", filteredFile.get());
}
}
};
}
@Bean
@ServiceActivator(inputChannel = "creFileInboundChannel")
MessageHandler creFileInFolderHandler(TraitementCreService traitementCreService) {
List<Advice> advices = new ArrayList<>();
advices.add(emptyFolderAdvice());
ServiceActivatingHandler serviceActivatingHandler = new ServiceActivatingHandler(traitementCreService, "invoke");
serviceActivatingHandler.setOutputChannelName("creOutputChannel");
serviceActivatingHandler.setAdviceChain(advices);
return serviceActivatingHandler;
}
@Bean
@ServiceActivator(inputChannel = "errorChannel")
MessageHandler erreurHandler() {
return message ->
LOGGER.info("Error when treating file : {}", ((ErrorMessage) message).getOriginalMessage().getPayload());
}
@Bean("errorChannel")
QueueChannel errorChannel() {
return new QueueChannel(500);
}
@Bean
public EmptyFolderAdvice emptyFolderAdvice() {
return new EmptyFolderAdvice();
}
}
here is my advice class that handles shutdown when directory is empty :
public class EmptyFolderAdvice extends AbstractMessageSourceAdvice {
@Override
public Message<?> afterReceive(Message<?> message, MessageSource<?> source) {
File directory = (File) source;
File[] files = directory.listFiles();
if (files == null || files.length == 0) {
System.exit(0); // Stop the application if no files exist
}
return message;
}
}
here is my integration test :
@SpringIntegrationTest
@SpringBootTest
@ContextConfiguration(classes = FiltrageApp.class)//{FlowConfiguration.class, FiltrageConfiguration.class})
public class StopApplicationTest {
@MockBean
private EmptyFolderAdvice advice; // Inject the advice under test
@Qualifier("creFileInboundChannel")
@Autowired
private MessageChannel inputChannel;
@MockBean
TraitementCreService traitementCreService;
@Autowired
private MessageSource<?> messageSource;
@Autowired
private ApplicationContext context;
@Autowired
private MessageHandler creFileInFolderHandler;
@Test
public void testAfterReceiveIsCalled() throws TechnicalException {
// Create a test message
Message<?> message = MessageBuilder.withPayload("").build();
// Send the message to the input channel
//traitementCreService.invoke(null);
inputChannel.send(message);
traitementCreService.invoke(null);
// Verify that the afterReceive method is called
Mockito.verify(advice).afterReceive(Mockito.any(Message.class), Mockito.any(MessageSource.class));
// You can also verify the number of times the method is called, e.g., Mockito.verify(mockAdvice, Mockito.times(1)).afterReceive(...)
}
my problem is that is does not work and the afterReceive method of the advice is never called.
thanks
答案1
得分: 1
你在配置中使用了显式的轮询器:
@InboundChannelAdapter(value = "creFileInboundChannel", poller = @Poller(fixedDelay = "1000"))
但是你应用了emptyFolderAdvice()
,它是没有用的。
你仍然需要一个PollerMetadata
bean,但它不能是PollerMetadata.DEFAULT_POLLER
,并且在@Poller
中使用它的名称:
/**
* @return {@link org.springframework.integration.scheduling.PollerMetadata} bean 的名称。
*/
String value() default "";
你的EmptyFolderAdvice
中的逻辑也是错误的:
public Message<?> afterReceive(Message<?> message, MessageSource<?> source) {
File directory = (File) source;
如何将MessageSource
强制转换为 File
?
你只需要检查 message == null
:如果没有要从 FileReadingMessageSource
中生成的文件,那么会调用此 afterReceive()
方法,并且 message
会为 null
。
英文:
You use an explicit poller in your configuration:
@InboundChannelAdapter(value = "creFileInboundChannel", poller = @Poller(fixedDelay = "1000"))
But you apply your emptyFolderAdvice()
which is out of use.
You still need to have a PollerMetadata
bean, but that must not be a PollerMetadata.DEFAULT_POLLER
and use its name in the @Poller
:
/**
* @return The {@link org.springframework.integration.scheduling.PollerMetadata} bean
* name.
*/
String value() default "";
The logic in your EmptyFolderAdvice
is also wrong:
public Message<?> afterReceive(Message<?> message, MessageSource<?> source) {
File directory = (File) source;
How a MessageSource
can be casted to a File
?
You just need to check for message == null
: if no files to produce from a FileReadingMessageSource
, then this afterReceive()
method is called with null
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论