Découvrez les forks de Spring Petclinic

L’application démo Spring Petclinic a été conçue pour montrer comment le framework Spring peut être utilisé pour développer une application web secondée par une base de données relationnelle. En somme, rien de révolutionnaire. Mais c’est ce qui fait tout son intérêt : présenter une architecture logicielle respectant l’état de l’art d’une application conçue avec Spring.

Avec plus de 2000 forks sur GitHub, la communauté a créé de nombreux forks de Spring Petclinic : Angular, React, REST, Spring Cloud … Afin de fédérer cet engouement, l’organisation GitHub Spring Petclinic a été créé sur GitHub en novembre 2016. La version de référence de Spring Petclinic reste sur https://github.com/spring-projects/spring-petclinic. Les branches et les forks ont basculé sur https://github.com/spring-petclinic.

Ce billet a pour objectif de vous présenter cette récente initiative puis de vous présenter les différents forks d’ores et déjà disponible dans l’organisation Spring Petclinic. Mais avant cela, remontons le temps.

Les origines

D’après une vieille documentation encore en ligne, Spring Petclinic a été initialement développé par Ken Krebs en 2003. A cette époque, la version 1.0 de Spring Framework n’était pas encore releasée (il a fallu attendre mars 2004). La Javadoc @author démontre que le co-fondateur du framework Spring, Juergen Hoeller en personne, a activement contribué à Petclinic.
Les années passèrent. L’application bénéficia des montées de version du framework Spring.
En 2007, Spring Petclinic était distribué avec Spring Framework 2.5 en tant qu’application d’exemple.
Ensuite, pendant 5 ans, l’application n’a plus évolué.

En 2013, Michael Isvy, ex-responsable formation Spring chez Pivotal, Keith Donald et Costin Leau ont fait revivre l’application en la déplaçant sur GitHub et en la migrant vers Spring 3.

A partir de juin 2015, j’ai eu l’honneur de reprendre la coordination technique du projet. Mes contributions principales auront été de proposer une configuration full Java, une version Spring Boot et de migrer l’IHM vers le thème Bootstrap 3 de Pivotal.

Le mois dernier, j’ai passé la main à Dave Syer, qui n’est autre que le papa de Spring Batch, Spring Cloud et de Spring Boot.

L’application Petclinic de référence

Reprenant les rennes, Dave Syer a tout de suite mis sa griffe sur le repo spring-projects/spring-petclinic :

  1. La version Spring Boot est désormais celle de référence. La version Spring Framework est « archivée » dans un fork présenté plus loin.
  2. Java 8 minimum
  3. La couche présentation en JSP est réécrite en Thymeleaf. Le WAR auto-exécutable devient un JAR.
  4. L’architecture applicative est modernisée. La Pull Request #200 « Modularize and migrate to aggregate-oriented domain » présente les changements. La couche service est retirée. Les Controllers dialoguent directement directement avec la couche Repository qui assure désormais la gestion des transactions. L’organisation des packages passe d’un découpage technique (model, repository, service et web) à un découpage métier (owner, vet, visit).

Ce dernier changement d’architecture est le fait le plus marquant. Quelle rupture avec 15 ans de découpage Contrôleur -> Service -> DAO. Afin d’éviter des dépendances circulaires entre packages Java, la conception objet est en quelque sorte dénormalisée. La classe Visit ne référence plus la classe Pet, mais seulement son identifiant.

Maintenue par l’équipe Pivotal, cette version « canonique » de Spring Petclinic est celle à partir desquels les forks pourront être créés. Notons enfin que c’est la version Spring Boot qui est mise en avant. Cela implique qu’une nouvelle application Spring doit donc partir dans la majorité des cas sur du Spring Boot.

Spring Framework Petclinic

L’application spring-petclinic/spring-framework-petclinic  a pour objectif de maintenir une version de Spring Petclinic sans Spring Boot, à l’ancienne, avec de la configuration Spring, de bonnes vielles pages JSP et une architecture 3-tiers.

Comparée à son aînée, cette version présente de nombreux points d’intérêts :

  1. La configuration Spring en XML (branche master) ou en full Java (branch javaconfig) de l’ensemble des couches d’une application web : présentation (Spring MVC, ressources statiques, dépendances JavaScript récupérées avec webjar), service (cache et transaction) et persistance.
  2. 3 implémentations de la couche de persistance : Spring JDBC, Hibernate et Spring Data JPA. Le choix se fait au démarrage de l’application web par l’usage d’un profile Spring.
  3. Des templates de pages et des composants graphiques avec JSP.
  4. L’usage de l’AOP avec l’aspect CallMonitoringAspect
  5. Un support de PostreSQL en plus de MySQL et HSQLDB.

Le fichier README.MD donne les points d’entrée vers les fichiers  de configurer et les classes Java les plus intéressantes.

Spring Petclinic AngularJS

Le fork spring-petclinic/spring-petclinic-angular1 a été créé à partir de la branche angular de l’application de référence, juste avant que celle-ci ne soit supprimée.
Liu Dapeng, Michael Isvy et moi-même en sont les principaux contributeurs.

L’intérêt principal de ce fork est de disposer d’un front-end full JavaScript. Le code Angular JS 1.5 dialogue avec le backend à l’aide d’une API REST propulsée par Spring MVC.
L’intérêt secondaire est de prouver que les mondes JavaScript et Java peuvent parfaitement cohabiter. Le téléchargement et l’exécution des outils front-end gulp, bower, npm et node sont pilotés par Maven à l’aide du frontend-maven-plugin.

L’application est décomposée en 2 modules Maven, un client front-end et une partie serveur Spring Boot :

  1. spring-petclinic-client : ressources statiques (fichiers JavaScript Angular, images, fonts, css) packagées sous forme d’un webjar
  2. spring-petclinic-server : API REST de Spring Petclinic et la page index.html (template Thymeleaf) permettant de référencer les ressources statiques du webjar

Côté serveur, afin d’exposer une API REST au front-end Angular, les contrôleurs Spring MVC ont été convertis en @RestController, renommés pour les besoins de l’API REST et simplifiés car une partie de la logique est désormais traitée dans le navigateur (ex : OwnerResource.java).

La partie front n’a rien à voir avec l’originale en JSP / Java. Elle bascule complètement dans le monde JavaScript (à l’exception d’un peu de Maven).
Le spring-petclinic-client/pom.xml est configuré pour installer Node JS et NPM, récupérer les librairies tierces JS avec bower (cf. bower.json) puis lancer la phase de build avec Gulp (cf. gulpfile.js). Le répertoire target/dist construit par Gulp et les librairies JS sont enfin packagés par Maven sous forme de webjar. A noter que Gulp est configuré pour générer des CSS à partir des fichiers LESS de Petclinic et à minifier JS et CSS.
Le code AngularJS est centralisé dans le répertoire spring-petclinic-client/src/scripts/. L’application Angular est bootstrapée dans le fichier app.js. Le module externe ui-router est chargé de la navigation entre vues. L’organisation de chaque vue se fait sur le même modèle. Voici en exemple celle listant les vétérinaires :

  1. vet-list.component.js : déclaration du composant vetList, du template vet-list.template.html et du contrôleur VetListController
  2. vet-list.controller.js : définition du contrôleur VetListController chargé de faire un appel REST pour récupérer l’objet JSON représentant la liste des vétérinaires.
  3. vet-list.js : configuration ui-router faisant le lien entre l’URL /vets et le template vet-list
  4. vet-list.template.js: template HTML comportant des directives Angular

Spring Petclinic AngularJS montre également l’usage des DevTools. Introduits dans Spring Boot 1.3, ils peuvent remplacer l’usage d’outils comme JRebel ou Spring Loaded.
Le module spring-boot-devtools a été configuré de manière à ce que :

  • la recompilation d’une classe Java déclenche le rechargement du contexte applicatif Spring (qui dure à peine 2 secondes sur mon macbook)
  • une modification de ressources statiques déclenche un rafraichissement de la page dans le navigateur (le plugin LiveReload doit préalablement être installé)

Cette configuration n’est active que pendant la phase de développement. Elle est localisée dans le fichier application-dev.properties qui n’est chargé par Spring Boot que lorsque le profile Spring dev est actif. Dans votre IDE, ajouter l’option ci-dessous au démarrage de la JVM : -Dspring.profiles.active=dev

Spring Petclinic ReactJS

Le projet spring-petclinic/spring-petclinic-reactjs est le 2nd portage de l’application Spring Petclinic vers un front-end full JavaScript de type SPA (Single Page Application), en l’occurrence basé ici sur ReactJS (un framework MVC JavaScript développé par Facebook) et TypeScript (un sur-ensemble de ES6 développé par Microsoft).
Ce fork a été développé par Nils Hartmann, co-auteur d’un livre en allemand sur React et pro Spring Boot. Nils est parti de la version Spring Boot de Spring Petclinic. Pour designer l’API REST, il a récupéré certaines classes de la version AngularJS.

Comparé au fork AngularJS, front-end et backend disposent de leur propre serveur : l’un tournant sur Node.JS et l’autre sous Spring Boot.

La partie front-end est localisée dans le sous-répertoire client. Outre le code TypeScript (TS) et les ressources statiques, on retrouve la configuration d’un certain nombres d’outils JavaScript :

  • NPM tire les dépendances
  • Webpack permet de modulariser le code JavaScript
  • Pendant le développement, Babel transpile à chaud le code TS en JS
  • TSlint est utilisé pour vérifier la qualité du code TS
  • Téléchargement de définitions TS avec Typings

Chaque page de l’application web a été décomposée en composants et sous-composants React. A titre d’exemple, la page OwnersPage.tsx affichant le détail d’un propriétaire est découpée en 2 composants : OwnerInformation.tsx et PetsTable.tsx. La majeure partie du code applicatif se retrouve ainsi dans le répertoire client/src/components dédié aux composants.

La partie serveur se rapproche de celle d’AngularJS. Seule différence majeure : les données envoyées par le client sont validées. Se référer aux classes InvalidRequestException, ApiExceptionHandler, ErrorResource et FieldErrorResource. Bien conçue, cette couche de validation pourra être reportée sur la version AngularJS (cf. issue 7).

Spring Petclinic Microservices

Fondée par Maciej Szarliński, la version microservices de Spring Petclinic est mon coup de cœur du moment : spring-petclinic/spring-petclinic-microservices. Un grand nombre de modules de la stack Spring Cloud y sont mis en œuvre.

Ce fork de la version AngularJS de Spring Petclinic a été décomposée en 3 micro-services fonctionnels : customers, vets et visits. Autonomes, ces micro-services ne communiquent pas ensemble. Au démarrage, ils vont chercher leur configuration auprès du serveur de config (module spring-petclinic-config-server). Par défaut, le serveur de config récupère la configuration depuis le repo GitHub spring-petclinic-microservices-config. Il est possible d’utiliser un repo Git local : -Dspring.profiles.active=local -DGIT_REPO=/projects/spring-petclinic-microservices-config

Les 3 micro-services vont s’enregistrer auprès de l’annuaire de Service (module spring-petclinic-discovery-server) basé sur Eureka. Ils peuvent ainsi être accédés à partir de leur nom de service (ex : http://customers-service/owners/{ownerId}). Leur nom est paramétré dans le fichier bootstrap.yml, au côté de l’URL du serveur de config.

Le front-end Angular n’attaque pas directement les 3 micro-services. Il passe par une API Gateway dont le mécanisme de routage est assuré par Zuul (module spring-petclinic-api-gateway). Cette gateway n’est pas réduite à un simple passe-plat. Elle s’occupe de :

  1. Agréger les réponses renvoyées par plusieurs micro-services avant de les retourner au client (se référer à la classe ApiGatewayController)
  2. Load-balancer les requêtes entre plusieurs instances du même micro-services (annotation @LoadBalanced dans la classe ApiGatewayApplication).

Afin de pouvoir suivre les requêtes HTTP entre plusieurs microservices, un mécanisme de traces distribuées a été mis en œuvre avec Spring Cloud Sleuth. L’interface graphique du serveur Zipkin permet de les consulter.

Enfin, avec pour objectif de simplifier le démarrage de l’ensemble de ces applications (3 microservices + 4 composants d’infra), un fichier docker-compose.yml sera bientôt mis à disposition.

Tableau de synthèse

Le tableau ci-dessous dresse une liste des différentes versions de Spring Petclinic présentant à mes yeux un intérêt majeur :

Appellation Description
Spring Petclinic Version de référence de Spring Petclinic.
Implémentée avec Spring Boot et Thymeleaf.
Spring Framework Petclinic Configuration XML et Java de Spring Framework.
Front-end implémenté en JSP.
3 technologies de persistance : JDBC, JPA et Spring Data JPA.
Spring Petclinic AngularJS Front-end Angular 1 embarqué dans un webjar.
Usage de DevTools.
Spring Petclinic ReactJS Front-end ReactJS délivré par un serveur NodeJS et attaquant l’API REST du back-end implémenté en Spring Boot.
Spring Petclinic Microservices Version distribuée de Spring Petclinic implémentée à l’aide de Spring Cloud : serveur Spring Config, annuaire de services avec Eureka, gestion des logs avec Zipkin et Sleuth, API Gateway avec Zuul, Docker compose …

Conclusion

Dans cet article, j’ai commencé par retracer l’historique de l’application de référence Spring Petclinic qui a fêté son 13ième anniversaire et qui comptabilise plus de 2000 forks. Parmi ces forks, une poignée a intégré la nouvelle organisation Spring Petclinic. On y retrouve des versions front-end basées sur AngularJS et ReactJS, une version distribuée avec des micro-services et du Spring Cloud, une version plus legacy n’utilisant pas Spring Boot mais de la configuration XML ou Java (au choix).

L’organisation Spring Petclinic demande à s’élargir, soit en proposant un nouveau fork (ex : sur Angular 2) soit en contribuant à ceux existants. Toute personne intéressée peut en faire la demande via l’issue Spring Petclinic Organization. Alors : à vos claviers !!

Resources :

2 réflexions au sujet de « Découvrez les forks de Spring Petclinic »

  1. I was trying to run Spring Petclinic AngularJS  version and am getting below error. Can you please let me know why and how to fix this?

    mvnw spring-boot:run
    [INFO] Scanning for projects…
    [WARNING]
    [WARNING] Some problems were encountered while building the effective model for org.springframework.samples:spring-petclinic-client:jar:1.4.3
    [WARNING] ‘build.plugins.plugin.version’ for com.github.eirslett:frontend-maven-plugin is missing. @ org.springframework.samples:spring-petclinic-client:[unknown-version], C:\raps\GitHub\spring-petclinic-angular1\spring-petclinic-client\pom.xml, line 28, column 12
    [WARNING]
    [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
    [WARNING]
    [WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
    [WARNING]
    [INFO] ————————————————————————
    [INFO] Reactor Build Order:
    [INFO]
    [INFO] Spring Petclinic :: Parent POM
    [INFO] Spring Petclinic :: AngularJS Client
    [INFO] Spring Petclinic :: Spring MVC REST server
    [INFO]
    [INFO] ————————————————————————
    [INFO] Building Spring Petclinic :: Parent POM 1.4.3
    [INFO] ————————————————————————
    [INFO]
    [INFO] >>> spring-boot-maven-plugin:1.4.3.RELEASE:run (default-cli) > test-compile @ spring-petclinic-angular1 >>>
    [INFO]
    [INFO] <<< spring-boot-maven-plugin:1.4.3.RELEASE:run (default-cli) < test-compile @ spring-petclinic-angular1 <<<
    [INFO]
    [INFO] — spring-boot-maven-plugin:1.4.3.RELEASE:run (default-cli) @ spring-petclinic-angular1 —
    [INFO] ————————————————————————
    [INFO] Reactor Summary:
    [INFO]
    [INFO] Spring Petclinic :: Parent POM ………………… FAILURE [ 0.813 s]
    [INFO] Spring Petclinic :: AngularJS Client …………… SKIPPED
    [INFO] Spring Petclinic :: Spring MVC REST server ……… SKIPPED
    [INFO] ————————————————————————
    [INFO] BUILD FAILURE
    [INFO] ————————————————————————
    [INFO] Total time: 1.489 s
    [INFO] Finished at: 2017-01-10T08:09:40+05:30
    [INFO] Final Memory: 16M/245M
    [INFO] ————————————————————————
    [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.4.3.RELEASE:run (default-cli) on project spring-petclinic-angular1: Unable to find a suitable main class, please add a ‘mainClass’ property -> [Help 1]
    [ERROR]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

     

    Thanks in advance

     

Laisser un commentaire

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