Spring Integration - konfiguracja FtpInboundFileSynchronizer Comparator z DSL
Spring Integration FtpInboundFileSynchronizerumożliwia ustawienie a, Comparator<FTPFile>aby umożliwić porządkowanie plików do pobrania. Dokumentacja mówi:
Począwszy od wersji 5.1, synchronizator może być wyposażony w komparator. Jest to przydatne podczas ograniczania liczby plików pobieranych za pomocą maxFetchSize.
To jest dobre dla konfiguracji @Bean:
@Bean
public FtpInboundFileSynchronizer ftpInboundFileSynchronizer(...)
FtpInboundFileSynchronizer synchronizer = new FtpInboundFileSynchronizer(sessionFactory);
...
synchronizer.setComparator(comparator);
return synchronizer;
}
Ale jeśli chcę programowo składać przepływy, zachęcam do korzystania z Java DSL.
StandardIntegrationFlow flow = IntegrationFlows
.from(Ftp.inboundAdapter(ftpFileSessionFactory, comparator)
.maxFetchSize(1)
...
Komparator w Ftp.inboundAdapter(...)metodzie fabrycznej służy tylko do lokalnego porównywania plików po ich pobraniu. Istnieją ustawienia konfiguracyjne, które są przekazywane do synchronizatora (takie jak katalog zdalny, znacznik czasu itp.). Ale nie ma ustawienia synchronizatora równoważnego ustawieniu go powyżej.
Próba rozwiązania:
Alternatywą jest utworzenie synchronizatora jako niebędącego fasolą, utworzenie FtpInboundFileSynchronizingMessageSourcew podobny sposób i użycie IntegrationFlows.from(source)do złożenia synchronizatora powoduje wyjątek czasu wykonywania, gdy przepływ jest rejestrowany w kontekście przepływu:
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]
To ma sens; FtpInboundFileSynchronizernie ma być wykonana poza kontekst. (Chociaż wydaje się, że to działa.) Ale jak w takim przypadku mogę dynamicznie łączyć przepływy integracji ftp z synchronizatorem skonfigurowanym z Comparator<FTPFile>?
Odpowiedzi
Wygląda na to, że przegapiliśmy ujawnienie tej remoteComparatoropcji w DSL.
Zapraszam do zgłaszania problemu z GH lub nawet wnoszenia poprawek: https://github.com/spring-projects/spring-integration/issues
Jako obejście dla dynamicznych przepływów, naprawdę proponuję iść odrębną FtpInboundFileSynchronizeri FtpInboundFileSynchronizingMessageSource, a następnie użyj wspomniano IntegrationFlows.from(source). To, czego prawdopodobnie brakuje w Twojej konfiguracji, to ten interfejs 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);
Mam na myśli FtpInboundFileSynchronizingMessageSourceto, że można to przekazać from()jako a jest, ale synchronizernależy je dodać jako dodatkowe ziarno do rejestracji.
Innym bardziej wymyślnym sposobem jest rozważenie zastosowania nowej funkcji zwanej rozszerzeniami DSL: https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/dsl.html#java-dsl-extensions
Możesz więc rozszerzyć to, FtpInboundChannelAdapterSpecaby zapewnić pominiętą opcję konfiguracji dla wewnętrznego synchronizer.