jeudi 4 octobre 2007

Bonne pratique pour gérer les environnement multiple dans maven

A chaque fois qu'un fichier représente un élément de configuration :

- fichier de propriétés
- fichier de configuration des log
- fichier de configuration hibernate
etc.

Il doit être aisément modifiable, c'est à dire qu'il ne doit pas se trouver dans un jar mais se trouvé dans un fichier facilement modifiable. Dans une application Web on placera le fichier de log4j.properties, hibernate.cfg.xml dans le répertoire classes. Ainsi, ces répertoire sont facilement modifiable par un intervenant qui ne connait a priori rien au fonctionnement de l'application.

Quand une application Web utilise un librairie, il ne faut donc pas qu'elle contienne de ressource susceptible d'interférer avec sa propre configuration. Concrètement, il faut éviter de mettre les fichier de configuration dans les partie

src/main des application et les mettre dans le repertoire test.

Il arrive parfois que la configuration soit une tache complexe et qu'il ne s'agisse pas de modifier quelques lignes mais de nombreuse modifications auquels cas il est plus approprié d'effectuer une copie pure et simple des fichiers de configuration et de garder ceux-ci dans le référentiel de sources.

Pour ce genre de problématique, maven a un mécanisme permettant de constituer un package et sa configuration à partir d'un ensemble de fichiers groupé dans un répertoire. Le mécanisme utilisé s'appelle profil. L'utilisation d'un profil conditionne le comportement de maven, il est selectionné par maven en tapant la commande -P

Supposons qu'on ai 4 environnements :

- Développement
- Test
- Recette
- Production

Pour créer un package, on spécifie le profil utilisé. Par exemple mvn -Ptest

Pour gérer ces différents environnements, on créé autant de profils dans le fichier settings.xml qui se trouve dans $HOME/.m2

<settings>
[...]
<profiles>
<profile>
<id>dev</id>
<properties>
<mode>dev</mode>
</properties>
</profile>
<profile>
<id>recette</id>
<properties>
<mode>recette</mode>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<mode>test</mode>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<mode>prod</mode>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>
[...]
</settings>


Ainsi, chaque fois que l'on tape mvn -Pprod on utilise le profil de production. La configuration des plugin et un ensemble de propriétés d'éxécution sont définies à ce moment. Dans cet exemple on ne configure que les propriétés, ainsi la propriété mode est définie à dev quand on est dans l'environnement de développement.

activeProfile permet de déterminer le profil par défaut (dev)

Pour avoir des ressources différenciées, on peut se servir du filtering maven. Le filtering effectue des substitution lors des copies de ressources. Toutefois, il est plus commode lorsque les modifications sont importantes et portent sur des fichiers en entier d'avoir recours à des répertoires différentiés.
Ainsi on a la structure de répertoire suivante :

- main/resources/resources qui contient les resources communes

et

- main/resources/dev
- main/resources/test
- main/resources/recette
- main/resources/prod

qui contiennent les ressources spécifiques à des environnements.

On modifie le descripteur de projet en modifiantle pom.xml


   <build>
[...]
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/${mode}</directory>
</resource>
</resources>
[...]
<build>

Aucun commentaire: