我已经为这个bean配置了spring集成:
private static final Pattern FILE_PATTERN = Pattern.compile("<pattern>");
@Bean
public SessionFactory<FTPFile> ftpSessionFactory(){
DefaultFtpSessionFactory factory = new DefaultFtpSessionFactory();
factory.setHost("localhost");
factory.setPort(21);
factory.setUsername("root");
factory.setPassword("123456");
factory.setClientMode(FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE);
return new CachingSessionFactory<>(factory);
}
@Bean
public ConcurrentMetadataStore metadataStore(){
PropertiesPersistingMetadataStore store = new PropertiesPersistingMetadataStore();
store.setFileName("ftpStore.properties");
return store;
}
@Bean(destroyMethod = "close")
public DataSource selectDataSource(){
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://10.10.10.10:33306/csv");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager(){
return new DataSourceTransactionManager(selectDataSource());
}
@Bean
public TransactionSynchronizationFactory synchronizationFactory(){
return new DefaultTransactionSynchronizationFactory(new TransactionSynchronizationProcessor() {
@Override
public void processBeforeCommit(IntegrationResourceHolder integrationResourceHolder) {
int x = 22; //???
}
@Override
public void processAfterCommit(IntegrationResourceHolder integrationResourceHolder) {
int x = 22; //???
}
@Override
public void processAfterRollback(IntegrationResourceHolder integrationResourceHolder) {
int x = 22; //???
}
});
}
@Bean
public PollerMetadata pollerMetadata(PlatformTransactionManager transactionManager){
PeriodicTrigger trigger = new PeriodicTrigger(5000);
trigger.setFixedRate(true);
MatchAlwaysTransactionAttributeSource source = new MatchAlwaysTransactionAttributeSource();
source.setTransactionAttribute(new DefaultTransactionAttribute());
TransactionInterceptor interceptor = new TransactionInterceptor(transactionManager, source);
PollerMetadata metadata = new PollerMetadata();
metadata.setTrigger(trigger);
metadata.setTransactionSynchronizationFactory(synchronizationFactory());
metadata.setAdviceChain(Collections.singletonList(interceptor));
return metadata;
}
@Bean
@InboundChannelAdapter(channel = "ftpChannel", poller = @Poller("pollerMetadata"))
public MessageSource<InputStream> ftpMessageSource(){
FtpStreamingMessageSource source = new FtpStreamingMessageSource(new FtpRemoteFileTemplate(ftpSessionFactory()));
source.setRemoteDirectory("ftp/folder");
source.setFilter(new CompositeFileListFilter<>(Arrays.asList(
new FtpRegexPatternFileListFilter(FILE_PATTERN),
acceptOnceFileListFilter()
)));
return source;
}
@Bean
public FtpPersistentAcceptOnceFileListFilter acceptOnceFileListFilter(){
FtpPersistentAcceptOnceFileListFilter filter = new FtpPersistentAcceptOnceFileListFilter(metadataStore(), "remote");
filter.setFlushOnUpdate(true);
return filter;
}
@Bean
@ServiceActivator(inputChannel = "newChannel")
public MessageHandler handler(){
return new MessageHandler(){
@Override
public void handleMessage(Message<?> message) throws MessagingException {
System.out.println(message.getPayload());
throw new MessagingException("error");
}
};
}
@Bean
public MessageChannel ftpChannel(){
return new DirectChannel();
}
@Bean
public MessageChannel newChannel(){
return new DirectChannel();
}
@Bean
public MessageChannel strChannel(){
return new DirectChannel();
}
@Bean
@Transformer(inputChannel = "ftpChannel", outputChannel = "strChannel")
public org.springframework.integration.transformer.Transformer transformer2(){
return new StreamTransformer("UTF-8");
}
@Bean
@Transformer(inputChannel = "strChannel", outputChannel = "newChannel")
public UnmarshallingTransformer transformer(){
UnmarshallingTransformer transformer = new UnmarshallingTransformer(unmarshaller());
return transformer;
}
@Bean
public Jaxb2Marshaller unmarshaller(){
Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
unmarshaller.setContextPath("com.generated.xsd");
return unmarshaller;
}
我的问题是在throw new MessagingException("error");
上,所有ftp文件都保存到ftpStore.properties
并在下次重新加载时(例如,如果JVM失败),这些文件将不再被处理。如何确保事务处于适当位置(即如果没有异常文件保存到ftpStore.properties
,否则不会)?是否有一些教程要遵循以便从FTP服务器下载文件的故障?
答案 0 :(得分:1)
对此问题有一个ResettableFileListFilter
抽象。
事实上你的FtpPersistentAcceptOnceFileListFilter
就是这样的一个:
如果在同步文件后,下游流处理文件时发生错误,则不会自动回滚过滤器,因此默认情况下不会重新处理失败的文件。
如果您希望在发生故障后重新处理此类文件,可以使用类似于以下内容的配置,以便于从过滤器中删除失败的文件。这适用于任何
ResettableFileListFilter
。
XML配置示例如下:
<int:transaction-synchronization-factory id="syncFactory">
<int:after-rollback expression="@acceptOnceFilter.remove(payload)" />
</int:transaction-synchronization-factory>
因此,您需要的是分别使用适当的synchronizationFactory
和DefaultTransactionSynchronizationFactory
调整ExpressionEvaluatingTransactionSynchronizationProcessor
。