Résumé
Le LSC est un outil d'alimentation d'annuaire LDAP à partir d'une source JDBC. Il a été conçu pour simplifier au maximum la synchronisation à partir du résultat d'une requête SQL avec des entrées de l'annuaire. Le format pivot est un objet POJO qui est généré à partir du schéma LDAP de la classe d'objet correspondante.
Généralités
L'outil de synchronisation est constitué d'un ensemble de classes JAVA, regroupées sous la forme de divers paquetages. Il est possible d'en distinguer deux grandes parties :
La partie générique dans le répertoire src/app permettant d'assurer le plus gros du travail de synchronisation ;
La partie spécifique dans le répertoire src/impl, à implémenter suivant l'annuaire et le schéma des objets relationnels d'origine, et qui permet de mettre en œuvre la partie générique.
Cette documentation n'abordera pas la première partie, celle-ci étant considérée comme relativement stable, et fournissant tous les moyens nécessaires pour implémenter les classes JAVA de la seconde partie.
Fonctionnement
Le LSC s'articule autour de trois axes fondamentaux :
- La définition d'objets (POJO) déclinés
- en objets plats (valeurs de type String) afin de représenter les données extraites directement depuis les enregistrements résultats d'une requête SQL
- en objets "normaux" (valeurs de type String et List) afin de représenter sous forme LDAP les entrées annuaire ;
- Un moteur générique, permettant de manipuler ces objets, de faire des comparaisons et d'évaluer les modifications à apporter sur l'annuaire.
Les deux premiers points font parties intégrantes de la seconde partie du logiciel. Quant au troisième point, il est géré par la première partie, et ne devrait pas être abordé par le développeur. Le travail important se situe donc essentiellement au niveau de ces deux premiers points.
Pour mettre en œuvre le processus de synchronisation, chaque classe d'objet LDAP doit être associée à un ensemble de classes JAVA, permettant essentiellement de manipuler les données. Il est possible de distinguer cinq grandes catégories de classes :
- Les BEANs : utilisés par le moteur générique afin de synchroniser les données relatives à la classe d'objet LDAP ;
- Les objets JNDI : utilisés par le moteur pour accéder aux données relatives à la classe d'objet LDAP dans l'annuaire ;
- Les objets LDAP : utilisés par le moteur pour reconstituer une entrées LDAP à partir de données provenant de la base de données ou de l'annuaire ;
- Les objets JDBC : utilisés par le moteur générique afin de récupérer les données associées à une entrée LDAP en provenance de la base de données ;
- Les fichiers de requêtes SQL : ce sont des fichiers XML, sous un format bien précis, utilisés dans le cadre des librairies IBATIS, afin de pouvoir interroger une base de données pour récupérer un ensemble d'information. Chaque entrée LDAP est associée à un fichier XML qui dispose d'au minimum deux requêtes SQL :
- l'une afin de récupérer l'ensemble des identifiants des entrées dans la base,
- l'autre afin de récupérer les informations d'une entrée à partir d'un identifiant dans la base.
Par conséquent, à une classe d'objet LDAP est associée obligatoirement : une classe d'objet JAVA représentant une classe d'objet LDAP, un objet JNDI, un objet JDBC et un fichier XML de requêtes SQL, et un BEAN. Cette rigidité dans l'outil produit nécessairement une difficulté dans la mise en œuvre de la synchronisation. L'illustration ci-dessous indique où interviennent ces différentes entités.

La partie générique de l'outil fournit bien entendu un ensemble de classes de base sur lesquelles doivent se reposer les classes spécifiques. Ces dernières permettront de mettre en avant des comportements particuliers à chaque classe d'objet LDAP. Parmi ces classes de base, il faut souligner :
- Les classes beans.AbstractBean – implémentées par tous les BEANs – et beans.BeanComparator : la première définie le comportement général d'un BEAN, tandis que la seconde effectue des comparaisons entre BEANs – et par déduction entre entrées en base de données et entrées LDAP ;
- La classe introspection.BeanIntrospection : elle permet au moteur générique de s'abstraire complètement des liaisons par appel de méthode entre BEANs. Cette classe d'objet analyse le code JAVA d'un BEAN et le complète si nécessaire grâce aux objets LDAP en JAVA.
- Les classes jndi.JndiModifications et jndi.JndiServices : la première effectue le travail de recherche LDAP pour constituer les entrées LDAP sous forme de classe JAVA, la seconde recense les modifications à effectuer sur une entrée LDAP en fonction d'une entrée LDAP sous forme de classe JAVA ;
- Les classes d'objet LDAP de base dans le paquetage objects : top, person, inetOrgPerson, organizationalUnit, etc ...

Enfin, l'outil est proposé avec d'autres paquetages plus ou moins libres, notamment :
- Les paquetages JAVA IBATIS permettant de lire des fichiers XML contenant des requêtes SQL ;
- Les paquetages JAVA contenant les pilotes spécifiques à chaque SGBD ;
- Le paquetage Log4J afin de tracer des événements au niveau du code JAVA dans des logs au format Syslog UNIX.
Arborescence
Voici une capture d'écran de l'arborescence des paquetages JAVA, sous l'IDE Eclipse.

L'arborescence du répertoire de l'outil est relativement simple :
- app contient trois fichiers de configuration :
- database.properties : la configuration d'accès à la base de données, au format JDBC ;
- log4j.properties : la configuration du paquetage Log4J ;
- lsc.properties : la configuration générale de l'outil (essentiellement les informations d'accès à l'annuaire).
- bin contient l'ensemble des sources compilées ;
- build est le répertoire de construction du paquetage LSC, opération effectuée à l'aide de l'outil ant ;
- doc recense la documentation éventuellement fournie avec l'outil ;
- lib-ext contient les librairies externes supplémentaires indispensables au bon fonctionnement de l'outil ;
- misc est utilisé par l'outil IVY de résolution de dépendances de paquetages JAVA ;
- src contient les sources des classes JAVA.
Cette arborescence est complétée par un fichier relativement important, le fichier build.xml. Ce fichier est un fichier au format XML utilisé par l'outil ant pour exécuter des tâches particulières de l'outil de synchronisation. Il peut être utilisé, par exemple, pour importer le projet dans l'IDE Eclipse.
Types de fichiers
Au sein du répertoire src, il faut distinguer trois types de fichiers distincts :
Les classes d'objets JAVA, effectuant le travail nécessaire ;
Les fichiers « flat » permettant de représenter une classe d'objet LDAP au format JAVA, sans se soucier du type des attributs. Ceux-ci sont disponibles dans le répertoire src/impl, au sein du paquetage org.linagora.ldap.lsc.objects.flat ;
Les fichiers XML contenant des requêtes SQL, celles-ci permettent de retrouver des données particulières nécessaires à l'organisation des données dans l'annuaire, par exemple. Ces fichiers sont disponibles dans le répertoire src/impl, au sein du paquetage org.linagora.ldap.lsc.persistance.xml.
Génération automatique
Afin d'alléger la création de tous les fichiers nécessaires à la bonne mise en œuvre de la synchronisation, l'outil dispose d'une tâche de génération automatique de ces fichiers, directement à partir de l'annuaire visé.
La génération des fichiers s'effectue en deux étapes :
- Interrogation de l'annuaire pour récupérer l'intégralité du schéma LDAP ;
- Génération des fichiers nécessaires pour la classe d'objet demandée par l'utilisateur.
La commande suivante permet de lancer la génération des fichiers :
$ ant -DocName="maClasseDObjectLDAP" generator
Les fichiers générés seront disponibles dans le répertoire src/impl, dans les sous-paquetages beans, jndi, objects et object.flat, persistance.xml, et service. C'est fichiers sont génériques, il faut obligatoirement repasser dessus pour effectuer les modifications importantes du comportement de chaque classe.
Effectuer une synchronisation
Les chapitres suivants vont détailler la mise en œuvre de code JAVA afin de permettre une synchronisation correcte entre une base de données source et un annuaire destinataire, sachant qu'à l'heure actuelle la base de données est maître sur l'annuaire.
La commande suivante permet de lancer la synchronisation :
$ ant synchronize
Buildfile: build.xmlinit:compile-app:
[echo] Copying xml and properties filesprepare-env:synchronize:
[java] JVM args ignored when same JVM is used.
[java] Working directory ignored when same JVM is used.
[java] 0 [main] INFO org.linagora.ldap.lsc.beans.BeanComparator.calculateModifications(BeanComparator.java:149) - Modifying entry "uid=C3097855,ou=ComptesUtilisateurs"
[java] 13512 [main] INFO org.linagora.ldap.lsc.beans.BeanComparator.calculateModifications(BeanComparator.java:90) - Adding new entry "uid=C3883410,ou=ComptesUtilisateurs"
[...]
Si la commande ne fonctionne pas, cela provient essentiellement de la JRE Java non adaptée ou non trouvée. Il est possible de fixer la variable d'environnement JAVA_HOME vers le répertoire d'installation de la JVM de SUN.
La commande suivante est valable pour un système Ubuntu 7.04 possédant le paquetage JAVA sun-java6-jre.
export JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.00/jre