projet composants logiciels - e

Transcription

projet composants logiciels - e
IUT Vélizy
PROJET COMPOSANTS LOGICIELS
Licence SIL
Université de Versailles Saint Quentin
SUJET
Introduction.
Il s’agit d’une application qui réalise le travail d'une caisse enregistreuse dans des salons de
coiffure appartenant à une chaîne de franchises. Les services proposés aux clients de ces salons sont
bien sûr des coupes de cheveux.
Les coupes sont adaptées à chaque type de client, femme, homme et enfant. Une coupe peut être
accompagnée de services supplémentaires comme par exemple un shampoing, une couleur, un
brushing ou un soin capillaire.
enregistrer une vente
<<include>>
<<include>>
s'authentifier
consulter le journal des ventes
employé d'un salon de coiffure
Ce sont les employés des salons qui utilisent l'application. Celle-ci doit leur faciliter le travail en
proposant une interface Homme-machine conviviale et simple.
Les cas d'utilisation recensés par l'équipe projet ont permis d'identifier un seul type d'utilisateur,
les employés des salons de coiffure.
Les cas d'utilisations sont «enregistrer une vente » et « consulter le journal des ventes ».
L'application n'est utilisable qu'après authentification de son utilisateur. Celle-ci repose sur un
identifiant et un mot de passe. Les deux cas d'utilisation nécessitant une identification, le cas
d'utilisation « s'authentifier » a été conceptualisé afin de factoriser dans un seul cas cette
fonctionnalité. Il est relié aux deux autres par une relation de type include.
Le premier cas, l'enregistrement d'une vente, permet de choisir un type de coupe de cheveux et les
services supplémentaires éventuels que le client a demandés.
Le second cas, le journal des ventes, mémorise l'ensemble des ventes avec le détail des coupes et
suppléments vendus aux clients (désignation et montant).
JJLC
1/10
LICENCE SIL
Contraintes non fonctionnelles.
L'application est une application Web hébergée au siège de la chaîne sur un serveur d'applications.
Elle est développée avec la plateforme JAVA EE1. C'est à dire avec le langage JAVA et les
technologies SERVLET et JSP mais structurées par le cadriciel (framework) standard JSF2 qui en
représente une couche d'abstraction.
Docker
Docker
Client
navigateur
Internet
Application Web
HTTP
JDBC
déployée dans Tomcat
Derby
mode client-serveur
RMI
Docker
JDBC
Application EJB
déployée dans Wildfly
Les informations produites par l'application sont stockées dans une base de données relationnelle.
Cette base de données sert de source de données à plusieurs applications de l'entreprise, c'est
pourquoi elle doit fonctionner en mode client-serveur. L'éditeur de la base de données choisie est
la fondation APACHE et son produit logiciel qui est libre3, est le SGBDR4 DERBY.
Le serveur d'application retenu pour héberger l'application est le produit logiciel libre TOMCAT,
lui-même appartenant au projet Jakarta de la fondation APACHE. Il s'agit d'un serveur HTTP
capable d'exécuter des applications JAVA EE WEB. Ses clients sont les ordinateurs de type caisse
enregistreuse présents dans les salons de coiffure. L'application est accessible via un navigateur
internet (browser).
Le système d'authentification permet de contrôler et sécuriser l'accès à l'application. Il est hébergé
sur un serveur JAVA EE de type full profile, c'est à dire capable d'exécuter des composants lourds de
type EJB (Enterprise JavaBean). Le serveur retenu est le produit logiciel libre WILDFLY de
l'éditeur JBoss appartenant à la société REDHAT.
Chacun des trois serveurs, d'applications et de données, est déployé dans un conteneur léger de type
LXC avec la solution d'isolation Docker. Les images des conteneurs sont disponibles à partir de
DockerHub et sont respectivement lecoz/derbysiolapie:latest, lecoz/tomcatsiolapie:latest et
lecoz/wildflysiolapie:latest.
1
2
3
JAVA EE : JAVA Enterprise Edition
JSF : JAVA SERVER FACES
Logiciel libre et Open source
4 SGBDR : système de Gestion de Base de Données Relationnelle (RDBMS en anglais)
JJLC
2/10
LICENCE SIL
Le modèle métier.
L'originalité de l'application est qu'elle repose sur un modèle métier persistant structuré grâce aux
patrons de conception5 Décorateur et Monteur (Builder).
Le patron de conception Décorateur s'adapte bien aux modèles contenant des objets qui
représentent un système d'information de base, ici les coupes de cheveux pour femme, pour enfant
et pour homme, et d'autres objets qui eux représentent un système d'information optionnel ou
complémentaire à celui de base, ici les services supplémentaires (couleur, brushing, soins, etc).
Le patron de conception Monteur permet de déléguer à une structure de classes la responsabilité
d'ordonnancer les tâches à réaliser afin de construire un graphe d'objets complexe. Dans le cas
présent celui de construire une structure de décoration.
Le modèle métier a vocation à être persistant. La technologie employée à cette fin est la couche de
persistance standard du langage JAVA : JPA (JAVA PERSISTENCE API). Le produit logiciel libre
utilisé pour implémenter cette couche est HIBERNATE6.
<<entity>>
+ Service
-désignation : String
-tarif : double
1
-service
+detail() : String
+montant() : double
+ Coupe
+ Supplément
+detail() : String
+montant() : double
+ Coupe Femme
+detail() : String
+montant() : double
+ Coupe Enfant
+ Brushing
+ Pas de Coupe
+ Couleur
+ Coupe Homme
+ Shampoing
+ Soin Capillaire
La solution de persistance du modèle décorateur et donc sa correspondance (mapping) au niveau de
la base de données relationnelle est implémentée par une seule table (solution union). Donc une
seule table pour toute la dérivation comprenant les classes Service, Coupe, Supplément,
CoupeHomme, CoupeFemme, CoupeEnfant, PasDeCoupe, Brushing, Couleur, Shampoing et Soin.
Il est possible qu'une cliente ou qu'un client ne désire pas de coupe mais ne veuille qu'un ou
plusieurs services de type supplément. Par exemple un simple brushing. C'est ce qui explique la
présence de la classe PasDeCoupe.
5 Design Pattern
6 Hibernate est un des leaders pour les solutions de persistance des objets Java
JJLC
3/10
LICENCE SIL
Le patron de conception Monteur est composé d'une interface et de deux classes responsables de la
construction de la structure d'objets de la décoration, c'est à dire d'une liste chaînée.
Le Monteur ou Builder est d'ailleurs conçu pour faciliter la création de graphes d'objets complexes.
Dans le cas d'une vente d'un service de coiffure, la construction doit absolument commencer par la
création d'un objet concret de type CoupeFemme, CoupeEnfant, CoupeHomme ou PasDeCoupe et
être « décoré » par zéro ou plusieurs suppléments.
La classe DirecteurDuMontage représente l'interface du patron de conception. C'est à elle que
s'adresse les objets consommateurs du montage.
+ MonteurDeService
+ DirecteurDuMontage
1
+dirigerLaConstruction() : void
-monteur +construire() : void
+getResultat() : Service
1 + Service
-résultat
structure décorateur
décrite dans l'autre
diagramme de classe
+ MonteurDeServiceImpl
+construire() : void
La classe MonteurDeServiceImpl implémente l'interface MonteurDeService. C'est elle qui a la
responsabilité de concrètement construire la structure d'objet représentant la Décoration.
Code source de la classe Monteur :
public class MonteurDeServiceImpl extends MonteurDeService {
private Map<String, Class> services = new Hashtable<String, Class>();
public MonteurDeServiceImpl() {
super();
initialisation();
}
public Service creationService(List<String > choixServices) throws Exception {
Service vente = creationServiceCoupe(choixServices.get(0));
for(int i = 1; i < choixServices.size(); i++)
vente = creationServiceSupplement(choixServices.get(i), vente);
instanciation par
réflexion
return vente;
}
public Service creationServiceCoupe(String typeService) throws Exception {
return (Service) services.get(typeService).newInstance();
}
public Service creationServiceSupplement(String typeService, Service service) throws Exception {
return (Service) services.get(typeService).getConstructor(Service.class).newInstance(service);
}
private void initialisation() {
services.put("CF", CoupeFemme.class);
services.put("CH", CoupeHomme.class);
services.put("PC", PasDeCoupe.class);
services.put("CO", Couleur.class);
services.put("BR", Brushing.class);
services.put("SC", SoinCapillaire.class);
services.put("SH", Shampoing.class);
}
}
JJLC
4/10
LICENCE SIL
L'application Web.
L'application « enregistrer une vente » est structurée grâce au cadriciel JSF. Elle doit proposer une
interface graphique Homme-Machine (IHM) composée de deux listes déroulantes pour en faciliter
l'utilisation.
La première liste propose les services ou formules de base (coupes de cheveux). La seconde liste
propose les suppléments (couleur, brushing, shampoing et soin capillaire).
La première liste est une liste à choix unique alors que la seconde est une liste à choix multiple.
Un bouton permet à l'utilisateur de valider la vente et donc l'enregistrement des services vendus.
Les listes de choix sont initialisées statistiquement dans la page JSF. Elles correspondent à un
composant géré (ManagedBean) avec un cycle de vie égal à celui de la requête HTTP (request
scope).
Ainsi, à chaque fois qu'une vente est validée les objets qui correspondent à chacun des choix sont
instanciés et mis en relation en conformité avec le patron de conception Décorateur qui structure
le modèle grâce aux objets qui implémentent le patron Monteur. Puis le tout est rendu persistant
dans la base de données grâce à l'interface de programmation (API) JSF de la couche de persistance.
Classes et pages de l'application WEB :
1
<<jsf>>
+ login.xhtml
<<managedbean>>
<<request>>
+ ComposantAuthentificateur
<<Remote>>
+ Authentificateur
+authentifier(login : String,password : String) : UtilisateurDTO
+authentifier() : String
+ UtilisateurDTO
2
3
4
<<jsf>>
+ menu.xhtml
<<jsf>>
+ vente.xhtml
<<managedbean>>
<<application>>
+ FournisseurDeGerantDePersistance
<<managedbean>>
<<request>>
+ ComposantVente
+fournir() : EntityManager
+enregistrer() : void
<<jsf>>
+ journal.xhtml
<<managedbean>>
<<request>>
+ ComposantJournal
+ ValueObject
+initialisation() : void
La page d'accueil de l'application (login.xhtml) est celle qui permet à l'utilisateur de s'authentifier. Si
l'authentification réussit, la navigation propose le menu général (menu.xhtml). Selon le choix de
l'utilisateur la navigation propose la page d'enregistrement d'une vente (vente.xhtml) ou celle qui
permet de consulter le journal comptable des ventes (journal.xhtml).
C'est le composant JAVA JSF ComposantAuthentificateur qui interagit avec la page login.xhtml. Il
délègue au service distant implémenté par un composant EJB, l'authentification de l'utilisateur.
Le composant JAVA JSF ComposantVente, quant à lui, interagit avec la page vente.xhtml. Il a la
responsabilité d'enregistrer la vente.
Le composant JAVA JSF ComposantJournal interagit avec la page journal.xhtml. Il a la
responsabilité de créer un objet valeur (ValueObject) contenant la liste des ventes utilisée par la
page journal.xhtml.
JJLC
5/10
LICENCE SIL
L'application EJB.
L'accès à l'application est soumise à authentification. Celle-ci est implémentée par un composant
distribué de type EJB Session Stateless et par un composant persistant de type EJB Entity. Ils ont
pour nom respectif : AuthentificateurEJB et Utilisateur.
Le composant distribué AuthentificateurEJB implémente la méthode authentifier() qui contrôle le
login et le password saisis dans l'interface Homme-machine. Chaque utilisateur correspond à un nuplet dans la table UTILSATEUR de la base de données.
Un objet de type Data Transfer Object (DTO) permet de communiquer la réussite ou l'échec de
l'authentification à l'application WEB.
Le diagramme de classe UML détaille ci-dessous les composants qui interagissent pour
implémenter le cas d'utilisation « s'authentifier ».
<<interface>>
+ Authentificateur
+authentifier(login : String,password : String) : UtilisateurDTO
<<interface>>
+ java.io.Serializable
<<realize>>
<<realize>>
+ UtilisateurDTO
<<EJB Stateless>>
<<Remote>>
+ AuthentificateurEJB
+authentifier(login : String,password : String) : UtilisateurDTO
-nom : String
-prénom : String
-message : String
<<EJB Entity>>
+ Utilisateur
-nom : String
-prénom : String
-login : String
-password : String
L'objet UtilisateurDTO est transmis via le protocole JAVA RMI à l'application WEB à l'issue du
processus d'authentification. Si l'authentification a réussi alors l'objet DTO contient le nom, le
prénom de l'utilisateur et le message a pour contenu « Bienvenue ». En cas d'échec seul le message
est renseigné avec le contenu « Echec ».
Cet objet doit implémenter l'interface java.io.Serializable afin de pouvoir être encodé
(Marshalling) et décodé (UnMarshalling) dans un format lui permettant d'être acheminé par le
réseau du serveur WILDFLY au serveur TOMCAT.
JJLC
6/10
LICENCE SIL
L'interface Homme-Machine.
L'interface de l'application est très simple. Elle doit permettre aux utilisateurs de réaliser une vente
très rapidement. L'utilisateur une fois authentifié arrive sur un menu qui propose les choix qui
correspondent aux deux cas d'utilisation : enregistrer une vente et journal des ventes.
L'application enregistrer une vente propose le choix de la coupe (Enfant, Femme, Homme, Pas de
Coupe) grâce à une liste déroulante à choix unique.
comportement AJAX
Le choix des suppléments est quant à lui réalisé avec l'aide d'une liste déroulante à choix multiple.
Un bouton permet de valider la vente. Un autre de retourner au menu principal.
Après le choix des services et le clic du bouton « enregistrer » il est possible de prévoir un
comportement de type AJAX qui affiche le résumé de la vente : détail des services et total à régler
par le client.
Extrait de la classe ComposantVente en interaction avec la page vente.xhtml :
@ManagedBean(name = "vente")
@RequestScoped
public class ComposantVente {
private String coupe;
private List<String> supplements = new ArrayList<String>();
@ManagedProperty(value = "#{fournisseur}")
private FournisseurDeGerantDePersistance fournisseur;
public void enregistrer(AjaxBehaviorEvent event) throws Exception { ...
Extrait de la page vente.xhtml :
<h:outputLabel>Coupe :</h:outputLabel>
<h:selectOneListbox value="#{vente.coupe}" size="1">
<f:ajax event="click" execute="@form" render="resume" listener="#{vente.raz}"></f:ajax>
<f:selectItem itemValue="CF" itemLabel="coupe femme" />
<f:selectItem itemValue="CH" itemLabel="coupe homme" />
<f:selectItem itemValue="PC" itemLabel="pas de coupe" />
</h:selectOneListbox>
<h:outputLabel>Suppléments :</h:outputLabel>
<h:selectManyListbox value="#{vente.supplements}" size="4">
<f:selectItem itemValue="BR" itemLabel="brushing" />
<f:selectItem itemValue="CO" itemLabel="couleur" />
<f:selectItem itemValue="SH" itemLabel="shampoing" />
<f:selectItem itemValue="SC" itemLabel="soin capillaire" />
</h:selectManyListbox>
JJLC
7/10
LICENCE SIL
La base de données.
Le schéma relationnel est composé de la table SERVICE. Elle est la résultante de la correspondance
objet-relationnel (mapping O-R). Cette correspondance est basée sur la solution UNION. C'est à
dire une seule table pour implémenter une dérivation (interfaces, classes).
Le patron de conception (Design pattern) Décorateur est basé sur un système de relation réflexive
ce qui explique la présence de la colonne SERVICE_FK. Celle-ci est une clé étrangère qui pointe,
qui référence la clé primaire de la même table. Tous les services de type supplément sont chaînés
entre eux et à une coupe ou non coupe via cette clé étrangère.
Pour restaurer les objets de type Service, la requête SQL ne doit sélectionner que les objets
périphériques de chaque décoration. Le patron de conception décorateur est un système qui crée un
amas d'objets dans une architecture qui ressemble à celle des oignons. Avec un cœur, un noyau
entouré, décoré par une succession de pelures d'oignon.
La structure globale est donc une liste chaînée de n-uplets dont il faut retrouver le dernier maillon
pour restaurer l'ensemble des objets appartenant à une décoration.
Schéma relationnel de la base de données
lien réflexif de la décoration
La requête SQL est la suivante :
SELECT * FROM SERVICE WHERE IDSERVICE NOT IN (SELECT IDSERVICE FROM
SERVICE WHERE IDSERVICE IN (SELECT SERVICE_FK FROM SERVICE))
Elle sélectionne le dernier n-uplet de chaque service vendu (la dernière pelure d'oignon). Celui qui
correspond au dernier choix de service : simple coupe ou supplément (dernier décorateur). Ainsi la
couche ORM (Object-Relational Mapping) JPA peut restaurer chaque graphe d'objets qui
correspond à une vente en partant de l'objet le plus périphérique de la structure de décoration. La clé
étrangère permet de traverser tout le graphe.
JJLC
8/10
LICENCE SIL
ANNEXES
Page JSF du menu de l'application :
Page JSF du journal des ventes :
JJLC
9/10
LICENCE SIL
Page JSF de l'authentification :
Diagramme de déploiement :
serveur physique: 192.168.x.x
Docker derby: 172.0.17.2
Docker wildfly: 172.17.0.3
venteDB
serveur WILDLFY
lien docker
SGBDR DERBY
authentificationDB
authentification
JDBC
lien docker
JDBC
lien docker
Docker tomcat: 172.17.0.4
RMI JAVA
serveur tomcat
caise enregistreuse
JPA
JSF
répertoire contenant les bases de
données dans le conteneur
solution alternative pour rendre persistante
la base de données
Script de démarrage des conteneurs Docker :
#!/bin/bash
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
#docker run -d --name derby -v /home/etudiant/docker/sgbdr:/opt/sgbdr lecoz/derbysiolapie:latest
docker run -d --name derby lecoz/derbysiolapie:latest
docker run -d --name wildfly --link derby:derby -v /home/etudiant/docker/wildflylogs:/wildfly-8.1.0.Final/standalone/log lecoz/wildflysiolapie:latest
docker run -d --name tomcat --link derby:derby --link wildfly:wildfly -v /home/etudiant/docker/tomcatlogs:/apache-tomcat-8.0.15/logs
lecoz/tomcatsiolapie:latest
JJLC
10/10
LICENCE SIL