Introduction à l’intégration printanière

1. Introduction

Cet article présentera les concepts de base de Spring Integration principalement par le biais de petits exemples pratiques.

Spring Integration fournit de nombreux composants puissants qui peuvent grandement améliorer l’interconnectivité des systèmes et des processus au sein d’une architecture d’entreprise.

Il incarne certains des modèles de conception les plus sophistiqués et les plus populaires, aidant les développeurs à éviter de faire rouler les leurs.

Nous examinerons les besoins spécifiques que cette bibliothèque remplit dans une application d’entreprise et pourquoi elle est recommandée par rapport à certaines de ses alternatives. Nous examinerons également certains outils disponibles pour simplifier davantage le développement d’applications basées sur Spring Integration.

2. Installer

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-core</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-file</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>

Vous pouvez télécharger les dernières versions de Spring Integration Core et la recherche https://. maven.org/classic/#search%7Cga%7C1%7Cspring-integration-file[Spring Integration File Support]de Maven Central.

3. Le modèle de messagerie

L’un des modèles de base de cette bibliothèque est la messagerie. Le modèle est centré autour de messages - des charges utiles discrètes de données qui passent d’un système ou processus d’origine à un ou plusieurs systèmes ou processus via des canaux prédéfinis.

Historiquement, le modèle apparaissait comme le moyen le plus flexible d’intégrer plusieurs systèmes disparates d’une manière qui:

  • Découpe presque complètement les systèmes impliqués dans l’intégration

  • Permet aux systèmes participant à l’intégration d’être complètement

agnostiques les uns des autres protocoles sous-jacents, formatage, ou autre Détails d’implémentation ** Encourage le développement et la réutilisation des composants impliqués dans la

l’intégration

4. Intégration de la messagerie en action

Considérons un exemple de base qui copie un fichier vidéo MPEG d’un dossier désigné dans un autre dossier configuré:

@Configuration
@EnableIntegration
public class BasicIntegrationConfig{
    public String INPUT__DIR = "the__source__dir";
    public String OUTPUT__DIR = "the__dest__dir";
    public String FILE__PATTERN = "** .mpeg";

    @Bean
    public MessageChannel fileChannel() {
        return new DirectChannel();
    }

    @Bean
    @InboundChannelAdapter(value = "fileChannel", poller = @Poller(fixedDelay = "1000"))
    public MessageSource<File> fileReadingMessageSource() {
        FileReadingMessageSource sourceReader= new FileReadingMessageSource();
        sourceReader.setDirectory(new File(INPUT__DIR));
        sourceReader.setFilter(new SimplePatternFileListFilter(FILE__PATTERN));
        return sourceReader;
    }

    @Bean
    @ServiceActivator(inputChannel= "fileChannel")
    public MessageHandler fileWritingMessageHandler() {
        FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(OUTPUT__DIR));
        handler.setFileExistsMode(FileExistsMode.REPLACE);
        handler.setExpectReply(false);
        return handler;
    }
}

Le code ci-dessus configure un activateur de service, un canal d’intégration et un adaptateur de canal entrant.

Nous allons examiner chacun de ces types de composants plus en détail sous peu.

L’annotation @ EnableIntegration désigne cette classe en tant que configuration d’intégration Spring.

Commençons par le contexte de notre application Spring Integration:

public static void main(String... args) {
    AbstractApplicationContext context
      = new AnnotationConfigApplicationContext(BasicIntegrationConfig.class);
    context.registerShutdownHook();

    Scanner scanner = new Scanner(System.in);
    System.out.print("Please enter q and press <enter> to exit the program: ");

    while (true) {
       String input = scanner.nextLine();
       if("q".equals(input.trim())) {
          break;
      }
    }
    System.exit(0);
}

La méthode principale ci-dessus démarre le contexte d’intégration; il accepte également le caractère « q » saisi en ligne de commande pour quitter le programme. Laissez-nous examiner les composants plus en détail.

5. Composants d’intégration Spring

5.1. Message

L’interface org.springframework.integration.Message définit le message spring: l’unité de transfert de données dans un contexte d’intégration Spring.

public interface Message<T> {
    T getPayload();
    MessageHeaders getHeaders();
}

Il définit les accesseurs à deux éléments clés:

  • En-têtes de message, essentiellement un conteneur clé-valeur pouvant être utilisé pour

transmettre des métadonnées, comme défini dans le org.springframework.integration.MessageHeaders class ** La charge utile du message, qui correspond aux données réelles qui ont de la valeur

transféré - dans notre cas d’utilisation, le fichier vidéo est la charge utile

5.2. Canal

Un canal dans Spring Integration (et effectivement, EAI) constitue la tuyauterie de base dans une architecture d’intégration. C’est le canal par lequel les messages sont relayés d’un système à un autre.

Vous pouvez le considérer comme un tuyau littéral à travers lequel un système ou un processus intégré peut transmettre des messages à (ou recevoir des messages d’autres systèmes).

Les canaux dans Spring Integration sont proposés sous différentes formes, en fonction de vos besoins. Ils sont en grande partie configurables et utilisables tels quels, sans code personnalisé, mais si vous avez des besoins personnalisés, un cadre robuste est disponible.

Les canaux Point-to-Point (P2P) sont utilisés pour établir des lignes de communication un à un entre des systèmes ou des composants. Un composant publie un message sur le canal afin qu’un autre puisse le récupérer. Il ne peut y avoir qu’un seul composant à chaque extrémité du canal.

Comme nous l’avons vu, la configuration d’un canal est aussi simple que de renvoyer une instance de DirectChannel :

@Bean
public MessageChannel fileChannel1() {
    return new DirectChannel();
}

@Bean
public MessageChannel fileChannel2() {
    return new DirectChannel();
}

@Bean
public MessageChannel fileChannel3() {
    return new DirectChannel();
}

Ici, nous avons défini trois canaux distincts, tous identifiés par le nom de leurs méthodes de lecture respectives.

Les canaux Publish-Subscribe (Pub-Sub) servent à établir une ligne de communication un à plusieurs entre des systèmes ou des composants. Cela nous permettra de publier sur les 3 canaux directs que nous avons créés précédemment.

En suivant notre exemple, nous pouvons remplacer le canal P2P par un canal pub-sub:

@Bean
public MessageChannel pubSubFileChannel() {
    return new PublishSubscribeChannel();
}

@Bean
@InboundChannelAdapter(value = "pubSubFileChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
    FileReadingMessageSource sourceReader = new FileReadingMessageSource();
    sourceReader.setDirectory(new File(INPUT__DIR));
    sourceReader.setFilter(new SimplePatternFileListFilter(FILE__PATTERN));
    return sourceReader;
}

Nous avons maintenant converti l’adaptateur de canal entrant en publication sur un canal Pub-Sub. Cela nous permettra d’envoyer les fichiers en cours de lecture du dossier source vers plusieurs destinations.

5.3. Pont

Un pont dans Spring Integration est utilisé pour connecter deux canaux de message ou des adaptateurs s’ils ne peuvent pas se connecter directement pour une raison quelconque.

Dans notre cas, nous pouvons utiliser un pont pour connecter notre canal Pub-Sub à trois canaux P2P différents (car les canaux P2P et Pub-Sub ne peuvent pas être connectés directement):

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel1() {
    return new DirectChannel();
}

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel2() {
    return new DirectChannel();
}

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel3() {
    return new DirectChannel();
}

La configuration de bean ci-dessus relie maintenant pubSubFileChannel à trois canaux P2P. L’annotation @ BridgeFrom définit un pont et peut être appliquée à un nombre quelconque de canaux devant s’abonner au canal Pub-Sub.

Nous pouvons lire le code ci-dessus comme "crée un pont entre pubSubFileChannel et fileChannel1, fileChannel2 et fileChannel3 de sorte que les messages de pubSubFileChannel puissent être envoyés simultanément aux trois canaux."

5.4. Service Activator

Service Activator est un POJO qui définit l’annotation @ ServiceActivator sur une méthode donnée. Cela nous permet d’exécuter n’importe quelle méthode sur notre POJO lorsqu’un message est reçu depuis un canal entrant et nous permet d’écrire des messages sur un canal sortant.

Dans notre exemple, notre activateur de service reçoit un fichier du input channel configuré et l’enregistre dans le dossier configuré.

5.5. Adaptateur

L’adaptateur est un composant basé sur un modèle d’intégration d’entreprise qui permet de «brancher» un système ou une source de données. Il s’agit presque littéralement d’un adaptateur, tel que nous le connaissons, car il est branché sur une prise murale ou un appareil électronique.

Il permet une connectivité réutilisable vers des systèmes «à fond noir» tels que des bases de données, des serveurs FTP et des systèmes de messagerie tels que JMS, AMQP et des réseaux sociaux tels que Twitter. La nécessité de se connecter à ces systèmes étant omniprésente, les adaptateurs sont très portables et réutilisables (il existe en fait un petit fichier catalog de adaptateurs , librement disponibles et prêts à être utilisés par n’importe qui).

  • Les adaptateurs se divisent en deux grandes catégories - entrant et sortant. **

Examinons ces catégories dans le contexte des adaptateurs utilisés dans notre exemple de scénario:

Les adaptateurs entrants ** , comme nous l’avons vu, sont utilisés pour importer des messages provenant du système externe (dans ce cas, un répertoire du système de fichiers).

Notre configuration d’adaptateur entrant comprend:

  • Une annotation @ InboundChannelAdapter qui marque le bean

configuration en tant qu’adaptateur - nous configurons le canal auquel le adaptateur alimentera ses messages (dans notre cas, un fichier MPEG) et un poller , un composant qui aide l’adaptateur à interroger le dossier configuré à l’intervalle spécifié ** Une classe de configuration standard Java java qui renvoie un

FileReadingMessageSource, l’implémentation de la classe d’intégration Spring qui gère l’interrogation du système de fichiers

  • Les adaptateurs sortants ** sont utilisés pour envoyer des messages vers l’extérieur. Spring Integration prend en charge un grand nombre d’adaptateurs prêts à l’emploi pour divers cas d’utilisation courants.

6. Conclusion

Nous avons examiné un cas d’utilisation de base avec Spring Integration qui illustre la configuration de la bibliothèque basée sur Java et la possibilité de réutilisation des composants disponibles.

Le code d’intégration Spring est déployable en tant que projet autonome dans JavaSE et fait partie d’un élément plus volumineux dans un environnement JavaEE.

Même s’il ne concurrence pas directement d’autres produits et modèles axés sur EAI, tels que les bus de service d’entreprise (Enterprise Service Buses, ESB), il s’agit d’une alternative viable et légère à la résolution de nombreux problèmes identiques à ceux conçus pour les serveurs ESB.

Vous pouvez trouver le code source de cet article dans le projet Github