Workshop Spring - Session 5
Etudes de cas
Spring Intégration
Diffusé en novembre 2013
Réactualisé en janvier 2015
Sommaire
Introduction à Spring Integration 3
Présentation de l’étude de cas 6
Implémentation avec Spring Integration 11
Conclusion 23
Workshop Spring Integration – Etude de Cas
2
Introduction
• Le messenging est une technique d’intégration entre
applications
– Souvent basé sur un Message Oriented Middleware (MoM)
• Permet 3 formes de Découplage :
• Spatial
• Temporel
• Logique
• Certains partisans poussent son Utilisation Au sein même
d’une même application
• Composants échangeant des données par messages en mémoire
• Applications orientées évènements
• Adaptateurs permettant de se connecter à des systèmes externes
3
Communication par messages
Introduction
• Livre cataloguant les patterns de type messaging utilisés
en entreprise pour architecturer le SI
– Ecrit par Gregor Hohpe et Bobby Woolf
• Standardisation de concepts MOM
• Liste de Patterns et iconographie
• Message
• Contient des En-têtes et un Contenu (Payload)
• Channel
• Point à Point ou de type Publish / Subscribe
• Envoi bloquant ou asynchrone
• Endpoint
• Connecte les Channels au code applicatif
et aux systèmes externes
4
Enterprise Integration Patterns (EIP)
Introduction
• Implémentation des Enteprise integration patterns
• Apache CAMEL en est une autre
• Repose sur le framework Spring et de
nombreux projets
• Reste un simple Framewok
• Offre de nombreux adapateurs :
• JMS
• JDBC, JPA, Mongo DB, REDIS
• HTTP, TCP / UDP
• Fichier, FTP, SFTP
• RSS, ATOM
• Mail, Twitter, XMPP, XML, Web services, RMI
5
Spring Intégration
Présentation de l’étude de cas
• Application de recherche et d’indexation
o Basée sur le moteur Elasticsearch
o Données métier issues de différents
référentiels et Back Office
• Indexation des données au fil de l’eau
o Mise en œuvre au sein d’une architecture SOA
o Exploitant l’infrastructure existante (ESB)
6
Application Indexo
Notification asynchrone envoyée à Indexo par JMS lors d’une création /
modification / suppression d’un ou plusieurs Produits
Consultation des données produits par appel d’un web service SOAP
Construction puis écriture du document à indexer dans Elasticsearch
7
Présentation de l’étude de cas
Communication entre applications
Serveur
Elasticsearch
Indexo
Module
d’indexation fil
de l’eau
Produx
Référentiel
Produits
ESB
JMS / XML
HTTP / SOAP
TCP / JSON
1
1
2
2
3
3
8
A format XML, une notification est composée de 2 parties :
1. En-tête technique : standardisé par le framework de notification de l’ESB
2. Partie métier : spécifique à l’application Indexo
• Cartouche technique :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Notification xmlns="http://v1.event.esb.javaetmoi.com">
<Header>
<Label>Business Object Domain Changes</Label>
<SentTime>2015-01-12T21:10:30+02:00</SentTime>
<Version>1</Version>
<MessageNumber>1456098922309</MessageNumber>
<Origin>PRODUX</Origin>
<Type>BODC</Type>
</Header>
<Body>Notification métier</Body>
</Notification>
Utilisé par l’ESB:
• Filtrage
• Routage JMS
Contenu
au format XML
Présentation de l’étude de cas
Notifications (1/2)
• Partie Métier
• Contient les informations relatives à la modification d'un ou plusieurs
objets métiers
• Spécifiée par une XSD (au même titre que le cartouche technique)
9
Présentation de l’étude de cas
Notifications (2/2)
Propriété Type Description
action Enumération Action de création, de modification ou de
suppression d'un objet métier
actionDate Timestamp Date et heure à laquelle l'action a eu lieu
businessId String Identifiant métier de l'objet mis à jour
objectTypeCode String Contient le nom des objets métiers du
dictionnaire d'entreprise
10
1. Lecture de la notification à partir de la file JMS
2. Filtrage à partir du cartouche technique
Permet d’écarter les notifications non destinées à Indexo
3. Traitement des erreurs
Fichier de logs et envoi de mails
4. Extraction puis unmarshalling XML de la partie métier
5. Séparation en informations de mise à jour unitaire
6. Routage en fonction de l’action
Le traitement des notifications de suppression est
transverse à tous les objets métiers
7. Routage en fonction du type d’objet métier
8. Récupération des données à indexer
Appel du ou des web services SOAP ou REST de consultation
9. Construction du document Lucene à indexer
10.Ecriture du document dans Elasticsearch
Présentation de l’étude de cas
Décomposition du traitement des notifications
Implémentation avec Spring Intégration
• Beans d’infrastructure du contexte applicatif Spring
• Connection Fatory JMS, File JMS (lookup JNDI ou standalone)
• Pools de threads (TaskExecutor)
• Marshaller JAXB 2 (Spring OXM)
• Clients Spring Web Services
• Client Elasticsearch
• Mise en œuvre basée sur Spring Integration 2.2.0
• Le JAR spring-integration-core + autant de jar que de technologies
supportées utilisées
• Configuration de Spring Integration
• Fichier de configuration XML avec espaces de nommage dédiés :
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-xml="http://www.springframework.org/schema/integration/xml"
• Annotations @MessageEndpoint, @Header, @Payload, @Gateway …
11
Mise en place de l’Architecture applicative
<!-- Fabrique de connexions JMS du broker de l’ESB -->
<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="IndexoEventCF">
<jee:environment>
java.naming.factory.initial=xxx
java.naming.provider.url=yyy
</jee:environment>
</jee:jndi-lookup>
<task:executor id="businessChangeTaskExecutor"
pool-size="10-40"/>
<task:executor id="errorTaskExecutor"/>
<!-- Unmarshaller JAXB 2 de la partie métier de la notification -->
<oxm:jaxb2-marshaller id="businessEventUnmarshaller"
contextPath="com.javaetmoi.indexo.model.event.business.v1"/> 12
Définition des beans d’Infrastructure
Accès à l’annuaire JNDI
distant de l’ESB
Pools de threads dédiés à la
gestion des erreurs et aux
traitements de chaque objet
métier à indexer
Implémentation avec Spring Intégration
Implémentation avec Spring Intégration
• Utilisation du pattern Channel Adapter
• Connecte un channel avec des systèmes ou des services de transports externes
• 2 types de Channel Addapter : Inbound ou Outbound
• Uni-directionnel
• Implémentation retenue dans Spring Integration :
– Adapteur JMS entrant de type Message Driven
<int-jms:message-driven-channel-adapter
destination="EventQueue"
channel="jmsEventChanel" />
<int:channel id="jmsEventChanel" />
13
Etape 1 : Lecture de la notification à partir de la file JMS
Nom de la file JMS
en entrée d’Index
Channel dans lequel
le GenericMessage
est déposé
Implémentation avec Spring Intégration
• Utilisation du pattern Message Filter
• Décide de faire passer ou non un message vers le output
channel
• Par défaut : un message filtré est ignoré
• Autre configuration possible : levée d’une exception
ou message routé dans un discard-channel
• Implémentation retenue dans Spring Integration :
– Filtre XML par expression XPath
<int-xml:xpath-filter
input-channel="jmsEvenChannel"
output-channel="indexoEventChannel"
discard-channel="unexpectedEventChannel">
<int-xml:xpath-expression expression=
"/Notification/Header/Type = 'BODC'"/>
</int-xml:xpath-filter> 14
Etape 2 : Filtrage à partir du cartouche technique
Notification de type
BODC dédiée à Indexo
Notifications
invalides routées
dans un channel
Implémentation avec Spring Intégration
• Patterns Publish-Subscribe, Content Enricher et
Channel Adapter
– Génération d’un log d’erreur et envoi d’un email en
simultanés
<publish-subscribe-channel id="unknownEventChannel"
task-executor="errorTaskExecutor"/>
<logging-channel-adapter channel="unknownEventChannel" level="ERROR"
expression=« 'Unknown message: ' + payload.failedMesssage.payload"/>
<chain input-channel="unknownEventChannel"/>
<int-mail:header-enricher>
<int-mail:subject value="Unknown message"/>
<int-mail:to value="support@javaetmoi.com"/>
</int-mail:header-enricher>
<int-mail:outbound-channel-adapter host="mailserver" port="1021"/>
</chain>
15
Etape 3 : Traitement des erreurs
Non Bloquant
Abonnés appelés
en parallèle
Ajoute les en-
têtes mail_subject
et mail_to
Implémentation avec Spring Intégration
• Pattern de transformation de messages
– Seule la partie métier est nécessaire à l’indexation
– Utilisation du unmarshaller XML JAXB 2 proposé par
Spring OXM
• Implémentation basée sur le support XML de Spring
Intégration
<chain input-channel="indexoEventChannel"
output-channel="businessEventChannel"/>
<int-xml:xpath-transformer
xpath-expression="/Notification/Body"
evaluation-type="NODE_RESULT" />
<int-xml:unmarshalling-transformer
unmarshaller="businessEventUnmarshaller"/>
</chain> 16
Etape 4 : Extraction puis unmarshalling de la partie métier
Implémentation avec Spring Intégration
• Utilisation du pattern Message Splitter
• Découpe un message en plusieurs messages.
• Permet de segmenter le traitement d’un payload « composite » avec possibilité de
regroupement
• Implémentation avec chaque sous-message traité en parallèle :
public class BusinessDomainEventSplitter {
List<BusinessDomainChange> split(BusinessDomainEvent event) {
return event.getChanges();
} }
<context:bean id="businessDomainEventSplitter"
class="com...BusinessDomainEventSplitter"/>
<splitter input-channel="businessEventChannel"
output-channel="businessChangeChannel"
ref="businessDomainEventSplitter"/>
<channel id="businessChangeChannel">
<dispatcher task-executor="businessChangeTaskExecutor"/>
</channel>
17
Etape 5 : Séparation en informations de mise à jour unitaire
Implémentation avec Spring Intégration
• Utilisation du pattern Message Router
• Décide dynamiquement vers quel(s) channel(s) un message doit être
envoyé
• La décision est généralement fonction des en-têtes ou du contenu
• Implémentation à l’aide d’une Spring Expression Language (SpEL) :
<recipient-list-router input-channel="businessChangeChannel">
<recipient channel="objetUpdateChannel"
selector-expression="payload.action.equals(UPDATE)"/>
<recipient channel="objetDeleteChannel"
selector-expression="payload.action.equals(DELETE)"/>
</recipient-list-router>
• Configuration simplifiée :
<router input-channel="businessChangeChannel"
expression="'object' + payload.action + 'channel'" />
18
Etape 6 : Routage en fonction de l’action
Implémentation avec Spring Intégration
• Utilisation une 2nde fois du pattern Message Router
• Exemple de configuration par annotations :
<context:component-scan
base-package="com.javaetmoi.indexo.endpoint"/>
@MessageEndpoint
public class ModificationObjetMetierRouter {
@Router(inputChannel="objetUpdateChannel")
public String route(BusinessDomainChange payload) {
return payload.getObjetTypeCode() +"UpdateChannel";
}
}
19
Etape 7 : Routage en fonction du type d’objet métier
Nom de l’OuputChannel dans le cas d’une mise à jour
d’un produit : « productUpdateChannel »
Auto-détection des beans Spring
par analyse de package java
Implémentation avec Spring Intégration
• Utilisation du pattern Gateway
• Masque l’API de messaging de Spring Integration
• Une Outbound Gateway fait appel à un système externe et renvoie la réponse dans
l’application (sous forme de Message)
• Une Inbound Gateway fait rentrer des messages dans l’application et attend la réponse
• Implémentation à l’aide du support Web Services de SI :
– Fait appel au WS SOAP Produx de consultation d’un produit
<int-ws:outbound-gateway
request-channel="productUpdateChannel"
reply-channel="productDtoChannel"
destination-provider="wsProductClient"
marshaller="productMarshaller"
unmarshaller="productUnmarshaller"/>
20
Etape 8 : Récupération des données Poduits à indexer
Marshalling
manuel via
JDOM :
l’identifiant du
produit est
utilisé comme
paramètre
d’appel du WS
Le produit retourné par le WS est unmarshallé dans un
ProductDto via JAXB2
Implémentation avec Spring Intégration
• Utilisation du pattern Service Activator
• Endpoint générique connectant un service métier au système de messagerie de SI
• L’opération d’un service est invoquée pour traiter le message reçu sur l’input-channel
• La réponse est encapsulée dans un message émis sur le output-channel ou le replyChannel
@Service("productProcessorService")
public class ProcessorServiceImpl
implements ProductProcessorService {
@Override
public ProductDocument process(
DtoProduct product) { … }
}
<service-activator input-channel="productDtoChannel"
output-channel="productDocumentChannel"
ref="productProcessorService" method="process"/>
21
Etape 9 : Construction du document Lucene à indexer
Transforme les
données
produits en un
document
indexable par
Elasticsearch
Implémentation avec Spring Intégration
• Nouvelle utilisation du pattern Service Activator
@Service("productIndexWriterService")
public class ProductIndexWriterImpl
implements ProductIndexWriter {
@Autowired private Client esClient;
public void write(ProductDocument item) {
IndexRequestBuilder req = esClient
.prepareIndex(« indexo","product", item.getId());
req.setSource(ESContentBuilder.buildContent(item));
esClient.index(req);
} }
<service-activator input-channel="productDtoChannel"
ref="productIndexWriterService" method="write"/>
22
Etape 10 : Ecriture du document Dans Elasticsearch
Conclusion
• Plaisant malgré une phase d’apprentissage non négligeable
• Jeu de lego à l’aide de nombreuses briques
• Utilisation sur étagère
• Couplage Lâche facilitant les tests et la réutilisabilité
• Service métier réutilisé dans les batchs d’indexation
• Facilite la mise en place de modèles d’échanges asynchrones
orientés messages au sein d’une application basée sur Spring
• Simple paramétrage des channels
• Séparation des préoccupations entre la logique métier et la
logique d’intégration
• Spring Intégration Fourni la plomberie et des extensions pour les
connectivités
23
Bilan de l’étude de cas
Conclusion
• Polling de channels passifs
– Cadencement des traitements
• Failover et load-balancing
– Répartition de la charge induite par le traitement des messages et mode
dégradé
• Bridge
– Connecte 2 channels
• Intercepteurs
– Positionnés globalement ou sur chaque channel, pattern wire-tap
• Gestion des transactions
– Propagation du contexte transactionnel
• Message Store
– Persistance JMS ou base de données
• API de Construction des messages
– API fluent de construction de messages et de leurs en-têtes 24
Pour aller plus loin (1/2)
• Site et Manuel de référence de Spring Intégration
• http://www.springsource.org/spring-integration
• 331 pages, concepts, description détaillée, exemples complets
• Site de référence dess EIPS :
http://www.enterpriseintegrationpatterns.com
• Livres sur Spring Intégration
• Just Spring Integration
• Spring Integration in action
• Pro Spring Integration
• Code source sur Github
• Spring Tool Suite (STS)
• Modélisation Graphique
Conclusion
25
Pour aller plus loin (2/2)

Workshop Spring - Session 5 - Spring Integration

  • 1.
    Workshop Spring -Session 5 Etudes de cas Spring Intégration Diffusé en novembre 2013 Réactualisé en janvier 2015
  • 2.
    Sommaire Introduction à SpringIntegration 3 Présentation de l’étude de cas 6 Implémentation avec Spring Integration 11 Conclusion 23 Workshop Spring Integration – Etude de Cas 2
  • 3.
    Introduction • Le messengingest une technique d’intégration entre applications – Souvent basé sur un Message Oriented Middleware (MoM) • Permet 3 formes de Découplage : • Spatial • Temporel • Logique • Certains partisans poussent son Utilisation Au sein même d’une même application • Composants échangeant des données par messages en mémoire • Applications orientées évènements • Adaptateurs permettant de se connecter à des systèmes externes 3 Communication par messages
  • 4.
    Introduction • Livre cataloguantles patterns de type messaging utilisés en entreprise pour architecturer le SI – Ecrit par Gregor Hohpe et Bobby Woolf • Standardisation de concepts MOM • Liste de Patterns et iconographie • Message • Contient des En-têtes et un Contenu (Payload) • Channel • Point à Point ou de type Publish / Subscribe • Envoi bloquant ou asynchrone • Endpoint • Connecte les Channels au code applicatif et aux systèmes externes 4 Enterprise Integration Patterns (EIP)
  • 5.
    Introduction • Implémentation desEnteprise integration patterns • Apache CAMEL en est une autre • Repose sur le framework Spring et de nombreux projets • Reste un simple Framewok • Offre de nombreux adapateurs : • JMS • JDBC, JPA, Mongo DB, REDIS • HTTP, TCP / UDP • Fichier, FTP, SFTP • RSS, ATOM • Mail, Twitter, XMPP, XML, Web services, RMI 5 Spring Intégration
  • 6.
    Présentation de l’étudede cas • Application de recherche et d’indexation o Basée sur le moteur Elasticsearch o Données métier issues de différents référentiels et Back Office • Indexation des données au fil de l’eau o Mise en œuvre au sein d’une architecture SOA o Exploitant l’infrastructure existante (ESB) 6 Application Indexo
  • 7.
    Notification asynchrone envoyéeà Indexo par JMS lors d’une création / modification / suppression d’un ou plusieurs Produits Consultation des données produits par appel d’un web service SOAP Construction puis écriture du document à indexer dans Elasticsearch 7 Présentation de l’étude de cas Communication entre applications Serveur Elasticsearch Indexo Module d’indexation fil de l’eau Produx Référentiel Produits ESB JMS / XML HTTP / SOAP TCP / JSON 1 1 2 2 3 3
  • 8.
    8 A format XML,une notification est composée de 2 parties : 1. En-tête technique : standardisé par le framework de notification de l’ESB 2. Partie métier : spécifique à l’application Indexo • Cartouche technique : <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Notification xmlns="http://v1.event.esb.javaetmoi.com"> <Header> <Label>Business Object Domain Changes</Label> <SentTime>2015-01-12T21:10:30+02:00</SentTime> <Version>1</Version> <MessageNumber>1456098922309</MessageNumber> <Origin>PRODUX</Origin> <Type>BODC</Type> </Header> <Body>Notification métier</Body> </Notification> Utilisé par l’ESB: • Filtrage • Routage JMS Contenu au format XML Présentation de l’étude de cas Notifications (1/2)
  • 9.
    • Partie Métier •Contient les informations relatives à la modification d'un ou plusieurs objets métiers • Spécifiée par une XSD (au même titre que le cartouche technique) 9 Présentation de l’étude de cas Notifications (2/2) Propriété Type Description action Enumération Action de création, de modification ou de suppression d'un objet métier actionDate Timestamp Date et heure à laquelle l'action a eu lieu businessId String Identifiant métier de l'objet mis à jour objectTypeCode String Contient le nom des objets métiers du dictionnaire d'entreprise
  • 10.
    10 1. Lecture dela notification à partir de la file JMS 2. Filtrage à partir du cartouche technique Permet d’écarter les notifications non destinées à Indexo 3. Traitement des erreurs Fichier de logs et envoi de mails 4. Extraction puis unmarshalling XML de la partie métier 5. Séparation en informations de mise à jour unitaire 6. Routage en fonction de l’action Le traitement des notifications de suppression est transverse à tous les objets métiers 7. Routage en fonction du type d’objet métier 8. Récupération des données à indexer Appel du ou des web services SOAP ou REST de consultation 9. Construction du document Lucene à indexer 10.Ecriture du document dans Elasticsearch Présentation de l’étude de cas Décomposition du traitement des notifications
  • 11.
    Implémentation avec SpringIntégration • Beans d’infrastructure du contexte applicatif Spring • Connection Fatory JMS, File JMS (lookup JNDI ou standalone) • Pools de threads (TaskExecutor) • Marshaller JAXB 2 (Spring OXM) • Clients Spring Web Services • Client Elasticsearch • Mise en œuvre basée sur Spring Integration 2.2.0 • Le JAR spring-integration-core + autant de jar que de technologies supportées utilisées • Configuration de Spring Integration • Fichier de configuration XML avec espaces de nommage dédiés : xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-xml="http://www.springframework.org/schema/integration/xml" • Annotations @MessageEndpoint, @Header, @Payload, @Gateway … 11 Mise en place de l’Architecture applicative
  • 12.
    <!-- Fabrique deconnexions JMS du broker de l’ESB --> <jee:jndi-lookup id="jmsConnectionFactory" jndi-name="IndexoEventCF"> <jee:environment> java.naming.factory.initial=xxx java.naming.provider.url=yyy </jee:environment> </jee:jndi-lookup> <task:executor id="businessChangeTaskExecutor" pool-size="10-40"/> <task:executor id="errorTaskExecutor"/> <!-- Unmarshaller JAXB 2 de la partie métier de la notification --> <oxm:jaxb2-marshaller id="businessEventUnmarshaller" contextPath="com.javaetmoi.indexo.model.event.business.v1"/> 12 Définition des beans d’Infrastructure Accès à l’annuaire JNDI distant de l’ESB Pools de threads dédiés à la gestion des erreurs et aux traitements de chaque objet métier à indexer Implémentation avec Spring Intégration
  • 13.
    Implémentation avec SpringIntégration • Utilisation du pattern Channel Adapter • Connecte un channel avec des systèmes ou des services de transports externes • 2 types de Channel Addapter : Inbound ou Outbound • Uni-directionnel • Implémentation retenue dans Spring Integration : – Adapteur JMS entrant de type Message Driven <int-jms:message-driven-channel-adapter destination="EventQueue" channel="jmsEventChanel" /> <int:channel id="jmsEventChanel" /> 13 Etape 1 : Lecture de la notification à partir de la file JMS Nom de la file JMS en entrée d’Index Channel dans lequel le GenericMessage est déposé
  • 14.
    Implémentation avec SpringIntégration • Utilisation du pattern Message Filter • Décide de faire passer ou non un message vers le output channel • Par défaut : un message filtré est ignoré • Autre configuration possible : levée d’une exception ou message routé dans un discard-channel • Implémentation retenue dans Spring Integration : – Filtre XML par expression XPath <int-xml:xpath-filter input-channel="jmsEvenChannel" output-channel="indexoEventChannel" discard-channel="unexpectedEventChannel"> <int-xml:xpath-expression expression= "/Notification/Header/Type = 'BODC'"/> </int-xml:xpath-filter> 14 Etape 2 : Filtrage à partir du cartouche technique Notification de type BODC dédiée à Indexo Notifications invalides routées dans un channel
  • 15.
    Implémentation avec SpringIntégration • Patterns Publish-Subscribe, Content Enricher et Channel Adapter – Génération d’un log d’erreur et envoi d’un email en simultanés <publish-subscribe-channel id="unknownEventChannel" task-executor="errorTaskExecutor"/> <logging-channel-adapter channel="unknownEventChannel" level="ERROR" expression=« 'Unknown message: ' + payload.failedMesssage.payload"/> <chain input-channel="unknownEventChannel"/> <int-mail:header-enricher> <int-mail:subject value="Unknown message"/> <int-mail:to value="support@javaetmoi.com"/> </int-mail:header-enricher> <int-mail:outbound-channel-adapter host="mailserver" port="1021"/> </chain> 15 Etape 3 : Traitement des erreurs Non Bloquant Abonnés appelés en parallèle Ajoute les en- têtes mail_subject et mail_to
  • 16.
    Implémentation avec SpringIntégration • Pattern de transformation de messages – Seule la partie métier est nécessaire à l’indexation – Utilisation du unmarshaller XML JAXB 2 proposé par Spring OXM • Implémentation basée sur le support XML de Spring Intégration <chain input-channel="indexoEventChannel" output-channel="businessEventChannel"/> <int-xml:xpath-transformer xpath-expression="/Notification/Body" evaluation-type="NODE_RESULT" /> <int-xml:unmarshalling-transformer unmarshaller="businessEventUnmarshaller"/> </chain> 16 Etape 4 : Extraction puis unmarshalling de la partie métier
  • 17.
    Implémentation avec SpringIntégration • Utilisation du pattern Message Splitter • Découpe un message en plusieurs messages. • Permet de segmenter le traitement d’un payload « composite » avec possibilité de regroupement • Implémentation avec chaque sous-message traité en parallèle : public class BusinessDomainEventSplitter { List<BusinessDomainChange> split(BusinessDomainEvent event) { return event.getChanges(); } } <context:bean id="businessDomainEventSplitter" class="com...BusinessDomainEventSplitter"/> <splitter input-channel="businessEventChannel" output-channel="businessChangeChannel" ref="businessDomainEventSplitter"/> <channel id="businessChangeChannel"> <dispatcher task-executor="businessChangeTaskExecutor"/> </channel> 17 Etape 5 : Séparation en informations de mise à jour unitaire
  • 18.
    Implémentation avec SpringIntégration • Utilisation du pattern Message Router • Décide dynamiquement vers quel(s) channel(s) un message doit être envoyé • La décision est généralement fonction des en-têtes ou du contenu • Implémentation à l’aide d’une Spring Expression Language (SpEL) : <recipient-list-router input-channel="businessChangeChannel"> <recipient channel="objetUpdateChannel" selector-expression="payload.action.equals(UPDATE)"/> <recipient channel="objetDeleteChannel" selector-expression="payload.action.equals(DELETE)"/> </recipient-list-router> • Configuration simplifiée : <router input-channel="businessChangeChannel" expression="'object' + payload.action + 'channel'" /> 18 Etape 6 : Routage en fonction de l’action
  • 19.
    Implémentation avec SpringIntégration • Utilisation une 2nde fois du pattern Message Router • Exemple de configuration par annotations : <context:component-scan base-package="com.javaetmoi.indexo.endpoint"/> @MessageEndpoint public class ModificationObjetMetierRouter { @Router(inputChannel="objetUpdateChannel") public String route(BusinessDomainChange payload) { return payload.getObjetTypeCode() +"UpdateChannel"; } } 19 Etape 7 : Routage en fonction du type d’objet métier Nom de l’OuputChannel dans le cas d’une mise à jour d’un produit : « productUpdateChannel » Auto-détection des beans Spring par analyse de package java
  • 20.
    Implémentation avec SpringIntégration • Utilisation du pattern Gateway • Masque l’API de messaging de Spring Integration • Une Outbound Gateway fait appel à un système externe et renvoie la réponse dans l’application (sous forme de Message) • Une Inbound Gateway fait rentrer des messages dans l’application et attend la réponse • Implémentation à l’aide du support Web Services de SI : – Fait appel au WS SOAP Produx de consultation d’un produit <int-ws:outbound-gateway request-channel="productUpdateChannel" reply-channel="productDtoChannel" destination-provider="wsProductClient" marshaller="productMarshaller" unmarshaller="productUnmarshaller"/> 20 Etape 8 : Récupération des données Poduits à indexer Marshalling manuel via JDOM : l’identifiant du produit est utilisé comme paramètre d’appel du WS Le produit retourné par le WS est unmarshallé dans un ProductDto via JAXB2
  • 21.
    Implémentation avec SpringIntégration • Utilisation du pattern Service Activator • Endpoint générique connectant un service métier au système de messagerie de SI • L’opération d’un service est invoquée pour traiter le message reçu sur l’input-channel • La réponse est encapsulée dans un message émis sur le output-channel ou le replyChannel @Service("productProcessorService") public class ProcessorServiceImpl implements ProductProcessorService { @Override public ProductDocument process( DtoProduct product) { … } } <service-activator input-channel="productDtoChannel" output-channel="productDocumentChannel" ref="productProcessorService" method="process"/> 21 Etape 9 : Construction du document Lucene à indexer Transforme les données produits en un document indexable par Elasticsearch
  • 22.
    Implémentation avec SpringIntégration • Nouvelle utilisation du pattern Service Activator @Service("productIndexWriterService") public class ProductIndexWriterImpl implements ProductIndexWriter { @Autowired private Client esClient; public void write(ProductDocument item) { IndexRequestBuilder req = esClient .prepareIndex(« indexo","product", item.getId()); req.setSource(ESContentBuilder.buildContent(item)); esClient.index(req); } } <service-activator input-channel="productDtoChannel" ref="productIndexWriterService" method="write"/> 22 Etape 10 : Ecriture du document Dans Elasticsearch
  • 23.
    Conclusion • Plaisant malgréune phase d’apprentissage non négligeable • Jeu de lego à l’aide de nombreuses briques • Utilisation sur étagère • Couplage Lâche facilitant les tests et la réutilisabilité • Service métier réutilisé dans les batchs d’indexation • Facilite la mise en place de modèles d’échanges asynchrones orientés messages au sein d’une application basée sur Spring • Simple paramétrage des channels • Séparation des préoccupations entre la logique métier et la logique d’intégration • Spring Intégration Fourni la plomberie et des extensions pour les connectivités 23 Bilan de l’étude de cas
  • 24.
    Conclusion • Polling dechannels passifs – Cadencement des traitements • Failover et load-balancing – Répartition de la charge induite par le traitement des messages et mode dégradé • Bridge – Connecte 2 channels • Intercepteurs – Positionnés globalement ou sur chaque channel, pattern wire-tap • Gestion des transactions – Propagation du contexte transactionnel • Message Store – Persistance JMS ou base de données • API de Construction des messages – API fluent de construction de messages et de leurs en-têtes 24 Pour aller plus loin (1/2)
  • 25.
    • Site etManuel de référence de Spring Intégration • http://www.springsource.org/spring-integration • 331 pages, concepts, description détaillée, exemples complets • Site de référence dess EIPS : http://www.enterpriseintegrationpatterns.com • Livres sur Spring Intégration • Just Spring Integration • Spring Integration in action • Pro Spring Integration • Code source sur Github • Spring Tool Suite (STS) • Modélisation Graphique Conclusion 25 Pour aller plus loin (2/2)

Notes de l'éditeur

  • #4 Découplage Spatial : les systèmes peuvent être distants ou non Temporel : réponse non immédiatement attendue, interaction asynchrone, unidirectionnel ou bidirectionnel Logique : l’émetteur n’a pas besoin de connaître le destinataire
  • #5 Publié en 2003 => les concepts sont vieux (années 70) Message : immuable, identifiant unique, Analogie avec les messages JMS et SOAP ou les requêtes HTTP En-têtes standardisées : durée de validité, adresse de retour, identifiant de corrélation Channel : le canal où transitent tous les messages. Endpoints : connecteurs, passif ou actifs (polling)
  • #6  La version RC1 de Spring Integration est sortie fin 2008 Autres prohets : Spring Security, Spring Batch, Spring WS API : <> conteneur / serveur, utilisable n’importe où : main(), web app, batch, swing … Assimilable à un mini ESB Extensions : projet Spring Integration Extension sur GitHub
  • #11 1. Lecture de la notification à partir de la file JMS : l’ESB a préalablement validé le cartouche technique
  • #12 Configuration possible à l’aide d’un DSL Groovy , Scala ou Java
  • #13 Drivers du provider JMS à inclure dans le classpath
  • #17 The result type expected from the XPath evaluation. This will be the type of the header value. The following values are allowed: BOOLEAN_RESULT, STRING_RESULT, NUMBER_RESULT, NODE_RESULT and NODE_LIST_RESULT. Defaults internally to XPathEvaluationType.STRING_RESULT if not set. Optional.
  • #18 Classe BusinessDomainEventSplitter : aucune d’adhérence avec Spring Intégration (annotations, interfaces), simple POJO
  • #21 Gateway : fait office de proxy
  • #22 Retour du service facultatif Service métier utilisé par les batchs d’indexation L’attribut method du service-activator est ici facultatif
  • #24 Un changement de paramétrage peut avoir des effets de bord qu’il faut avoir à l’esprit (ex : parallélisme entrainant la perte du contexte de sécurité et du contexte transactionnel)