vendredi 17 août 2012

Tester son code LDAP avec OpenDJ

Ceci est la reprise de l'article que j'ai écrit pour Silverpeas. Par rapport au commentaire de Fanf concernant les différentes possibilités de tester du code LDAP avec Unboundid pour un mode complètement en-mémoire, bien que je trouve cette possibilité élégante et sûrement plus performante il se trouve que nous utilisons OpenDJ en production et que je préfére utiliser un code de serveur de production (même en mode mémoire) pour mes tests plutôt qu'un bouchon, aussi performant soit-il.

A l'heure du TDD et du test unitaire il convient de pouvoir tester son code facilement et rapidement.
Si pour les bases de données relationnelles cela est bien documenté, ce n'est pas le cas des annuaires LDAP qui viennent d'un temps où les exigences en termes de tests étaient moindre.
Heureusement les serveurs LDAP Java libres et modernes commencent à prendre ces paramètres en compte.
Si ApacheDS propose un runner JUnit, j'ai eu quelques difficultés à le mettre en œuvre.
J'ai donc décidé d'utiliser OpenDJ qui peut être facilement embarqué et qui peut utiliser un stockage mémoire ce qui permet d'avoir des performances acceptables pour une exécution dans un mode test.
Cependant même si OpenDJ utilise un backend mémoire, sa configuration reste gérée par quelques fichiers. C'est pourquoi vous devrez embarquer quelques fichiers dans vos tests.

Avec JUnit nous avons deux possibilités pour gérer des ressources externes :

  • utiliser un runner particulier qui va gérer les références au serveur embarqué (c'est le choix fait par ApacheDS).
  • utiliser des règles (rules) pour démarrer et arrêter le serveur embarqué. C'est ce choix que nous avons fait en utilisant une ClassRule : c'est à dire une règle qui s'applique sur une variable static de la classe de test. Cette fonctionnalité est disponible depuis JUnit 4.10

Afin de faciliter la configuration du serveur LDAP pour le test nous allons définir une annotation nous servant à passer un certain nombre de paramètres, CreateLdapServer :

  • un fichier LDIF pour insérer des données dans l’annuaire
  • le chemin (en relatif ou absolu) vers le répertoire contenant la configuration minimale d'OpenDJ
  • l'identifiant du backend mémoire où seront mises les données de test
  • le DN de base associé à ce backend.

Maintenant il ne reste plus qu'à écrire notre règle qui doit implémenter l'interface org.junit.rules.TestRule.
Nous avons donc une méthode à réaliser :

@Override
public Statement apply(Statement stmnt, Description d) {
  CreateLdapServer annotation = d.getAnnotation(CreateLdapServer.class);
  if (annotation != null) {
    return statement(stmnt, annotation.serverHome(), annotation.ldifConfig(), annotation.
        ldifFile(), annotation.backendID(), annotation.baseDN());
  }
  return stmnt;
}

La première ligne recherche la présence de notre annotation CreateLdapServer et si celle si est présente alors nous allons encapsuler le test pour démarrer le serveur au chargement de la classe et l'arrêter à la fin des tests. C'est là le rôle de la méthode :

private Statement statement(final Statement stmnt, final String serverHome,
  final String ldifConfigFile, final String ldifFile, final String backendId,
  final String dn) {
  return new Statement() {
    @Override
    public void evaluate() throws Throwable {
      before();
      try {
        stmnt.evaluate();
      } finally {
        after();
      }
    }
    private void after() {
      stopLdapServer();
    }
    private void before() {
      try {
        startLdapServer(serverHome, ldifConfigFile);
        loadLdif(ldifFile, backendId, DN.decode(dn));
      } catch (Exception ex) {
        ex.printStackTrace();
        throw new RuntimeException("Could'nt start LDAP Server", ex);
      }
    }
  };
}

On voit qu'on crée un org.junit.Statement qui encapsule le test originel avec deux méthodes : before() appelée avant l'exécution du test, et after() une fois le test exécuté, quelque soit son résultat. Ces méthodes sont très simples :

  • before() va démarrer le serveur LDAP et y charger le contenu du fichier LDIF,
  • after() va se contenter d'arrêter le dit-serveur.


Les données étant chargées dans un backend mémoire nous n'avons pas besoin de les nettoyer avant d'arrêter le serveur. Pour l'implémentation du démarrage du serveur et son arrêt je vous laisse consulter le code.
Comment utiliser tout cela dans un test :
Tout d'abord vous devez utiliser l'annotation que nous venons de créer :

@CreateLdapServer(ldifConfig="opendj/config/config.ldif", serverHome="opendj", ldifFile="silverpeas-ldap.ldif")
public class LDAPDriverTest {
...

Maintenant, il nous faut déclarer notre règle :

@ClassRule
public static OpenDJRule ldapRule = new OpenDJRule();

Nous voilà donc presque prêts à tester. Il ne nous manque plus que les ressources nécessaires. Dans le cadre d'un projet Apache Maven il faut ajouter les dépendances vers les bibliothèques d'OpenDJ nécessaires :

    ...
    <dependency>
      <groupId>org.forgerock.opendj</groupId>
      <artifactId>opendj-server</artifactId>
     <version>2.4.5</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.sleepycat</groupId>
      <artifactId>je</artifactId>
      <version>1.4.7</version>
      <scope>test</scope>
    </dependency>
    ...


Les ressources nécessaires sont au nombre de deux :
  • le fichier ldif (silverpeas-ldap.ldif) que nous avons déclaré et qui va se retrouver dans src/test/resources
  • le répertoire opendj qui contient la configuration minimale et va lui aussi dans src/test/resources
Attention à ne pas filtrer ce répertoire opendj et tout ce qu'il contient avec Apache Maven.

Le code source et un exemple d'utilisation est disponible sur Github : https://github.com/ehsavoie/embedded-ldap

Merci à Ludovic Poitou pour son aide sur la configuration et l'utilisation OpenDJ.


dimanche 13 novembre 2011

Revue du livre Apache Maven 3 Cookbook

Ce nouveau livre sur Apache Maven se veut un ensemble de recettes pour mettre en œuvre Apache Maven 3 lorsque l'on souhaite démarrer un projet.
Il se compose de 9 chapitres :
  1. Une introduction aux concepts et à l'utilisation d'Apache Maven 3

    Ce premier chapitre est une introduction 'classique' à la mise en place et la configuration d'Apache Maven 3 sur un poste de développement.

  2. Les techniques d’ingénierie logicielle

    Ce chapitre parle des bonnes pratiques de développement d'un logiciel et de l'utilisation de Maven dans un tel contexte. On y parle de TDD, de qualité de code et de gestion des dépendances et comment Apache Maven facilite cette mise en œuvre. On pourra regretter le choix de PMD pour la qualité logicielle plutôt que d’un outil plus complet comme Sonar.

  3. Les principes agiles de développement et de collaboration

    L'auteur explique ici comment intégrer Apache Maven dans votre organisation avec un gestionnaire de dépôts, un serveur d'intégration continue, ... Bref comment tirer un profit maximum des outils autour de Maven pour développer vos logiciels.

  4. Rapports et documentationNous découvrons l'usage des taches de reporting d'Apache Maven pour produire un site statique, de la Javadoc et plusieurs autres rapports. On pourra regretter le fait que les POM montrés utilisent la vieille forme de configuration d'Apache Maven 2.x et non ce qui est spécifique à Apache Maven 3.

  5. Développement Java avec Maven

    On voit ici comment produire un squelette pour chaque type de projet Java d'entreprise :

    • application Web et comment l'exécuter avec Jetty
    • pour J2EE : archetype
    • pour Spring : on construit un vrai projet Spring
    • pour Hibernate : utilisation du hibernate3-maven-plugin
    • Seam avec Seam Forge : projet Maven de generation de code

  6. Développement Google avec Maven

    C'est pour moi le chapitre le plus intéressant car on y voit comment Apache Maven permet de développer dans le monde des technologies Google : Android, GWT et GAE (Google App Engine).
    Android : comment configurer son environnement pour développer et déployer une application Android.
    GWT : Là encore comment configurer son poste pour créer et tester (que ça soit avec l'outil de test intégrer ou Selenium) une application web GWT.
    GAE : comment utiliser la plate forme de cloud de Google et les différents archétypes disponibles pour construire vos applications.

  7. Scala, Groovy et Flex

    Si pour Scala il existe l'outil Simple Build Tool, celui-ci est destiné aux projets Scala purs, si vous mélangez Scala et Java utilisez Maven et ses archétypes.
    Groovy fournit un archétype et un plugin gmaven qui permet aussi l'exécution des scripts Groovy et l'utilisation de la console et du shell Groovy.
    Enfin pour le troisième langage, Flex, nous découvrons flexmojo qui permet de produire la structure d'un projet Flex type ainsi que la documentation de ce plugin.

  8. Intégration dans un EDI

    Les EDI modernes (Netbeans, Elipse, Intellij IDEA) offrent une excellente intégration d'Apache Maven. Chaque EDI est présenté ainsi qu e sa manière d'intégrer Apache Maven et d'importer un projet Apache Maven dans l'outil.

  9. Étendre Apache Maven avec vos plugins

    Apache Maven est extensible au moyen de plugins. Nous voyons ici comment créer un plugin en Java mais aussi les autres manières d'en faire en utilisant des scripts Apache Ant ou Ruby avec JRuby.

En conclusion ce livre apporte plusieurs détails importants, cependant s'il permet une rapide mise en œuvre d'Apache Maven (et c'est bien là son but affiché) un débutant devrait s'orienter vers un livre offrant une vision plus complète pour mieux en maîtriser les concepts avant d'enrichir sa bibliothèque avec cet ouvrage.

mardi 27 avril 2010

Soirée Jersey et Atmosphere

Lundi soir c'était la 3ème soirée de l'AlpesJug et nous avons eu la chance d'avoir Paul Sandoz, spec leader pour JAX-RS et développeur de Jersey.

Après une légère introduction aux principes de REST qui permettent de créer des services :
  • agregeables
  • faiblement couplés
  • scalables
  • simples
  • apportant des fonctionnalités insoupçonnées
JAX-RS (et donc Jersey) apporte une approche par annotation pour l'exposition REST des services. C'est à ce moment là que j'ai bien cru revenir à la présentation Play! framework. Cependant les fichiers de configuration sont remplacés par des annotations et donc on profite de l'IDE pour coder.
Là encore le développeur n'est pas oublié et on obtient des traces très intéressantes sur le routage dans les headers des réponses HTTP de Jersey (si le mode trace est activé) !!!
Paul avance le long de ses démos nous présentant ensuite Jersey MVC, ce qui permet d'aller vers une application web classique (un futur remplacement de Spring MVC ? ;) .
Courageux, Paul se lance dans une démonstration du framework Atmosphere, qui permet la gestion les connexions HTTP persistantes et le véritable push Ajax. Les démos venant de Jean-François Arcand, tout a bien fonctionné mais Paul n'a pas pu être aussi libre qu'il l'avait été pour les démos Jersey.


Enfin, Paul nous a présenté Jersey couplé à différents moteurs de template basés sur Scala (grâce à Scalate) et là la comparaison avec play! est devenue plus qu'évidente. J'ai vraiment l'impression qu'on peut voir dans Jersey un sérieux concurrent aux frameworks web, tout en conservant une grande souplesse (là où Play! a fait le choix tout à fait respectable de définir une pile complète) en termes de frameworks (JEE6, mais d'autres sont aussi possibles).

Pour récupérer les slides et le code des démonstrations.

mercredi 20 janvier 2010

Coder c'est beau

J'ai voulu m'amuser à voir tout le travail que nous avons effectué chez Silverpeas depuis que nous avons décidé d'ouvrir le code.
Pour réaliser cette vidéo j'ai utilisé gource et ffmeg pour encoder le tout en h264. C'est un premier jet mais ça permet de voir qu'ouvrir un logiciel ce n'est pas si évident.

Silverpeas Gource from Emmanuel Hugonnet on Vimeo.

vendredi 4 décembre 2009

Ca bouge dans les Alpes

Et oui ça bouge dans le monde Java de la région grenobloise. Tout d'abord une annonce fracassante : l'AlpesJug est né. Et oui Grenoble a de nouveau son Java User Group. Les réunions mensuelles vont commencer dès le 22/02/2010 avec la venue d'Antonio Goncalves pour nous présenter JEE6 et le 29/03/2010 Arnaud Héritier célèbre dans toute la communauté Maven pour son livre en français avec Nicolas de Loof viendra nous parler de Maven 3.


Toujours à propos de Maven, la traduction de Maven - The definitive guide en français est maintenant achevée et nous (Erwan et moi-même) attendons les retours de vos relectures. Pour vos remarques et vos corrections, passez par Github et pour lire soit le pdf ou la version HTML, une seule adresse : http://www.maven-definitive-guide.fr/