vendredi 18 octobre 2013

Paris JUG : Soirée Intégration avec Spring Intégration et Apache Camel

parisjugUn Système d'Information vit et grossit. Au cour de son expansion, il assiste à la naissance de nouvelles technos, les voit vieillir et devenir obsolètes. Parallèlement le nombre d'applications à intégrer ne cesse de croître, avec chacune ses technos, ses formats de données et ses protocoles de communication. Le domaine métier aussi évolue au même rythme que les renouvellements de personnel. Il est très peu pratique de concevoir une application pour qu'elle reste isolée. Quand elle n'est pas appelée à fournir des services ou à échanger des données avec d'autres applications, elle peut avoir besoin de s'appuyer sur de l'existant pour implémenter une fonctionnalité.

L'un des enjeux de ce contexte est de simplifier les échanges entre applications, tout en tenant compte des différentes contraintes inhérentes à un SI hétérogène (domaine métier, fiabilité et lenteur réseau, protocole, formats de données…).

Un des travaux les plus aboutis dans le domaine de l'intégration entre applications est celui de Gregor Hohpe et Bobby Woolf. Leur livre “Enterprise Integration Patterns” (EIP) , préfacé par Martin Fowler, constitue LA référence sur le sujet. Il y est présenté un catalogue de 65 patterns pour répondre aux problèmes couramment rencontrés.

Dans l'écosystème Java trois frameworks (Apache Camel, Spring Integration et Mule) fournissent chacun son implémentation des EIP à sa façon. Sur internet les blogs et les forums abondent déjà de sujets sur les points forts et les points faibles de chacun ainsi que des critères de choix.

Voilà une brève présentation du thème de la soirée Paris JUG du 08 Octobre 2013 présentée par Guillaume Giamarchi et Grégory Boissinot de la société Zenika dans les locaux de l'ISEP . Il y avait deux présentations, la première consacrée à l'EIP (Entreprise Integration Pattern) et la deuxième partie sur Spring Integration et Apache Camel, deux implémentations des EIP.

Au fil des ans l'ingénierie logicielle a vu apparaitre différents styles d'intégration :

File Transfert : Les applications communiquent par le biais d'un fichier où elles viennent écrire ou lire par intervalle de temps régulier. Un style qui pose le problème des accès concurrents.

FileTransferIntegration

Shared Data Base : Ce système fonctionne comme le FT, avec des données stockées en base. Il soulève naturellement des problématiques de Transaction.

SharedDatabaseIntegration

RPC (Remote Control Process) : Ici l'information est encapsulée dans une invocation distante (RMI et Corba). A demande à B d'effectuer une action et de lui retourner le résultat. On rencontre ici un problème de dépendance entre les deux applications, A doit connaître les interfaces de B.

EncapsulatedSynchronousIntegration

Messaging System : L'échange se fait par le biais d'un bus de messages où les données transitent. La communication se fait de manière asynchrone. JMS et AMQP sont des exemples de Messaging.

Messaging

Parmi ces quatre styles d'intégration le Messaging est celui qui répond le mieux, grâce à sa flexibilité, aux problèmes rencontrés. Il permet un couplage faible entre les applications. Dans ce système on se focalise plus sur la structure des données échangées que sur la manière dont elles sont produites.
Le système de Messaging est structuré autour de six concepts qui forment les briques de bases pour la conception d'un système.

Message : Les données échangées entre deux applications sont encodées dans un message. Il est composé d'un header et d'un body.
MessageIcon
Channel : Il établit la liaison entre deux applications. C'est le chemin virtuel par lequel sont transmis (et reçus) les Messages.
ChannelIcon
Pipe & Filter : C'est un enchainement de traitements, dans lequel la sortie d'un traitement est utilisé comme entrée du traitement suivant.
PipesAndFiltersIcon
Routing : Le routing consiste à consommer un message (sans l'altérer) et à choisir une sortie en fonction de conditions déterminées dynamiquement.
ContentBasedRouterIcon
Transformer : Le transformer, comme son l'indique, transforme le message consommé à l'entrée pour à la sortie.
MessageTranslatorIcon
End point : C'est le point d'entrée/sortie d'une application, son interface avec l'extérieur. C'est lui qui encode le Message (en lui ajoutant un header) avant de le mettre sur un channel. A l'autre bout, le message est également reçu et décodé (extraction du content) par un End Point.
MessageEndpointIcon

Spring Integration

C'est l'implémentation de Spring pour les EIP. Ses principaux composants sont le Message, le MessageChannel, et le MessageEndpoint. Il bénéficie en tant que partie intégrante de Spring portfolio des fonctionnalités de base de Spring core, lifecycle management, Task Execution, Aspect-Oriented Progaramming, Transaction Management, Dependancy Injection, Method Invocation,... Il est fourni avec des adaptateurs sur étagères pour les utilisations classiques (AMQP, IMAP, JMS, Mongo DB, FTP/SFTP, …). Il est fourni avec une API programmatique mais trouve sa force dans son modèle déclaratif qui permet d'avoir un couplage faible entre le métier et l'infrastructure :
  • le métier dans le code java
  • la logique d'intégration dans un fichier XML
Exemple avec AMQP :

<!-- End Point -->
<int-amqp:inbound-channel-adapter
   queue-names="testQueue"
   channel="channel1"
    ...
/>

<!-- Channel -->
<int:channel id="channel1">
    <int:interceptors>
        <int:wire-tap channel="loggingChannel" />
    </int:interceptors>
</int:channel>

<!-- Transformer -->
<int:transformer input-channel="channel1" output-channel="channel2">
    <bean class="com.spring.jug.CustomTransformer">
</int:transformer>

<!-- Channel -->
<int:channel id="channel2">
    <int:interceptors>
        <int:wire-tap channel="loggingChannel" />
    </int:interceptors>
</int:channel>

<!-- MessageHandler -->
<int:service-activator input-channel="channel2"
    output-channel="channel3"
    ref="customMessageHandler"/>

Apache Camel

Ici le composant principal est le Route. Apache Camel fournit plus de components sur étagère que Spring Integration, avec près de 150 connecteurs. En plus il peut s'intégrer facilement avec Spring Core. Tout comme Spring Integration on peut décrire avec Apache Camel le système de Messaging dans un fichier XML. Mais son originalité se trouve dans l'utilisation d'un DSL Java, (qui existe aussi en Scala ou Groovy) avec lequel il exprime le routing dans le code. Les composants sont représentés par des méthodes, from() et to() pour le EndPoint, choice() et split() pour le Routing, ...

Exemple XML

<camelcontext id="camelTargetContext">
    <route>
        <from uri="direct:EndpointA">
        <to uri="mock:result">
    </to></from></route>
    <route>
        <from uri="direct:EndpointC">
        <process ref="myProcessor">
      </process></from></route>
</camelcontext>

Exemple Java
from("direct:EndpointA").to("mock:result");

from("direct:EndpointC").recipientList().method("drinkRouter");

from("seda:coldDrinks?concurrentConsumers=2")
.to("bean:barista?method=prepareColdDrink")
.to("direct:deliveries");

Conclusion

Apache Camel et Spring Intégration sont deux solutions des EIP qui ont des approches différentes. Pour un habitué de Spring la courbe d'apprentissage est nulle pour démarrer avec Spring Integration. On y retrouvera tous les concepts de Spring Core. Mais le DSL de Apache Camel a l'avantage de présenter la logique d'intégration de manière plus lisible, plus facile à maintenir. Si vous voulez en connaître plus sur les éléments de comparaison vous pouvez jeter un coup d’œil sur les slides de Kai Wähner sur les points faibles/forts de chacun des frameworks.

Pour plus de lecture