Spring : Utiliser un unique fichier de configuration « .properties » pour plusieurs environnements.

Posted on avril 1, 2008. Filed under: Spring | Tags: |

Ce post expose une façon d’utiliser un seul fichier de configuration .properties pour plusieurs environnements.

Ce qui existe actuellement.

La méthode couramment utilisée consiste à définir un fichier de configuration par environnement :

database-${env}-config.properties

avec comme fichiers :

database-test-config.properties
database-integration-config.properties
database-production-config.properties

et ${env} prend donc les valeurs local,test,integration et production

En fonction de la valeur d’${env} le bon fichier de configuration est chargé en mémoire par Spring.

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="database-${env}-config.properties" />
</bean>

Par exemple le fichier de configuration « database-local-config.properties » contient les données suivantes :

database.url=jdbc:oracle:thin:@localhost:1521:XE
database.driverClassName=oracle.jdbc.driver.OracleDriver
database.user=XXXX
database.password=xxxx

Et le fichier « database-production-config.properties » les suivantes :

database.driverClassName=oracle.jdbc.driver.OracleDriver
database.user=YYYY
database.password=yyyy

La datasource exploitant ces informations serait alors définie comme-ci :

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${database.url}" />
<property name="driverClassName"
value="${database.driverClassName}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>

Or cela devient vraiment très pénible dès lors que la configuration diffère pour la base de données, mais aussi pour le serveur CVS, le système de fichier (Windows,Unix), etc.

Pour ne pas voir fleurir des dizaines de fichiers de configuration, je propose ci-dessous une solution me permettant d’avoir un unique fichier regroupant la configuration de la base de données et cela quel que soit l’environnement.

Se simplifier la vie.

Le fichier de configuration database-config.properties à exploiter est le suivant :

#local, test, intergation, production
environnement=local
 
 #default values
database.url=jdbc:oracle:thin:@localhost:1521:XE
database.driverClassName=oracle.jdbc.driver.OracleDriver
database.user=XXX
database.password=xxxx
#local values
local.database.url=jdbc:oracle:thin:@localhost:1521:XE
local.database.driverClassName=oracle.jdbc.driver.OracleDriver
local.database.user=XXXX
local.database.password=xxxx
#test values
test.database.url=jdbc:oracle:thin:@216.101.67.21:1521:TEST
test.database.driverClassName=oracle.jdbc.driver.OracleDriver
test.database.user=YYYY
test.database.password=yyyy
#integration values integration.database.url=jdbc:oracle:thin:@216.128.101.216:1521:INT
integration.database.driverClassName=oracle.jdbc.driver.OracleDriver integration.database.user=ZZZZ
integration.database.password=zzzz
#production values
production.database.url=jdbc:oracle:thin:@216.21.36.64:1521:PROD
production.database.driverClassName=oracle.jdbc.driver.OracleDriver
production.database.user=TTTT
production.database.password=tttt

Pour cela, nous allons créer une classe qui étend de org.springframework.beans.factory.config.PropertyPlaceholderConfigurer et qui surcharge la méthode :

protected String resolvePlaceholder(String placeholder, Properties props) {...}

Dans notre cas, la règle à appliquer est la suivante :

Si la chaine placeholder débute par « database » alors il faut rechercher la propriété ${environnement}+ « .» + placehorlder.

De cette façon, lorsque nous allons utiliser ${database.url} dans notre datasource, nous allons en fait appeler ${local.database.url} (car environnement = local tout en haut du fichier de configuration).

@Override
protected String resolvePlaceholder(String placeholder, Properties props) {
try{
if(placeholder.startsWith("database")){
return  props.getProperty(props.getProperty("environnement")+"."+placeholder);
}
}catch(Throwable t){
log.error("Impossible de trouver "+ placeholder + "pour l'environnement "+props.getProperty("environnement") ) ;
}
// default operation
 
 return super.resolvePlaceholder(placeholder, props);
 
 }

Pour changer d’environnement, il suffit de modifier la ligne suivante du fichier de configuration :

#local, test, intergation, production
environnement=production

Dans cet exemple, ${database.url} fera référence à ${production.database.url}

Pour que cela fonctionne, il suffit de remplacer la précédente définition du propertyConfigurer

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="database-${env}-config.properties" />
</bean>

Par la suivante :

<bean id="propertyConfigurer"
 class="fr.monprojet.config.MyPropertyPlaceholderConfigurer">
<property name="location" value="database-config.properties" />
</bean>

Cette méthode me permet de centraliser les informations relatives aux bases de données, mais aussi aux serveurs CVS/SVN, et à tout autres dispositifs susceptibles de varier suivant les environnements.

Make a Comment

Make A Comment: ( None so far )

blockquote and a tags work here.

Liked it here?
Why not try sites on the blogroll...