Spring Integration - Configurazione del comparatore FtpInboundFileSynchronizer con DSL
Spring Integration FtpInboundFileSynchronizer
consente l'impostazione di a Comparator<FTPFile>
per consentire l'ordinamento dei download. La documentazione dice:
A partire dalla versione 5.1, il sincronizzatore può essere dotato di un comparatore. Questo è utile quando si limita il numero di file recuperati con maxFetchSize.
Questo va bene per la configurazione @Bean:
@Bean
public FtpInboundFileSynchronizer ftpInboundFileSynchronizer(...)
FtpInboundFileSynchronizer synchronizer = new FtpInboundFileSynchronizer(sessionFactory);
...
synchronizer.setComparator(comparator);
return synchronizer;
}
Ma se voglio assemblare in modo programmatico i flussi, il Java DSL è incoraggiato.
StandardIntegrationFlow flow = IntegrationFlows
.from(Ftp.inboundAdapter(ftpFileSessionFactory, comparator)
.maxFetchSize(1)
...
Il comparatore nel Ftp.inboundAdapter(...)
metodo di fabbrica è solo per il confronto dei file in locale, dopo che sono stati scaricati. Ci sono impostazioni di configurazione che vengono passate al sincronizzatore qui (come directory remota, timestamp, ecc.). Ma non esiste un'impostazione per il sincronizzatore equivalente all'impostazione precedente.
Tentativo di soluzione:
L'alternativa è creare il sincronizzatore come non-bean, creare FtpInboundFileSynchronizingMessageSource
in modo simile e utilizzare IntegrationFlows.from(source)
per assemblare i risultati del sincronizzatore in un'eccezione di runtime quando il flusso viene registrato con il contesto del flusso:
Creating EvaluationContext with no beanFactory
java.lang.RuntimeException: No beanFactory
at org.springframework.integration.expression.ExpressionUtils.createStandardEvaluationContext(ExpressionUtils.java:90) ~[spring-integration-core-5.3.2.RELEASE.jar:5.3.2.RELEASE]
at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.afterPropertiesSet(AbstractInboundFileSynchronizer.java:299) ~[spring-integration-file-5.3.2.RELEASE.jar:5.3.2.RELEASE]
Ha senso; il FtpInboundFileSynchronizer
non dovrebbe essere costruito al di fuori di un contesto. (Anche se questo sembra funzionare.) Ma come, in tal caso, posso assemblare dinamicamente flussi di integrazione ftp con un sincronizzatore configurato con un Comparator<FTPFile>
?
Risposte
Sembra che non abbiamo esposto questa remoteComparator
opzione in DSL.
Sentiti libero di sollevare un problema di GH o persino di contribuire a risolverlo:https://github.com/spring-projects/spring-integration/issues
Come soluzione alternativa per i flussi dinamici, suggerirei davvero di andare in un separato FtpInboundFileSynchronizer
e FtpInboundFileSynchronizingMessageSource
quindi utilizzare il suddetto IntegrationFlows.from(source)
. Quello che probabilmente ti manca nella tua configurazione è questa API:
/**
* Add an object which will be registered as an {@link IntegrationFlow} dependant bean in the
* application context. Usually it is some support component, which needs an application context.
* For example dynamically created connection factories or header mappers for AMQP, JMS, TCP etc.
* @param bean an additional arbitrary bean to register into the application context.
* @return the current builder instance
*/
IntegrationFlowRegistrationBuilder addBean(Object bean);
Voglio dire che FtpInboundFileSynchronizingMessageSource
va bene passare a from()
così com'è, ma synchronizer
deve essere aggiunto come bean extra per la registrazione.
Un altro modo più elegante è prendere in considerazione l'utilizzo di una nuova funzionalità chiamata estensioni DSL:https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/dsl.html#java-dsl-extensions
Quindi, puoi estenderlo FtpInboundChannelAdapterSpec
per fornire un'opzione mancante da configurare per un file synchronizer
.