1 Xooctory – Projet GL Aurélie COHE Fabien FAGOAGA Alice GARCIA Matthieu JOUBERT Christelle MAZEREAU Client : Xavier HANIN
2 Plan Présentation de lapplication Architecture adoptée Refactoring et utilisation de Triplesec Réalisation de la persistance en base (Hibernate) Configuration de lapplication (Spring) Tests unitaires Conclusion
3 Présentation du projet
4 Objectif du projet (1/2) Etat actuel de lapplication : Application LDAP Persistance
5 Objectif du projet (2/2) Etat souhaité de lapplication : Application LDAPBase de données Persistance
6 Outils utilisés Wicket : Framework Web permettant de développer des pages HTML dynamiques en Java Utilisée pour les IHM Compréhension nécessaire pour pouvoir lutiliser Hibernate : Outil de mapping objet-relationnel Conseillé par notre client Spring : Outil utile pour les configurations de lapplication Triplesec : Permet la communication avec un serveur LDAP
7 Organisation du travail Conception Réalisation découpé en 2 sous-équipes : Un binôme sur Wicket et Triplesec Un trinôme sur Spring et Hibernate Tests
8 Architecture des paquetages (1/2)
9 Architecture des paquetages (2/2) Réorganisation des paquetages Séparation des couches métier, vue et persistance
10 Architecture des classes (1/3) Actuellement : Utilisation de classes Triplesec dans les éléments utilisés par Wicket : Modèles et Panels Utilisation de modèles : adaptateur des données de la couche métier aux composants de Wicket Composants de Wicket : objets permettant de modéliser un élément daffichage Ex : wicket.markup.html.form.Button représente un bouton
11 Architecture des classes (2/3) Exemple des rôles dans l'application existante : Conséquences : oModification de ces éléments afin quils ne fassent pas appel à Triplesec (directement ou indirectement) oAjout dune couche dabstraction
12 Architecture des classes (3/3) Exemple des rôles :
13 Refactoring - Méthodologie Extraction du code spécifique à Triplesec dans les classes Analyse du service rendu par ces portions de code Création de linterface Remplacement du code spécifique à Triplesec par des appels aux méthodes de linterface Déplacement du code spécifique à Triplesec afin dimplémenter les méthodes de linterface
14 Refactoring (1/3) Panels Configuration de lapplication Mise en place de larborescence Code spécifique à Triplesec Paquetage : org.xoocode.xooctory.web
15 Refactoring (2/3) Code spécifique à Triplesec Fonction du code Triplesec : o Sauvegarde o Suppression o Récupération de toutes les instances stockées dans la couche de persistance Objets Triplesec : o Equivalent aux modèles définies
16 Refactoring (3/3) Code initial Code spécifique à Triplesec Code indépendant Code équivalent utilisant les fonctions de linterface
17 Refactoring – Exemple (1/3) public PermissionPanel(String id, Imodel model, Tree tree) { super(id, model, tree); setLegend("Existing Permission"); PermissionModel permissionModel = new PermissionModel(getPermission()); getForm().setModel(new CompoundPropertyModel(permissionModel)); [...] } protected void onDelete() { [Code Triplesec pour la suppression] } protected AdministeredEntity onSave() { [Code triplesec pour la sauvegarde] } private Permission getPermission() { return (Permission) ((DefaultMutableTreeNode) getModelObject()).getUserObject(); } Exemple avec le panel gérant les permissions
18 Refactoring – Exemple (2/3) public PermissionPanel(String id, Imodel model, Tree tree) { super(id, model, tree); setLegend("Existing Permission"); PermissionModel permissionModel = new PermissionModel(getPermission()); getForm().setModel(new CompoundPropertyModel( getPermission() )); [...] } protected void onDelete() { Locator.getSecurityManagementService().deletePermission(getPermission()); } protected AdministeredEntity Model onSave() { return Locator.getSecurityManagementService().savePermission( getPermission(), (PermissionModel) getForm().getModelObject()); } private Permission Model getPermission() { return (Permission Model ) ((DefaultMutableTreeNode) getModelObject()).getUserObject(); }
19 Refactoring – Exemple (3/3) private TriplesecPermissionDAO permissionDAO = new TriplesecPermissionDAO(); [...] public AdministeredEntityModel savePermission(PermissionModel oldPermission, PermissionModel newPermission) { return permissionDAO.save(oldPermission, newPermission); } public void deletePermission(PermissionModel permission) { permissionDAO.delete(permission); } [...] public void delete(PermissionModel permission) { [Code Triplesec pour la suppression] } public AdministeredEntityModel save(PermissionModel oldPermission, PermissionModel newPermission) { [Code Triplesec pour la sauvegarde] } [...] TriplesecPermissionDAO TriplesecSecurityManagementService
20 Persistance en base de données Utilisation dHibernate Informations stockées dans la même base que celle déjà existante Mapping des modèles réalisées dans les classes *Model
21
22 Architecture des classes à mapper Choix technique : Mapping des classes AdministeredEntityModel et LocalUserModel
23 Choix techniques retenus (1/4) La classe AdministeredEntityModel : Mapping en représentant une table par classe concrète Pas de table AdministeredEntity Toutes les tables mappant des classes héritant de AdministeredEntityModel contiennent les données de la classe mère
24 Choix techniques retenus (2/4) La classe LocalUserModel : Hiérarhie dû au framework Triplesec 3 types dutilisateurs : LocalUser, ExternalUser et HauskeysUser Mapping représentant une table par hiérarchie : une seule table User Uniquement des utilisateurs LocalUser
25 Choix techniques retenus (3/4) Tables principales : Ajout des classes faisant lobjet dun mapping dans le fichier de configuration spring-config-hb.xml :... org.xoocode.xooctory.web.directory.security.model.AdministeredEntityModel org.xoocode.xooctory.web.directory.security.model.ApplicationModel org.xoocode.xooctory.web.directory.security.model.GroupModel org.xoocode.xooctory.web.directory.security.model.LocalUserModel org.xoocode.xooctory.web.directory.security.model.PermissionModel org.xoocode.xooctory.web.directory.security.model.ProfileModel org.xoocode.xooctory.web.directory.security.model.RoleModel org.xoocode.xooctory.web.directory.security.model.UserModel
26 Choix techniques retenus (4/4) Dautres tables pour stocker les associations : Table Profile_Grants pour stocker lensemble des privilèges associés aux profils Table …. ATTENTION : diapo 22 -> modifié limage
27 Problème rencontré (1/2) Tous les modèles héritent de AdministeredEntityModel et mapping représentant une table par = InheritanceType.TABLE_PER_CLASS) public abstract class AdministeredEntityModel implements Serializable { private String creatorsName; private String modifiersName; private Date createTimestamp; private Date modifyTimestamp; … } Exception au démarrage de lapplication : org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor':... nested exception is org.hibernate.AnnotationException: No identifier specified for entity: org.xoocode.xooctory.web.directory.security.model.AdministeredEntityModel
28 Problème rencontré (2/2) Causes : Pas didentifiant précisé au modèle avec La classe mère na pas didentifiant, ils sont dans les sous-classes Correction : Utilisation public abstract class AdministeredEntityModel implements Serializable { private String creatorsName; private String modifiersName; private Date createTimestamp; private Date modifyTimestamp; … }
29
30 Implémentation des DAO Hibernate (1/2) Accès à la base de données Hibernate en utilisant un ensemble de DAO Chaque DAO hérite de la classe HibernateDaoSupport du framework Spring : Accès à Hibernate par les méthodes de cette classe public class HbGroupDAO extends HibernateDaoSupport = false) public AdministeredEntityModel add(GroupModel group) { String id = (String) getHibernateTemplate().save(group); group.setId(id); return group; } … }
31 Implémentation des DAO Hibernate (2/2) Instanciation dune SessionFactory obligatoire : Création dun bean pour chaque DAO dans spring- config.xml <bean id="permissionDAO" class="org.xoocode.xooctory.web.directory.security.manager. hibernate.HbPermissionDAO"> Chaque bean possède une propriété SessionFactory récupérée à laide du bean sessionFactory présent dans spring-config-hb.xml ?????????? Vérifier le nom du fic
32 Choix de limplémentation (1/3) Objectifs : Facilité pour changer dimplémentation de la sécurité Pas de modification de code source Solution : utilisation de Spring pour faire la configuration
33 Choix de limplémentation (2/3) Utilisation du fichier spring-config-security.xml Création de 2 beans Mise en commentaire du bean non choisi
34 Choix de limplémentation (3/3) Création dun locator :
35 Les DAO Hibernate (1/3) Homogénéité avec les DAO existants
36 Les DAO Hibernate (2/3) Ajout dun bean pour chaque DAO dans le fichier spring-config.xml
37 Les DAO Hibernate (3/3) Dans spring-config-hb.xml : <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation. AnnotationSessionFactoryBean">... org.xoocode.xooctory.web.directory.security.model.AdministeredEntityModel org.xoocode.xooctory.web.directory.security.model.ApplicationModel org.xoocode.xooctory.web.directory.security.model.GroupModel org.xoocode.xooctory.web.directory.security.model.LocalUserModel org.xoocode.xooctory.web.directory.security.model.PermissionModel org.xoocode.xooctory.web.directory.security.model.ProfileModel org.xoocode.xooctory.web.directory.security.model.RoleModel org.xoocode.xooctory.web.directory.security.model.UserModel
38 Les problèmes rencontrés Dans spring-config-hb.xml Dans spring-config.xml
39 Solution provisoire Erreur : java.lang.ClassNotFoundException: ${jdbc.driver.class}
40
41 Tests existants AvantAprès
42 Nouveaux tests test web Une classe de tests par DAO AjoutMise à jourConsultationSuppression
43 Scénarios des nouveaux tests Ajout dun élément Vérification que lélément ait bien été créé Modification de lélément Vérification que les modifications aient été prises en compte Suppression de lélément Vérification que lélément nexiste plus
44
45 Management – Diagramme de Gantt
46 Conclusion Projet très intéressant Découverte de nouveaux outils Refactoring de code Utilisation dHibernate (approfondissement du cours) Merci à Xavier Hanin pour son aide