Spring統合-DSLを使用したFtpInboundFileSynchronizerコンパレータ構成

Aug 22 2020

Spring IntegrationFtpInboundFileSynchronizerではComparator<FTPFile>、ダウンロードの順序を許可するようにを設定できます。ドキュメントには次のように書かれています。

バージョン5.1以降、シンクロナイザーにはコンパレーターを提供できます。これは、maxFetchSizeでフェッチされるファイルの数を制限する場合に役立ちます。

これは@Bean構成には問題ありません。

 @Bean
 public FtpInboundFileSynchronizer ftpInboundFileSynchronizer(...)
        FtpInboundFileSynchronizer synchronizer = new FtpInboundFileSynchronizer(sessionFactory);
        ...
        synchronizer.setComparator(comparator);
        return synchronizer;
    }

しかし、プログラムでフローをアセンブルしたい場合は、JavaDSLをお勧めします。

 StandardIntegrationFlow flow = IntegrationFlows
                .from(Ftp.inboundAdapter(ftpFileSessionFactory, comparator)
                                .maxFetchSize(1)
    ...

Ftp.inboundAdapter(...)ファクトリメソッドのコンパレータは、ファイルがダウンロードされた後、ローカルでファイルを比較するためだけのものです。ここにシンクロナイザーに渡される構成設定があります(リモートディレクトリ、タイムスタンプなど)。ただし、上記の設定に相当するシンクロナイザーの設定はありません。

解決策の試み:

別の方法は、シンクロナイザーを非Beanとして作成FtpInboundFileSynchronizingMessageSourceし、同様の方法で作成し、を使用IntegrationFlows.from(source)してシンクロナイザーをアセンブルすると、フローがフローコンテキストに登録されたときにランタイム例外が発生します。

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]

それは理にかなっている; これFtpInboundFileSynchronizerは、コンテキスト外で構築されることは想定されていません。(これは機能しているように見えますが。)しかし、その場合、Comparator<FTPFile>?で構成されたシンクロナイザーを使用してftp統合フローを動的にアセンブルするにはどうすればよいですか?

回答

2 ArtemBilan Aug 24 2020 at 20:47

remoteComparatorDSLでそのオプションを公​​開するのを見逃したようです。

GHの問題を提起するか、修正を提供してください。 https://github.com/spring-projects/spring-integration/issues

ダイナミックフローのための回避策として、私は本当に別々に行くことを示唆しているFtpInboundFileSynchronizerFtpInboundFileSynchronizingMessageSource、次に言及を使用しますIntegrationFlows.from(source)。構成でおそらく見逃しているのは、この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);

つまりFtpInboundFileSynchronizingMessageSourcefrom()そのまま渡しても問題ありsynchronizerませんが、登録用の追加Beanとして追加する必要があります。

もう1つのより凝った方法は、DSL拡張機能と呼ばれる新機能の使用を検討することです。 https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/dsl.html#java-dsl-extensions

したがって、これを拡張しFtpInboundChannelAdapterSpecて、内部用に構成するための欠落したオプションを提供できますsynchronizer