Why make donate

SimExplorer SI - Implémentation

Découpage

Module entities

Ce premier module a trois objectifs :

  1. les classes de données
  2. les types de contenus attachés aux données
  3. les "usines" à instances, capables d'instancier les données, et de sérialiser/désérialiser en XML

Classes de données

Ce sont des classes sérializables. Elles représentent le modèle de données fournies. Le type "LoggableElement" se voit rattaché une association vers un "MetaDataEntity". Cette classe contient toutes les propriétés nécessaires au fonctionnement de Simexplorer SI.

Types de contenus

Afin de traiter les contenus attachés aux données, ContentType permet de spécifier le type d'un contenu en fournissant le MIME type et une méthode virtuelle de conversion d'un flux en texte, afin de l'afficher ou de l'indexer pour la recherche.

Factories

Ces classes servent à charger/sauver les objets sous la forme de fichiers XML.

Module storage

Database

Cette interface spécifie comment les meta données doivent être gérées. On y trouvera :

  1. ouverture/fermeture/commit
  2. insertion d'élément
  3. Récupération d'un élément dans sa dernière version, ou dans une version spécifique grâce à l'obtention de toutes ses versions
  4. Recherche paginée d'élements (ie comptage et extraction d'un sous ensemble des résultats) : - par propriétés - par type - par recherche dans le contenu
  5. Suppression d'un élément
Une implémentation est fournie, basée sur Lucene.

Attachment

On trouvera dans cette interface les méthodes nécessaires à la gestion du stockage des flux. Ainsi, on peut stocker/retrouver/effacer un flux. Un flux est l'association d'une meta donnée, d'un champ et d'un contenu (InputStream). Une implementation est fournie, basée sur le système de fichiers.

Engine

On trouvera dans ce dernier package l'association de "Database" et "Attachment". On retrouvera grosso modo les méthodes disponibles dans "Database", agrémentées des flux de contenu, en convertissant les contenus attaché aux meta données en données indexables par exemple. StorageEngine propose aussi le stockage de flux temporaires, afin de dupliquer des InputStream.

Module service

Ce module est constitué d'une interface du service et de ses implémentations. On retrouvera dans cette interface tout ce qui est nécessaire au fonctionnement de :
  1. l'application web, en accès EJB
  2. le service de stockage local du client lourd, en instance locale
  3. la connexion au serveur central, en accès EJB

Module web

L'accès au service EJB se fait via StorageServiceFactory. Si le proxy n'a pas été initialisé, on recherche l'EJB via des propriétés JNDI propres à JBoss. Un ContextListener ouvre le service lors du lancement du serveur, et le ferme à son arrêt. Un composant Layout permet de définir toutes les pages. Les autres pages utilisent alors uniquement ce composant dans leur page, et mette leur contenu propre à l'intérieur.

Authentification/Autorisations

On souhaite pouvoir gérer des utilisateurs et des groupes ayant des droits sur les entités de l'application.

L'authentification

Les utilisateurs et les groupes sont des données pouvant être stockées dans une base de données, embarquée type H2 ou dédiée type PostGreSQL. Afin de permettre le choix de la base et la simplification du développement de l'intégration et du développement, le stockage sera géré par JPA.

L'authentification en elle même peut se baser sur JAAS, afin de bénéficier de son expérience de sécurisation.

Deux possibilités s'offrent pour l'authentification :

  • se baser entièrement la sécurité de JBoss (JBossSX) Cette solution a l'avantage et l'inconvénient d'être très intégré aux EJB, permettant de retrouver le Principal de façon simple. De plus, si l'application web est lancée dans le même JBoss, elle peut utiliser le même contexte de sécurité.
  • créer un EJB d'authentification et fournir un "token" à l'utilisateur Cette solution implique des développement plus lourds lors des appels métiers, en demandant à l'utilisateur du service de prouver qu'il est bien authentifié. Le système utilisé serait celui utilisé par les applications web pour authentifier l'utilisateur, avec un cookie contenant un identifiant de session. Ce contexte de connexion est alors à passer à chaque appel de méthode.
La deuxième solution possède le net avantage de ne pas dépendre sur l'implémentation de sécurité de JBoss.

Les autorisations

De la même façon que la base de données est gérée, une interface définie ce que doit implémenter le service de gestion des autorisations :
  1. Ajout/création/suppression d'entités (uniquement son identifiant)
  2. Ajout/création/suppression des permissions sur les entités
  3. Vérification des permissions sur un élément par rapport à un utilisateur
  4. Filtrage d'une liste de résultats
Le principal problème réside dans la recherche par contenu. En effet, cette partie étant gérée par la base de données, il est possible d'intéragir avec les résultats uniquement a posteriori. Ainsi, le comptage du nombre de résultats auquel l'utilisateur a accès n'est pas possible. Il est néanmoins possible d'afficher le nombre de résultats hors filtrage, puis d'appliquer les autorisations à l'affichage de chaque ligne de résultat. L'utilisateur obtient alors tout de même le nombre d'éléments auxquels il n'a pas accès.

Utilisation service

L'interface StorageService est la base commune à l'application web et au client lourd. Ce service est disponible sur le serveur afin d'afficher les données dans l'application web, et pour synchroniser le client lourd avec les données locales. Une instance est aussi disponible par client lourd lancé, afin de gérer les données stockées localement.

Afin d'accéder au service sur le serveur, le code suivant est nécessaire :

StorageService storageService = null;
Properties properties = (Properties) System.getProperties().clone();
properties.put("java.naming.provider.url", "jnp://localhost:1099");
properties.put("java.naming.factory.initial",
               "org.jnp.interfaces.NamingContextFactory");
properties
                 .put("java.naming.factory.url.pkgs", "org.jnp.interfaces");

         Context context = new InitialContext(properties);
         storageService = (StorageService) context
                 .lookup("StorageService");

On trouve alors dans storageService un proxy attaquant le service EJB déployé dans JBoss.

Les classes nécessaires à l'accès au serveur JBoss sont contenus dans jbossall-client (disponible sur le dépôt maven java.net).

reStructuredText
google analytics