Workshop Spring - Session 4 - Spring Batch

25
Workshop Spring - Session 4 Retour d’expérience Mise en œuvre de Spring Batch Diffusé en janvier 2012 Réactualisé en décembre 2014

Transcript of Workshop Spring - Session 4 - Spring Batch

Page 1: Workshop Spring -  Session 4 - Spring Batch

Workshop Spring - Session 4

Retour d’expérienceMise en œuvre de Spring Batch

Diffusé en janvier 2012Réactualisé en décembre 2014

Page 2: Workshop Spring -  Session 4 - Spring Batch

Sommaire

Introduction 3

Présentation de l’étude de cas 4

Objectifs 7

Mise en œuvre 8

Pour aller plus loin 23

Conclusion 24

2

Retour d’Expérience sur la mise en œuvre de Spring Batch

Page 3: Workshop Spring -  Session 4 - Spring Batch

Introduction

• Qu’est-ce qu’un Batch ?• Suite de traitements sur un ensemble de données

• sans intervention humaine

• Java et les batchs• Spring Batch

• Standardisation JSR-352 Batch Applications dans JEE 7– Implémentation de référence : https://java.net/projects/jbatch/

• Aucune alternative aussi aboutie

• Objectifs• Aperçu concret de sa Mise en œuvre

• Intégrer les fondamentaux

• Avoir une vue d’ensemble de Ses fonctionnalités

• L’utiliser demain

3

Workshop sur les batchs en java

Page 4: Workshop Spring -  Session 4 - Spring Batch

Présentation de l’étude de cas

4

Périmètre fonctionnel

• Commandes réalisées depuis une application Web

et stockées en base de données

• Tous les soirs, un traitement batch émet un fichiers

client et un fichier de facturation vers un Back

Office Mainframe

• Les commandes traitées sont marquées comme tel

Page 5: Workshop Spring -  Session 4 - Spring Batch

Présentation de l’étude de cas

• Projet métier• Retarder l’exécution de 2 batchs quotidiens

• Export de données au Mainframe réalisé à chaud

• Batchs iso-fonctionnels

• Recette complète par la MOA

• Opportunités• Montée de version de framework : Spring et Hibernate

• Migration d’un framework de batch maison à Spring Batch 2.1

• Déploiement automatisé des batchs

• Fiabiliser l’exécution des batchsGestion des erreurs et des codes retours

• Améliorer la gestion des logs

• Bénéficier de reporting5

Origine du projet de migration

Page 6: Workshop Spring -  Session 4 - Spring Batch

Présentation de l’étude de cas

1. Récupère les identifiants des commandes à exporter

2. Charge les commandes à partir de leurs identifiants

3. Itère sur la liste des commandes1. Génère les factures et identifie les clients

2. Construit les enregistrements CICS des factures et des clients

3. Incrémente les compteurs

4. Construit les enregistrements header et footer

5. Ecrit les enregistrements dans 2 fichiers temporaires

6. Met à jour en base de données un flag d’émission

7. Renomme les fichiers temporaires afin qu’ils soient pris en compte par le système de transfert de fichier

6

Batchs existants décomposés en 7 étapes

Page 7: Workshop Spring -  Session 4 - Spring Batch

Objectifs

• Migration technique• Mêmes données en entrée

• Mêmes fichiers en sortie

• Evolutions techniques

• Tests de non régressions– Tests de bout en bout basés sur :

• Un échantillonnage de données de production

• Des fichiers générés à partir du batch existant

• Des outils : H2, Maven et JUnit

• Tests selenium• Saisie et émission de commandes

• Exécutés automatiquement avant, pendant et après le batch

7

Des batchs iso-fonctionnels

Page 8: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

8

Décomposition des batchs en une seule étape

BaseMySqlavec

Commandes

Lecture Ecriture

Fichier de facturation

Fichier des clients

Traitement

Construction

Enregistrements

CICS

Une étape décomposée en 3 phases

Erre

ur

Alerte par mail

Page 9: Workshop Spring -  Session 4 - Spring Batch

Spring Batch

9

Vocable

sItemReader ItemProcessor ItemWriter

Chunk Tasklet

Step

Job

Base G@el

Page 10: Workshop Spring -  Session 4 - Spring Batch

Spring Batch

10

Diagramme de séquence de traitement d’un chunk

TaskletStep ItemReader ItemWriterItemProcessor

read

item

transform(items)

write(transformedItems)

transformedItems

Chaque chunks’exécute dans sa propre transaction

Les items sont lus un à un ou en bloc

La phase de traitement est optionnelle

Le lot de données à traiter peut être morcelé en chunk

Point de sauvegardeavant le commit

Page 11: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

11

Configuration d’un Job et d’un Step

<!-- Job Spring Batch chargé d'exécuter le batch JM076--><batch:job id="batchJM076Job" restartable="false">

<batch:step id="processCarOrderStep" parent="processOrderStep" />

</batch:job>

<!– Etape chargée d'émettre des commandes--><batch:step id="processOrderStep" abstract="true">

<batch:tasklet transaction-manager="transactionManager"><batch:chunk reader="orderReader"

processor="orderProcessor"writer="billingAndCustomerWriter"… />

</batch:tasklet>…

</batch:step>

Référence 3 beans Spring

Permet de mutualiser le step entre 2 batchs

Batch transactionnel

Page 12: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

12

Reader Hibernate

<!-- Reader Spring Batch chargé de récupérer les commandesà traiter depuis la base de données via Hibernate -->

<bean id="orderReader" class="org.sf.batch.item.database.HibernateCursorItemReader"p:sessionFactory-ref="sessionFactory" p:useStatelessSession="false">

<property name="queryString"value="FROM Order orderWHERE order.sentItemFlag is nullORDER BY id" />

</bean>

Initialement décomposé en un bean parent générique et un beanspécifique au batch JM076

Requête HQL de sélection des commandes à émettre

Session Hibernate nécessaire pour le Lazy-loading

Page 13: Workshop Spring -  Session 4 - Spring Batch

Spring Batch

13

Quelques implémentations de Reader disponibles

public interface ItemReader<T> {T read() throws Exception, UnexpectedInputException,

ParseException;}

Classes Propriétés

StoredProcedureItemReader Nom de la procédure stockée, paramètres, row mapper

JdbcPagingItemReader Taille d’une page, fournisseur de requêtes SQL pagninées, paramètres

FlatFileItemReader Encodage, ressource à lire, lignes d’en-tête,line mapper, séparateur

StaxEventItemReader Ressource XML à lire, élément racine, unmarshaller

JmsItemReader Jms template, file JMS à lire

Page 14: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

14

Déclaration et implémentation d’un Item Processor

<!-- Traite les commandes fin d'émettre les factures --><bean id="orderProcessor"

class="com.javaetmoi.batch.jm076.CarOrderProcessor"scope="step"p:billingCounter-ref="billingCounter"p:customerCounter-ref=« customerCounter" />

public class CarOrderProcessor implementsItemProcessor<Order, ProcessResultHolder> {

public ProcessResultHolder process(Order order) throws BatchException {

// … Création des factures et identification des clientsreturn processResultHolder;} …

}

Page 15: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

15

Configuration des writers (1/2)

<!-- Writer composite Spring batch chargé de générer 2 fichiers pour le back office et de mettre à jour la base MySql-->

<bean id="billingAndCustomerWriter" class="org.sf.batch.item.support.CompositeItemWriter">

<property name="delegates"><list>

<!-- Fichier des factures --><ref bean=« billingWriter" /><!-- Fichier des clients --><ref bean="customerWriter" /><!– Mis à jour indicateur de transmission dans la table

des commandes --><ref bean="orderFlagWriter" />

</list></property>

</bean>

Writers délégués appelés séquentiellement dans l’ordre déclaré

Page 16: Workshop Spring -  Session 4 - Spring Batch

Spring Batch

16

Quelques implémentations de writers disponibles

public interface ListItemWriter<T> {void write(List<? extends T> items) throws Exception;

}

Classes Propriétés

HibernateItemWriter Template Hibernate

JdbcBatchItemWriter Requête SQL, callback method chargé de setter les paramètres

FlatFileItemWriter Encodage, fichier plat, séparateur de ligne, callbacks d’en-ête et de fin de fichier

StaxEventItemWriter Fichier XML, élément racine, marshaller, callbacks d’en-ête et de fin de fichier

SimpleMailMessageItemWriter Implémentation de MailSenders

Page 17: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

17

Configuration des writers (2/2)

<!-- Writer Spring batch chargé d'écrire le fichier des factures --><bean id="billingWriter"

class="com.javaetmoi.core.batch.writer.ExtendedFlatFileItemWriter"p:lineSeparator="" p:encoding="ISO-8859-1" p:shouldDeleteIfError="true" /><property name="lineAggregator"><bean class="com.javaetmoi…common.item.BillingLineAggregator"/>

</property><property name="resource" value="file:${batch.data.out.path}

/billing-jm076.dat"/><property name="footerCallback" ref="billingFooterCallback" />

</bean>

<!-- Met à jour le flag des factures envoyées au back office --><bean id="billingFlagWriter"

class="com.javaetmoi…common.item.GenericFlagWriter"p:processOrderToExport-ref="processOrderToExport" />

<bean id=" processOrderToExport " class="fr…batch.commun.services.ProcessOrdertoExport"p:orderDao-ref="orderDao" />

Page 18: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

• Besoin• Une seule et unique transaction pour tout le batch

• Les erreurs fonctionnelles ne doivent pas faire échouer le batch

• Fichiers générés : tout ou rien

• Comportement proposé par Spring Batch• Une transaction par chunk

• Configuration des exceptions n’annulant pas la transaction

• Les writers sur filesystem peuvent participer au contexte transactionnel

• Solutions• Intervalle de commit réglé à l’infini pour avoir un unique chunk

• Les exceptions de type BatchException ne provoquent pas de rollback

• Les writers des factues et des clients sont enregistrés au Stream

• Restauration en mémoire des compteurs assurée par un listener18

Gestion des transactions (1/2)

Page 19: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

19

Gestion des transactions (2/2)

<batch:tasklet transaction-manager="transactionManager" …><batch:chunk … commit-interval="2147483647" …><batch:streams>

<batch:stream ref="billingWriter" /><batch:stream ref="customerWriter" />

</batch:streams>…</batch:chunk><batch:no-rollback-exception-classes>

<batch:includeclass="com…common.exception.BatchException" />

</batch:no-rollback-exception-classes>…<batch:listeners>

<batch:listener ref="orderProcessListener" />…

</batch:listeners></batch:tasklet>

Page 20: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

• Besoin• Erreur de traitement d’une commande non bloquante

• Enregistrée dans les pistes d’audit

• Être alerté par mail

• Solutions• Les erreurs fonctionnelles signalées par des exceptions spécifiques

ne doivent pas faire échouer le traitement– Non vérifiées, les BatchException sont levées lors de la génération des

enregistrements

– Paramétrable dans le chunk : skip-limit et skippable-exception-classes

• Traces générées lorsqu’une exception est levée– Méthode onProcessError() de l’interface ItemProcessListener

• Envoi de mail sur génération d’une trace de niveau >= à warning– Implémentation avec Logback : SMTPAppender, OnEventEvaluator,

HTMLLayout

20

Gestion des erreurs (1/2)

Page 21: Workshop Spring -  Session 4 - Spring Batch

21

<batch:tasklet …><batch:chunk … skip-limit="2147483647" …>

…<batch:skippable-exception-classes>

<batch:includeclass="com…common.exception.BatchException" />

</batch:skippable-exception-classes></batch:chunk>

…</batch:tasklet>

public void onProcessError(Order order, Exception ex) {LOGGER.error("Une erreur est survenue lors du

traitement de la commande n°{}: {}", order.getNumber(), ex.getMessage());

}

Mise en œuvre Gestion des erreurs (2/2)

Page 22: Workshop Spring -  Session 4 - Spring Batch

Mise en œuvre

• Exécution possible en ligne de commande ou par programmation

• Ordonnanceur : Quartz, $U, CRON, planificateur de tâches Windows …

• Tests Junit et TestNG

• JMX, Interface graphique, ServIces web …

• Contexte projet : • Ordonnanceur Dollar Universe

• Packagés dans un JAR– Extrait du MANIFEST.MF de myapp-batch-2.0.1.jar :

– Main-Class: org.springframework.batch.core.launch.support.CommandLineJobRunnerClass-Path: ./ojdbc-10.2.0.3-jdk14.jar ./spring-batch-core-3.0.2.RELEASE.jar …

• En Ligne de commande – java -jar myapp-batch-2.0.1.jar \

com/javaetmoi/myapp/batch/applicationContext-batch-jm076.xml

batchJM076Job

22

Exécution du batch

Page 23: Workshop Spring -  Session 4 - Spring Batch

Pour aller plus loin

• Console d’administration et de suivi• Spring batch Admin

• Reprise sur erreur• Réexécution d’une instance de job

• Persistance du contexte

• Exécution dynamique• Enchaînement conditionnels d’étapes

• Paramètres d’entrée évalués dynamiquement

• Scalabilité et Parallélisme• Exécution de chunk et de step en parallèle

• Sur la même machine ou de manière distribuée

• Partionnement des données23

Fonctionnalités non présentées

Page 24: Workshop Spring -  Session 4 - Spring Batch

Conclusion

• Code technique supprimé

• Réutilisabilité du code métier• Création des enregistrements CICS à partir des commandes

• Testabilité• Tests unitaires existants conservés

• Tests de bout en bout ajoutés

• Design Amélioré• Découpage mieux structuré

• Peut-être encore meilleur si développé from scrath

• Désenttement de l’ancien framework de batchs maison• Buggué au niveau du code retour en cas d’erreur

• Exemple d’utilisation réutilisé pour 2 autres batchs

• Job Repository persistant non exploité

• Effort nécessaire pour monter en compétences

• La connaissance du framework Spring est un pré-requis24

Retours sur la migration vers Spring Batch

Page 25: Workshop Spring -  Session 4 - Spring Batch

Conclusion

25

Spring Batch en 3 mots

Robuste

• Fiable

• Gestion des erreurs

• Reprise

• Tests unitaires

• Performant

• Standardisé

Productif

• Cadre de développement

• Maintenabilité

• Code technique fourni

Extensible

• Ouvert

• Spring Batch Admin

• SpringIntégration