Framework Spring-Batch 2.x : Une démo avancée (Part 1/2)

spring-mini-logo.png

Le (célèbre) framework Spring-Batch, dans sa nouvelle version (actuellement v 2.1.8), apporte d'importantes nouveautés.

Qu'est-ce que ce (nouveau) framework?
A quoi peut-il servir?

Nous répondons à ces questions avec une démo de lecture des données depuis une base.
Ces données sont transformées puis consignées dans un fichier.
Tout cela réalisé avec peu de code.


PRE-REQUIS: Connaître impérativement spring.

Lorsque je cherche à développer une application web en java, une panoplie de frameworks (Spring MVC, JSF, Struts2, GWT, ...) open-source existe.
Lorsque je cherche des solutions de persistance, là aussi des frameworks robustes sont présents (JPA, Hibernate, EJB, IBatis,.).
Mais, si le besoin consiste à développer un batch, alors là ... il faut bien chercher un framework.
A part les solutions "maisons", on ne trouve pas de standard bien conçu!
C'est pourquoi, établir un standard de développement pour les applications java batch, qui favorise les meilleures pratiques, devient une nécessité.
L'idéal serait d'utiliser des POJO faciles à tester, afin de construire pour les batchs un standard à l'image de celui des applications Web/JEE.
Spring-batch est le framework qui comble ce manque.

Q- Une application batch, c'est quoi?
R- En général, c'est une application java standard qui traite ou échange un volume important de données sans aucune intervention humaine.
Exemples:

  1. Mise à jour régulière (quotidienne) des référentiels,
  2. Intégration de flux fréquents dans le SI,
  3. Export/Import de fichiers XML depuis/vers base, jms,...

Q- Quelles sont les différences entre application batch et application web?
R- Voici une synthèse des différences:

Diff_webapp_batchApp.PNG

Donc, ce qui est spécifique au batch:

  • Une volumétrie importante de données échangées ;
  • Une exigence de robustesse, le batch ne doit, en aucun cas, s'interrompre brutalement car il n'y a pas d'interaction utilisateur,
  • Exigence de performance pour réduire l'indisponibilité du SI ;
  • Exigence de traçabilité (logs complets, notification par mail,..) ;
  • Une gestion appropriée des erreurs. Identifier les erreurs pour lesquelles le batch ne doit pas être interrompu ;
  • Une gestion optimale de la consommation des ressources (mémoire, disque, ...). Une consommation excessive perturbe le SI,
  • Opérations et traitements planifiés régulièrement ;
  • Possibilité de reprise sur erreur ;
  • Gestion des transactions (rollback ou commit).

Q- Le framework Spring-Batch, qu'est-ce que c'est ?

R- Beaucoup d'applications d'entreprise comportent des opérations planifiées traitant un volume important de données (centaines de milliers ou millions).
Typiquement, elles importent les données d'une base source, les transforment après
formatage et/ou validation puis les insèrent dans une base cible.
Tout cela est effectué éventuellement de manière transactionnelle.
Spring-Batch est un framework conçu pour construire ce type de batch.
L'architecture de spring-batch favorise le principe de "separation of concerns".
Le code infrastructure est fourni pour pratiquement tous les cas.

Q- Quelle est l'architecture de Spring-Batch?
R- L'architecture de spring-batch est constituée de trois couches comme l'illustre la figure suivante.

Archi-SpringBATCH.PNG

Explications : le tiers Application regroupe le code métier du batch.
Le tiers batch-core contient toutes les classes utiles à la gestion des jobs.
Enfin, ces deux tiers s'appuient sur le dernier contenant les services, les readers et writers.

Q- Spring-Batch est-il un framework de planification des tâches (scheduler)?

R- Non. Spring-Batch permet d'utiliser les solutions open source de planification (scheduler) tel Quartz.
Il est nécessaire d'utiliser un scheduler pour lancer un batch à base de spring-batch.

Q- Comment intégrer Spring-Batch dans mon projet?
R- Ajouter les jars au projet et c'est tout!

Q- Quels sont les avantages à utiliser Spring Batch?

R- Pour répondre vite, ce sont les mêmes bénéfices que ceux des applications web/JEE conçues avec Spring.

Autrement dit, Spring-Batch offre un nombre de services réutilisables incluant la gestion :

  • de la traçabilité
  • des transactions,
  • de la relance des jobs,
  • des ressources,
  • de la concurrence des jobs,
  • de la parallélisation des traitements,
  • des planifications,
  • de l’exécution partielle des jobs,
  • de la scalabilité.

Q- Quel est le bénéfice le plus important de Spring-Batch?

R- Le bénéfice le plus important, à mes yeux, est que le développeur se concentre uniquement sur le code métier.
Et, il laisse à Spring-Batch la partie code de tuyauterie (code d'infrastructure).
Ainsi, il y a moins de recette pour le code métier.
Un autre bénéfice important est l'aisance technique pour configurer l'ensemble des tâches (jobs) avec les rapports de suivi fournis par spring.

Q- Quel est le scénario typique que couvre Spring Batch?

R- Le scénario typique est :
Lire des données depuis une source (base, jms,..), les traiter en incluant la validation et le formatage, les transformer puis enfin les enregistrer dans une cible (base, jms,..).

La démo présentée plus loin reprend ce scénario.

Q- Y a t-il un lien avec Spring Core?

R- Spring-Batch repose sur Spring Core.

Q- Comment Spring-Batch traite-t-il efficacement une volumétrie importante ?

R- Prenons le scénario typique suivant :
Lire des données à partir d'un fichier et les écrire dans une base de données.
Une démarche simple serait de charger l'ensemble des données du fichier en mémoire (sous forme d'arbre d'objets java) puis d'itérer sur cette liste pour
écrire les données traitées dans la base cible.
Or, cette approche est loin d'être appropriée pour les fichiers de plusieurs centaines de mégaoctets.
En effet, charger une volumétrie importante en mémoire est une mauvaise pratique et elle peut conduire à des Out Of Memory.

Spring-Batch propose une approche efficace nommée "chunk processing".
Il récupère un nombre déterminé des données sources (en streaming), les traite puis les écrit dans la base cible.
Cette opération est répétée jusqu'à l'épuisement des données sources.
springBatch_chunkProcessing.png

Avant d'aborder la démo, voici une description rapide des notions essentielles de Spring-Batch.
Ces notions permettent de progresser rapidement dans la prise en main de Spring-Batch.
Job: Simplement un conteneur (abstrait) regroupant plusieurs steps (étapes) du batch,
Step: Unité de tâche ou une étape d'un job du batch,
JobInstance: L'instance concrète d'un Job (penser à la relation instance/classe en java)
JobLauncher: Interface pour contrôler les jobs (lancer, arrêter, relancer,..),
JobRepository: Interface responsable de la persistance des jobs dans la base (ou en mémoire). Il contient les opérations CRUD pour gérer les jobs.
__
ItemReader__: Interface permettant de lire les données en entrée (depuis un fichier, une base, ...).

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

ItemWriter: Interface permettant d'écrire les données en sortie.

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

Tasklet: Interface permettant d'effectuer une tâche unitaire du batch avec ou sans reader/writer.
Chunk: Interface permettant de faire un traitement par lot (commit-interval définit la taille du lot),
ItemProcessor: Interface permettant d'effectuer les transformations avant de transférer les données au writer.

public interface ItemProcessor<T, V> {
V process(T item) throws Exception;
}

Les cinq premières notions font partie de "Core de Spring-Batch"
Ces cinq dernières notions font partie du tiers infrastructure de spring-batch.
Les3tiers_springBatch.PNG

Passons à la démo.

      LES PHASES DE LA DEMO

PHASE 0: Préparer l'environnement

0.1- Créer les tables dans MYSQL pour persister les infos sur les jobs du batch,
Les scripts sql de création de ces tables se trouvent dans spring-batch-infrastructure-2.1.7.RELEASE.jar
Créer aussi une table MYSQL nommée "CLIENTS" ayant les colonnes id, nom, prénom, adresse puis insérer quelques lignes.

0.2- Créer un projet maven,

            mvn archetype:generate -Dfilter=org.apache:quickstart

0.3- Configurer le pom.xml
Compléter le pom.xml avec les dépendances suivantes:

 <dependency>
   <groupId>org.springframework.batch</groupId>
   <artifactId>spring-batch-core</artifactId>
   <version>${spring.batch.version}</version>
 </dependency>
 <dependency>
 	<groupId>org.springframework.batch</groupId>
 	<artifactId>spring-batch-infrastructure</artifactId>
 	<version>${spring.batch.version}</version>
 </dependency>

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-jdbc</artifactId>
 <version>${spring.framework.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${spring.framework.version}</version>
</dependency>
 <dependency>
 <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring.framework.version}</version>
 </dependency>
 <dependency>
   <groupId>commons-dbcp</groupId>
   <artifactId>commons-dbcp</artifactId>
   <version>1.2.2</version>
</dependency>
<dependency>
 <groupId>commons-io</groupId>
 <artifactId>commons-io</artifactId>
 <version>1.4</version>
</dependency>
<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib-nodep</artifactId>
  <version>2.2</version>
 </dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.17</version>
</dependency>

Penser à définir les versions pour les artifacts spring-batch et spring.

0.5- Configurer le projet pour Eclipse
Lancer la commande dos: mvn eclipse:eclipse

0.6 - Importer le projet dans eclipse.

PHASE 1: Configurer Spring

La suite dans la partie 2 de ce billet ici.

Un commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.