Documentation de développement

Organisation du code source

La version 2 de clover se découpe en plusieurs modules qui correspondent à des rôles fonctionnels spécifiques :

  • cloveretl.engine : ce module correspond au moteur de CloverETL ;
  • cloveretl.lookup : ce module contient le code relatif au lookup pour les bases de données ;
  • cloveretl.sequence : ce module permet de créer des séquences ;
  • cloveretl.component : ce module contient l'ensemble des composants (noeuds) de Clover ;
  • cloveretl.connection : ce module contient les éléments permettant d'effectuer des connections ;
  • cloveretl.thirdparty : ce module contient le code issu de sources autre que Clover.
Chaque module est organisé en paquets, de manière tout à fait classique pour Java.

Sources créées

Le code source propre à Linagora a été créé dans le module thirdparty. À terme, il devrait être intégré à CloverETL dans les modules « component » et « connection ».

Voici l'arborescence des sources :

com
`-- linagora
    |-- connection
        `-- LdapConnection.java
    |-- component
    |   |-- LdapEntryExists.java
    |   |-- LdapReader.java
    |   `-- LdapWriter.java
    `-- ldap
        |-- Jetel2LdapData.java
        |-- Ldap2JetelData.java
        |-- LdapFormatter.java
        `-- LdapParser.java

Le module "connection" contient le code permettant de créer une connexion Clover vers un annuaire. Il contient le code permettant de se connecter à un annuaire en utilisant l'API JNDI ainsi que des fonctions de haut niveau permettant d'effectuer des requêtes LDAP sur l'annuaire. Le module "ldap" contient le code permettant de faire le pont entre l'API JNDI et l'API interne à CloverETL. Le module "component" contient les trois composants qui permettent d'accéder aux annuaires LDAP dans un graphe CloverETL et utilisent le code précédent.

Détails des classes

LdapConnection

Fonctionnement général

Cette classe permet de créer une connexion Clover vers un annuaire LDAP. Concrètement, cette classe donne la possibilité d'ajouter dans la partie "global" du fichier de configuration XML du graphe d'alimentation un connexion de type LDAP en plus des connections de type JDBC. Cette connexion peut alors être utilisée dans les composants nécessitant l'accès à un annuaire.

Ce composant permet de créer des connexions anonymes ou authentifiées grâce à une authentification simple (utilisateur + mot de passe).

D'un point de vu plus technique, cette classe fournit les méthodes de haut niveau permettant d'interagir avec un contexte JNDI (et donc un annuaire LDAP), telles que les méthodes de création du contexte, de recherche et de modification. Ces méthodes constituent une surcouche à l'API JNDI de Sun dans le cadre de la manipulation de l'annuaire LDAP à travers une connexion CloverETL.

Paramètres XML
Voici le détail de la syntaxe XML à utiliser afin de configurer une connexion LDAP dans CloverETL :

Nom de l'attributOptionnelDéfautDéfinition
typenonLDAPtype de connexion, valeur à mettre : "LDAP"
idnon identification de la connexion
hostnameouilocalhostle nom d'hôte du serveur LDAP
portoui389le numéro de port du serveur LDAP
useroui DN de l'utilisateur pour effectuer une connexion authentifiée
passwordoui mot de passe de l'utilisateur pour effectuer une connexion authentifiée
threadSafeConnectionouitruepermet d'éviter les problèmes de concurrence en environnement multi-threadés lorsque plusieurs composants utilisent la connexion

Exemple de connexion à l'annuaire accessible à l'adresse "ldap://ldap.foo.com:1389". La connexion est authentifiée avec l'utilisateur "cn=Manager,dc=foo,dc=bar" ayant le mot de passe "managerpassword" :

<Connection type="LDAP" id="LdapConnection0" hostname="ldap.foo.com" port="1389" user="cn=Manager,dc=foo,dc=bar" password="managerpassword">

Exemple de connexion anonyme utilisant les paramètres par défaut (URL de l'annuaire : "ldap://localhost:389") :

<Connection type="LDAP" id="LdapConnection0">

Composants Clover LDAP

LdapReader
Fonctionnement général

Ce composant permet d'effectuer des recherches dans un annuaire LDAP. Il utilise un connexion LDAP et est paramétré par les attributs classiques d'une requête de recherche LDAP, à savoir :

  • un DN de base pour la recherche,
  • un filtre de recherche LDAP,
  • la portée (ou étendue) de la recherche.
Les résultats de la recherche sont traités séquentiellement. Pour chaque résultat, les attributs de l'entrée LDAP sont transformés en données Clover afin de produire un enregistrement Clover conforme aux métadonnées utilisées.
Description des entrées et sorties

Ce paragraphe décrit les entrées et sorties du composant, ainsi que les données attendues et fournies sur chacune d'elles.

TypeNuméroRôle
sortie0sortie standard des enregistrements lus dans l'annuaire
Paramètres XML

Voici le détail de la syntaxe XML à utiliser afin de configurer un composant LdapReader dans CloverETL :

Nom de l'attributOptionnelDéfautDéfinition
idnon identifiant du composant
typenonLDAP_READERtype de composant : "LDAP_READER"
ldapConnectionnonidentifiant de la connexion à utiliser
basenon DN de base de la recherche.
scopeouiOBJECTPortée de la recherche à effectuer, valeur parmi :
OBJECT : la recherche ne porte que sur l'objet correspond à base
SUBTREE : sous arbre dont la racine est base
ONELEVEL : recherche sur les enfants de base
filteroui(objectClass=*)Filtre à appliquer à la recherche. La syntaxe à utiliser est la même que pour les filtres LDAP

Example de recherche sur l'annuaire identifiée par la connexion "LdapConnection0". La recherche prend comme noeud de base "ou=people,dc=uninett,dc=no", elle est effectué sous l'ensemble du sous-arbre, et le filtre de recherche LDAP est "(uid=*)".

<Node ldapConnection="LdapConnection0" id="INPUT1" type="LDAP_READER" scope="SUBTREE" filter="uid=*" base="ou=people,dc=uninett,dc=no">

Et voici les métadonnées associées à cette recherche, sachant que les "inEmployees" sont de type (classe d'objet) "inetOrgPerson" dans l'annuaire :

<Metadata id="InMetadata">
  <Record name="inEmployees"     type="delimited">
    <Field name="dn"             type="string"  delimiter=";" />
    <Field name="uid"            type="string"  delimiter=";" />
    <Field name="mail"           type="string"  delimiter=";" />
    <Field name="employeeNumber" type="integer" delimiter=";" />
    <Field name="l"              type="string"  delimiter="\\n"/>
  </Record>
</Metadata>
LdapWriter
Fonctionnement général

Ce composant permet d'effectuer des mises à jour du contenu de l'annuaire. Il utilise une connexion LDAP pour contacter l'annuaire sur lequel est effectué la mise à jour. Les différents type de mises à jour sont définies par les actions disponibles, qui peuvent être des ajouts, suppression ou renommage d'entrées, ou des ajouts, suppressions ou modification d'attributs.

Chaque enregistrement Clover est traité en fonction de l'action choisie afin d'effectuer la requête LDAP appropriée.

Les noms des champs des métadonnées doivent correspondre aux noms des attributs des objets cibles. De plus, il doit exister un champ nommé "dn" dont la valeur est le DN de l'entrée qui doit être modifiée par l'enregistrement.

Enfin, aucune vérification a priori n'est effectuée sur la consistance ni sur la validité des données (valeurs, format, etc). Les entrées non-valides pour l'action demandée seront refusées au niveau de l'annuaire. En particulier, dans le cas d'ajout d'entrées, tous les champs obligatoires pour la classe d'objet de l'entrée doivent être renseignés.

Description des entrées et sorties

Ce paragraphe décrit les entrées et sorties du composant, ainsi que les données attendues et fournies sur chacune d'elles.

TypeNuméroRôle
entrée0entrée standard des enregistrements à écrire, modifier ou supprimer dans l'annuaire
sortie0sortie d'erreur : les enregistrements provoquant une exception lors de leur traitement sont envoyés sur cette sortie

Exemple d'enregistrement pouvant provoquer des erreurs : tentative de modification d'une entrée inexistante, suppression d'un attribut obligatoire, ajout d'une entrée dont tous les attributs obligatoires ne sont pas renseignés, perte de la connexion lors de l'ajout de l'entrée, etc.

Paramètres XML

Voici le détail de la syntaxe XML à utiliser afin de configurer un composant LdapReader dans CloverETL :

Nom de l'attributOptionnelDéfautDéfinition
idnon identifiant du composant
typenonLDAP_WRITERtype de composant : "LDAP_WRITER"
ldapConnectionnon identifiant de la connexion à utiliser
actionnonadd_entriesType d'action à effectuer, choisir parmi :
add_entries : ajouter des entrées
remove_entries : enlever les entrées spécifiées
rename_entries : renommer des entrées. La valeur du nouveau DN doit être spécifiée dans le champ "newDn"
replace_attributes : remplacer les attributs spécifiés
remove_attributes : enlever les attributs spécifiés

Exemple de modification d'attributs sur l'annuaire identifié par la connexion "LdapConnection0" :

<Node ldapConnection="LdapConnection0" id="LDAP_Output0" type="LDAP_WRITER"  action="add_entries">

Et voici les métadonnées associées, sachant que les «"outEmployees" sont de type (classe d'objet) "inetOrgPerson" :

<Metadata id="OutMetadata">
  <Record name="outEmployees" type="delimited">
    <Field name="dn"               type="string"  delimiter=";" />
    <Field name="departmentNumber" type="integer" delimiter=";" />
    <Field name="mail"             type="string"  delimiter="\\n" />
  </Record>
</Metadata>
LdapEntryExists
Fonctionnement général

Cette classe utilise encore une fois une connexion LDAP. Son rôle est de vérifier l'existence dans l'annuaire définit par la connexion des enregistrements qui lui sont fournis en entrée. Les enregistrements sont alors triés en deux groupes, ceux présents dans l'annuaire (qui sont envoyés sur la sortie 0 du composant) et ceux absents (envoyés sur la sortie 1 du composant).

Attention, ce composant est à utiliser avec précaution : si le contenu de l'annuaire sur lequel est effectué le test d'existence est modifié au cours de l'exécution du graphe, les résultats peuvent ne pas être cohérents avec les différents états de l'annuaire (en effet, nous pouvons rencontrer des problèmes race condition, l'ensemble de CloverETL étant multi-threadé et chaque composant étant exécuté en parallèle des autres).

Description des entrées et sorties

Ce paragraphe décrit les entrées et sorties du composant, ainsi que les données attendues et fournies sur chacune d'elles.

TypeNuméroRôle
entrée0entrée standard des enregistrements à écrire, modifier ou supprimer dans l'annuaire
sortie0sortie standard : les entrées trouvées sont envoyées sur cette sortie (comportement par défaut, voir le paramètre switchOutputs)
sortie1sortie standard : les entrées non trouvées sont envoyées sur cette sortie (comportement par défaut, voir le paramètre switchOutputs)
sortie2sortie d'erreur : les enregistrements provoquant une exception lors de leur traitement sont envoyés sur cette sortie
Paramètres XML

Voici le détail de la syntaxe XML à utiliser afin de configurer un composant LdapReader dans CloverETL :

Nom de l'attributOptionnelDéfautDéfinition
idnon identifiant du composant
typenonLDAP_ENTRY_EXISTStype de composant : "LDAP_ENTRY_EXISTS"
ldapConnectionnon identifiant de la connexion à utiliser
switchOutputsouifalseInverser les sorties. Si "true", les entrées trouvées sont envoyées sur la sortie 1, les entrées non trouvées sont envoyées sur la sortie 0

Exemple :

<Node ldapConnection="LdapConnection0" id="LDAP_entry_exists_0" type="LDAP_ENTRY_EXISTS">

Et voici les métadonnées associées, sachant que les "outEmployees" sont de type "inetOrgPerson" :

<Metadata id="OutMetadata">
  <Record name="outEmployees" type="delimited">
    <Field name="dn"               type="string"  delimiter=";" />
    <Field name="departmentNumber" type="integer" delimiter=";" />
    <Field name="mail"             type="string"  delimiter="\\n" />
  </Record>
</Metadata>

Classes utilitaires

Le paquet « com.linagora.ldap » contient l'ensemble du code liant l'API de Clover à l'API JNDI de Sun. Ce code permet de créer une connexion Clover, fournit les outils permettant d'effectuer des requêtes en lecture ou en écriture sur l'annuaire, et de transformer les données JNDI en données Clover (ou inversement).

Le rôle précis de chaque classe est décrit ci-dessous.

LdapParser

Cette classe est la classe qui permet de faire le lien entre une connexion à un annuaire et les données LDAP, le composant LdapReader et les données Clover ETL.

Elle a deux rôles :

  • elle prend en charge le traitement des requêtes LDAP effectuées sur la connexion ; en particulier, elle traite les exceptions JNDI qui peuvent être générées par la connexion ;
  • elle transforme les données LDAP en données Clover ETL en utilisant la classe Ldap2JetelData et les métadonnées du composant LdapReader lié.
LdapFormatter

Cette classe est le pendant de la classe LdapParser pour le côté écriture. Elle est donc utilisée par le composant LdapWriter pour prendre en charge le traitement des requêtes JNDI et la transformation des données Clover en données LDAP grâce aux métadonnées liées au composant et à la classe Jetel2LdapData.

Jetel2LdapData et Ldap2JetelData

Ces deux classes sont des utilitaires qui permettent d'effectuer les transtypages entre les types Clover et les types LDAP.

Comme aucune vérification n'est effectuée en client pour les données LDAP, ces classes servent essentiellement à transformer des chaînes de caractères en données d'un type Clover. Elles prennent également en charge la gestion des attributs multivalués (par concaténation).