Modélisation UML & SysML

Expertise et articles Blog sur UML, SysML, et Enterprise Architect de Sparx Systems

mardi, 29 novembre 2016 16:30

MDG VISEO EA UML to JHipster Generator : générateur JDL d'entités JHipster à partir de modèles UML

Écrit par
Évaluer cet article
(0 Votes)

VISEO EA UML to JHipster Generator MDG Technology

Cet article présente le MDG "VISEO EA UML to JHipster Generator", un générateur UML vers JHipster pour transformer un modèle de classes réalisé avec l’outil de modélisation Sparx Systems Enterprise Architect au format JDL (JHipster Domain Language).

JHipster permet de générer à partir d'un fichier JDL les entités d’une application avec leurs propriétés et relations. JHipster est un générateur d'application utilisé pour développer rapidement des applications Web modernes en utilisant Angular et le framework Spring. Il s'inscrit dans une démarche RAD (Rapid Application Development).

En l'absence d'un outil d'intégration entre les modèles UML définis avec Sparx Enterprise Architect et JHipster, j'ai réalisé ce module pour une application logicielle développée avec JHipster 2 chez VISEO.

Mise à jour (31/10/2017) : ce projet est dorénavant disponible sur GitHub (MDG-Sparx-EA-UML-JHipster Github project) et pourra ainsi évoluer avec les dernières définitions JDL de JHipster.

Note : an english version of this article is available here (version anglaise).

Contexte

Un référentiel de modélisation a été défini avec Enterprise Architect afin de centraliser les informations et connaissances pour l’équipe de développement VISEO R&I, ainsi que pour les partenaires.

Un modèle de classes métier a été établi lors des premières phases du projet, partagé via une représentation visuelle avec UML. Cette approche a facilité la conception dans l'environnement technique, JHipster.

JHipster (Java Hipster) est un framework de développement rapide dédié à la création d'applications web.

JHipster fournit des outils pour générer un projet avec une pile Java coté serveur (SpringBoot Spring Security, Spring Data, Spring MVC, etc.) , et un frontal Web adaptatif coté client (AngularJS et Bootstrap). JHipster embarque également des outils de développement pré-configurés comme Yeoman, Maven, Gradle, Grunt, Gulp.js et Bower.

Générateur UML vers JHipster JDL

Présentation

La réalisation de modèles de classes sur les couches métier et technique a permis de maîtriser la bonne intégration des notions métiers dans l'application. Les échanges durant les ateliers de conception ont été facilités via un outil et langage communs (Sparx Enterprise Architect et UML).

La recherche d’intégrations existantes entre outils UML et JHipster pointait principalement sur des exports XMI. D’expérience, XMI est souvent mal implémenté pour un échange exploitable de modèles UML entre outils i.e. sans perte ou altération. Le JDL Studio m’a paru intéressant; cet outil de modélisation en ligne permet d'obtenir un fichier JDL dont le contenu est exploitable par JHipster pour générer des entités (exemple de commande : "yo jhipster:import-jdl export-jdl-uml.jh").
En l’absence d'un générateur adéquat entre Enterprise Architect et JHipster, j’ai réalisé un script pour générer ce contenu directement à partir de modèles UML EA. Ce script s’appuie sur les spécificités JHipster 2 suivantes, intégrées dans EA :

  • Data types : intégration des types JHipster sur les attributs de classes UML.
  • Profil UML : stéréotypes de classes et d’attributs UML afin de disposer de tagged values optionnelles présentées ci-dessous.
    • Classes
      • jhipsterDto : déclare la classe comme DTO mapstruct
      • jhipsterPaginate : choix de pagination pour une liste (infinite-scroll, pager, pagination)
      • jhipsterService : déclare la classe avec le serviceClass
    • Attributs
      • jhipsterisRequired : déclare l'attribut comme obligatoire
      • jhipsterMin: déclare la valeur minimum (minlength pour le type String, ou min pour le type Integer, Long, Float, Double, BigDecimal)
      • jhipsterMax: déclare la valeur maximum (maxlength pour le type String, ou max pour le type Integer, Long, Float, Double, BigDecimal)
      • jhipsterPattern: déclare la valeur pattern pour un attribut de type String
    • Script : générateur du contenu JDL

 Le diagramme de classes UML suivant illustre le méta-modèle personnalisé pour la génération UML vers JHipster 2 JDL :

SparxSystems Enterprise Architect UML to JHipster JDL File generator metamodel

Ces éléments ont été améliorés au fur et à mesure de leur mise en pratique, ou lors d'évaluations par les experts JHipster de VISEO.

Installation

Le MDG EA UML to JHIpster est publié au travers d'un fichier XML. Une fois installé (menu PROJECT > MDG Technology Import), ce MDG est visible dans la liste suivante :

MDG EA UML to JHipster JDL

Remarque : le fichier d'installation et les sources du MDG sont disponibles depuis GitHub: MDG-Sparx-EA-UML-JHipster Github project. Pour toute question, vous pouvez me contacter par mail sur jhipster[at]umlchannel.com.

Diagrammes JHipster et boîte à outils contextuelle

Le MDG Technology JHipster permet de créer un diagramme avec sa boîte à outils contextuelle. Celle-ci propose de créer des entités ou attributs JHipster :

uml to jhipster sparx en toolbox

Remarque : les stéréotypes JHipster sont masqués par défaut dans le diagramme de type JHipster afin d’améliorer la lisibilité. Voici une illustration d’une entité JHipster avec et sans affichage du stéréotype :

mdg stereotypes jhipster uml profile

Profil UML et stéréotypes JHipster

Le MDG Technology JHipster embarque un profil UML ; une classe ou un attribut stéréotypé "JHipster" dispose de Tagged Values nécessaires à la génération JDL.

Pour démarrer un modèle de conception UML JHipster, les éléments Entity doivent être créés à l'aide de la boîte à outils. Les propriétés de ces classes permettent d’accéder aux tagged values disponibles sous l'onglet JHipster : DTO, paginate, service. La valeur "none" est proposée par défaut afin de permettre à toutes ces propriétés d’être optionnelles.

uml jhipster entity properties

Le champ Language JHipster est défini par défaut pour ces classes afin de disposer des data types JHipster pour les attributs.

La boîte à outils contextuelle permet de créer des attributs stéréotypés JHipster sur une classe JHipster Entity. Les propriétés JDL d'un attribut sont accessibles via l’onglet Tagged Values, illustré ci-dessous.

sparx ea uml attribute jhipster

Script de génération UML vers JHipster

Le diagramme de classes UML suivant a été réalisé avec Sparx Enterprise Architect selon l’exemple du JDL Studio. Ce modèle a permis de vérifier que les contenus JDL générés sont identiques.

En comparaison avec la représentation utilisée par le modeleur en ligne JDL Studio, le diagramme de classes UML présente l’avantage de s’appuyer sur un standard. De plus l'outil Sparx EA permet d'intégrer cette représentation dans un référentiel de modélisation, s'intégrant ainsi dans une démarche globale et adaptée.

jhipster jdl studio uml class diagram sparx enterprise architect

Le contenu JDL suivant a été généré à part de ce script :

=== EA UML to JHipster Entity Export ===
== More information is available from www.umlchannel.com/jhipster ==
INSTRUCTIONS: copy and paste the following content in a text file, and rename it e.g. as dpl.jh =
entity Department {
departmentId Long,
departmentName String required
}
entity JobHistory {
startDate ZonedDateTime,
endDate ZonedDateTime,
language Language
}
entity Job {
jobId Long,
jobTitle String,
minSalary Long,
maxSalary Long
}
/**
* The Employee entity.
*/
entity Employee {
employeeId Long,
/**
* The firstname attribute.
*/
firstName String,
lastName String,
email String,
phoneNumber String,
hireDate ZonedDateTime,
salary Long,
commissionPct Long
}
entity Location {
locationId Long,
streetAddress String,
postalCode String,
city String,
stateProvince String
}
entity Task {
taskId Long,
title String,
description String
}
entity Country {
countryId Long,
countryName String
}
entity Region {
regionId Long,
regionName String
}
enum Language {
FRENCH, ENGLISH, SPANISH
}
relationship OneToOne {
Department{location} to Location
}
relationship OneToMany {

/**
* A relationship
*/
Department{employee} to
/**
* Another side of the same relationship
*/
Employee
}
relationship OneToOne {
JobHistory{department} to Department
}
relationship OneToOne {
JobHistory{employee} to Employee
}
relationship OneToOne {
JobHistory{job} to Job
}
relationship ManyToMany {
Job{task(title)} to Task{job}
}
relationship ManyToOne {
Employee{manager} to Employee
}
relationship OneToMany {
Employee{job} to Job
}
relationship OneToOne {
Location{country} to Country
}
relationship OneToOne {
Country{region} to Region
}
paginate JobHistory, Employee with infinite-scroll
paginate Job with pagination
dto Job, Employee with mapstruct
service Employee with serviceClass

 La dernière étape consiste alors à copier ce contenu dans un fichier JH et de l'utiliser dans JHipster pour générer les entités.

Utilisation

Cette approche est a été utile pour injecter facilement de nouvelles versions du modèle d'entités dans JHipster. Les mises à jour dans EA ont ainsi pu être réalisées pour être en phase avec le métier, puis testées et validées directement dans l'environnement technique.

Une fois les entités utilisées dans JHipster, des spécificités dans le code empêchent la génération systématique depuis le modèle UML. Néanmoins cette approche a permis de partir d'un modèle de conception UML dont la définition correspond exactement au modèle implémenté dans les premières itérations du projet. Ce niveau de visibilité est très utile, même si des écarts sont voués à apparaître (reste à l'équipe de maintenir un niveau de cohérence entre le modèle UML et JHipster si besoin).

Evolutions

Ce MDG a été réalisé et utilisé avec JHipster 2. Il pourra évoluer à l'avenir pour proposer une compatibilité avec les dernières propriétés de JHipster, notamment:

  • Nouvelle valeur de service pour les entités (serviceImpl)
  • Support de la syntaxe « dto (ou service ) * with … except … »
  • Support de skipClient et skipServer sur les entités
  • angularSuffix
  • Déclaration de microservices (ex : microservice with <jhipster app name>)
  • Activation de la recherche elasticsearch sur des entités (ex : search * with elasticsearch except …)
  • Nouveaux types (AnyBlob, ImageBlob)
  • Générer minbytes & maxbypes sur les attributs de type blob (Blob, AnyBlob, ImageBlob)