Intégration Spring - Configuration du comparateur FtpInboundFileSynchronizer avec DSL

Aug 22 2020

Spring Integration FtpInboundFileSynchronizerpermet de définir un Comparator<FTPFile>pour permettre la commande des téléchargements. La documentation dit:

A partir de la version 5.1, le synchroniseur peut être équipé d'un comparateur. Ceci est utile lors de la restriction du nombre de fichiers récupérés avec maxFetchSize.

C'est bien pour la configuration @Bean :

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

Mais si je veux assembler des flux par programmation, le Java DSL est encouragé.

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

Le comparateur dans la Ftp.inboundAdapter(...)méthode d'usine sert uniquement à comparer les fichiers localement, après leur téléchargement. Il y a des paramètres de configuration qui sont transmis au synchroniseur ici (comme le répertoire distant, l'horodatage, etc.). Mais il n'y a pas de réglage pour le synchroniseur équivalent au réglage ci-dessus.

Tentative de résolution :

L'alternative consiste à créer le synchroniseur en tant que non-bean, à le créer FtpInboundFileSynchronizingMessageSourcede la même manière et à l'utiliser IntegrationFlows.from(source)pour assembler les résultats du synchroniseur dans une exception d'exécution lorsque le flux est enregistré avec le contexte de flux :

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]

Ça a du sens; le FtpInboundFileSynchronizern'est pas censé être construit en dehors d'un contexte. (Bien que cela semble fonctionner.) Mais comment, dans ce cas, puis-je assembler dynamiquement des flux d'intégration ftp avec un synchroniseur configuré avec un Comparator<FTPFile>?

Réponses

2 ArtemBilan Aug 24 2020 at 20:47

On dirait que nous avons manqué d'exposer cette remoteComparatoroption dans DSL.

N'hésitez pas à soulever un problème de GH ou même à contribuer à un correctif :https://github.com/spring-projects/spring-integration/issues

Comme solution de contournement pour les flux dynamiques, je suggérerais vraiment d'utiliser un fichier séparé FtpInboundFileSynchronizer, FtpInboundFileSynchronizingMessageSourcepuis d'utiliser le fichier IntegrationFlows.from(source). Ce qui vous manque probablement dans votre configuration, c'est cette 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);

Je veux dire que FtpInboundFileSynchronizingMessageSourcec'est OK pour passer au from()tel quel, mais synchronizerdoit être ajouté en tant que haricot supplémentaire pour l'enregistrement.

Une autre façon plus sophistiquée consiste à envisager d'utiliser une nouvelle fonctionnalité appelée extensions DSL :https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/dsl.html#java-dsl-extensions

Ainsi, vous pouvez étendre cela FtpInboundChannelAdapterSpecpour fournir une option manquée à configurer pour un fichier synchronizer.