28 September 2010

Desplegando con diferentes ficheros de configuración

Continuando con la cruzada maven + liferay....

Bueno, muchas veces, cuando desarrollamos, atacamos nuestra propia base de datos y utilizamos ficheros de propiedades para almacenar algunos de los parametros variables de la aplicación, evidentemente con las rutas y puertos de nuestra máquina; ahora bien, cuando desplegamos nuestra aplicación, en otro entorno que no sea el de desarrollo local, se nos presenta el problema de tener que modificar el paquete (jar, war, ear), con el fin de actualizar los valores de las propiedades, con aquellos correspondientes al entorno de destino.

Esto es algo que se puede controlar fácilmente, si utilizamos ANT o MAVEN.  En el caso de MAVEN, este dispone de un elemento llamado PROFILE y de un plugin llamado maven-antrun-plugin, cuya combinación nos permite generar los desplegables adecuados al entorno de destino de una forma fácil.

Pues bien el secreto de la receta se basa en:
  1. Tener tantos ficheros de propiedades como entornos de destino vayamos a tener ( config.properties, config.int.properties, config.pre.properties, config.pro.properties)
  2. Crear un perfil, por cada entorno de destino previsto, dentro de nuestro pom.xml, de preferencia con un nombre descritptivo, referente a su destino.
  3. Añadir el plugin maven-antrun-plugin en cada perfil para que borre los ficheros redundantes de configuración, y copie y renombre los necesarios.

He aquí un pequeño snippet de ejemplo, con "dos ficheros y un destino":

<profiles>
 ...
 <profile>
  <id>integracion</id>
  <build>
    <plugins>
       ...
 <plugin>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
   <execution>
    <phase>compile</phase>
    <goals><goal>run</goal></goals>
 
    <configuration>
     <tasks>
      <echo>------------------------------------------------</echo>
      <echo>COPIANDO LOS FICHEROS DEL ENTORNO DE INTEGRACION</echo>
      <echo>------------------------------------------------</echo>
      <delete
       file="${project.build.outputDirectory}/config.int.properties" />
      <delete
       file="${project.build.outputDirectory}/config.properties" />
      <copy
       file="src/main/resources/config.int.properties"
       tofile="${project.build.outputDirectory}/config.properties" />
     </tasks>
    </configuration>
    
   </execution>
  </executions>
 </plugin>
       ...
    </plugins>
  </build>
 </profile>
 ...
</profiles>

En este ejemplo, en un entorno normal se utilizará el fichero config.properties por defecto, y cuando invocamos la compilación y la generación del war no se hará nada especial.
Sin embargo, si, al compilar y generar el war indicamos que se debe ejecutar el perfil llamado "integracion", este borrará todos los ficheros de configuración de los entornos innecesarios y copiará únicamente aquel que necesita, renombrandolo a fin que pueda ser accedido por el código, en tiempo de ejecución, sin más complicaciones.

InputStream is = Configuracion.class.getResourceAsStream("config.properties");
Properties tmp = new Properties();
tmp.load(is);
Evidentemente a este último código le falta algún que otro try/catch.


Enlaces relacionados:
Building For Different Environments with Maven 2


- FIN -