Workshop Spring - Session 5 - Spring Integration

25
Workshop Spring - Session 5 Etudes de cas Spring Intégration Diffusé en novembre 2013 Réactualisé en janvier 2015

Transcript of Workshop Spring - Session 5 - Spring Integration

Page 1: Workshop Spring - Session 5 - Spring Integration

Workshop Spring - Session 5

Etudes de casSpring Intégration

Diffusé en novembre 2013Réactualisé en janvier 2015

Page 2: Workshop Spring - Session 5 - Spring Integration

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

Page 3: Workshop Spring - Session 5 - Spring Integration

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

Page 4: Workshop Spring - Session 5 - Spring Integration

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)

Page 5: Workshop Spring - Session 5 - Spring Integration

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

Page 6: Workshop Spring - Session 5 - Spring Integration

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

Page 7: Workshop Spring - Session 5 - Spring Integration

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 casCommunication entre applications

Serveur Elasticsearch

IndexoModule

d’indexation fil de l’eau

ProduxRéférentiel

Produits

ESB

JMS / XML

HTTP / SOAP

TCP / JSON

1

1

2

2

3

3

Page 8: Workshop Spring - Session 5 - Spring Integration

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’ESB2. 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 casNotifications (1/2)

Page 9: Workshop Spring - Session 5 - Spring Integration

• 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 casNotifications (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

Page 10: Workshop Spring - Session 5 - Spring Integration

10

1. Lecture de la notification à partir de la file JMS2. Filtrage à partir du cartouche technique

Permet d’écarter les notifications non destinées à Indexo

3. Traitement des erreursFichier de logs et envoi de mails

4. Extraction puis unmarshalling XML de la partie métier5. Séparation en informations de mise à jour unitaire6. 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étier8. Récupération des données à indexer

Appel du ou des web services SOAP ou REST de consultation

9. Construction du document Lucene à indexer10.Ecriture du document dans Elasticsearch

Présentation de l’étude de casDécomposition du traitement des notifications

Page 11: Workshop Spring - Session 5 - Spring Integration

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

Page 12: Workshop Spring - Session 5 - Spring Integration

<!-- 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

Page 13: Workshop Spring - Session 5 - Spring Integration

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-adapterdestination="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é

Page 14: Workshop Spring - Session 5 - Spring Integration

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

Page 15: Workshop Spring - Session 5 - Spring Integration

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="[email protected]"/>

</int-mail:header-enricher>

<int-mail:outbound-channel-adapter host="mailserver" port="1021"/>

</chain>15

Etape 3 : Traitement des erreurs

Non BloquantAbonnés appelés

en parallèle

Ajoute les en-têtes mail_subject

et mail_to

Page 16: Workshop Spring - Session 5 - Spring Integration

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-transformerxpath-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

Page 17: Workshop Spring - Session 5 - Spring Integration

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

Page 18: Workshop Spring - Session 5 - Spring Integration

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

Page 19: Workshop Spring - Session 5 - Spring Integration

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 Springpar analyse de package java

Page 20: Workshop Spring - Session 5 - Spring Integration

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

Page 21: Workshop Spring - Session 5 - Spring Integration

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 {@Overridepublic 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

Page 22: Workshop Spring - Session 5 - Spring Integration

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

Page 23: Workshop Spring - Session 5 - Spring Integration

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

Page 24: Workshop Spring - Session 5 - Spring Integration

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)

Page 25: Workshop Spring - Session 5 - Spring Integration

• 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)