miércoles, 11 de enero de 2017

De como enviar mail que contiene datos en el cuerpo del mensaje

Podria parecer que resulta fácil enviar un mail des de Pentaho DI con información relevante, pero de hecho, no lo es tanto. Si que es sencillo enviar un mail con el cuerpo relativamente fijo y un fichero adjunto con datos pero si queremos que los datos aparezcan en el propio cuerpo del mensaje eso ya es otra historia.
Para empezar el mail hay que enviarlo desde una transformación, puesto que los datos los calculamos a nivel de transformación. Si que disponemos de un step para enviar mails, pero no es conveniente pasarle mas de un registro con información, puesto que si lo hacemos, enviará un mail por cada registro, por lo que nos podemos encontrar con el buzón de correo lleno, cuando no bloqueado con un mail por cada registro.
Entonces, voy a proponer una solución, que admito que algo rebuscada es, pero que funciona (si alguien tiene alguna idea mejor que lo diga):

Primer step: Table Input


El objetivo básico es recoger los datos que deseamos enviar en el mail y combinarlos de alguna manera para que se conviertan en un solo registro y por tanto en un solo mail. Una de las formas mas adecuadas de presentarlos seria mediante una tabla HTML. Seguro que hay mas formas pero esta resulta perfecta para presentar varios registros. En mi caso he usado el Table Input para recoger los datos de una tabla que quiero enviar por mail. Para convertir varios registros en uno solo he usado la siguiente estrategia: La select constará de, como mínimo:
1. Dividir la select en 3 selects unidas con "union all": una select para la cabecera , otra para el cuerpo y otra para el pie, 
2. La primera select constarà de los tags de inicio HTML, un texto si queremos antes de la tabla i la cabecera de la tabla con los títulos de los camps.

 select 'A' id, '<html><body>el texto que queramos independiente de la tabla</br></br><table border=''1''><tr><th>TITULO CAMPO 1</th><th>TITULO CAMPO 2</th></tr>' mail_body from dual
3. La segunda select constarà de los datos, concatenando tags de html antes y despues de cada campo.

 union all
select 'A' id,'<tr><td>' || c.campo1 || '</td><td>' || c.campo2|| '</td></tr>' mail_body
from
tabla c
where
...
4. La tercera constarà de los tags HTML para cerrar la tabla y el fichero.
Podemos añadir mas selects con mas texto uniendolas entre si. 

 union all
select 'A' id,'</table></br></body></html>' mail_body from dual

Eso si, cada select debe tener como mínimo dos campos, uno que sea constante, por ejemplo un texto, y otro con las concatenaciones de HTML y campos de información.
Ese campo constante veremos luego para que lo necesitamos.


Segundo step: Group by


El campo constante de la select nos servirá como referencia sobre el cual agruparemos el otro campo usando el step group by. Usaremos el tipo de agrupación Concatenate strings separated by:


Tercer step: Get Variables


Este paso no es realmente necesario. Es, sin embargo, una buena práctica el guardar los datos de conexiones, de servidores y en este caso, del servidor de mail, en variables que se instancian en un fichero kettle.properties y se cargan al iniciar el spoon. Pero eso ya es otra historia que será contada en otra ocasión. El caso es que el step de mail necesita datos de conexión del servidor de mail que no se pueden indicar directamente mediante variables en el step mismo, así que antes tengo que capturar el valor de las variables y guardarlos en campos.


Cuarto step: Send Mail


En este paso configuramos el mail que queremos enviar, definimos la conexión al servidor de correo, le indicamos que el cuerpo del mensaje lo contiene el campo MAIL_BODY que construimos en los steps anteriores, le adjuntamos un archivo si deseamos y listo!







jueves, 21 de marzo de 2013

Concatenar cadenas

Hay varias opciones para concatenar cadenas en una transformación con Spoon. Aunque hay que admitir que no son del todo obvias.
La primera opción és utilizar el paso Calculator. Con la operación A+B, si los campos A i B son cadenas el resultado será la concatenación de las mismas.
 Definimos un step Data Grid con dos campos:


Definimos un step calculator con la suma de los dos campos que almacenaremos en el nuevo campo CAMPO_HOLA_MUNDO:


El resultado que obtenemos en una previsualización és el siguiente:


Como vemos, la suma de dos strings és la concatenación.


Otra opción és usar un paso JavaScript. Nuevamente al sumar dos variables de tipo String, obtendremos la concatenación. 
Cambiamos el step calculator por un step Java Script :

 Editamos el step tal como indica la figura siguiente:



Como vemos cuando probamos el script el resultado és el mismo.

viernes, 15 de marzo de 2013

Como hacer tests en Pentaho Data Integration (Parte II)

Ahora tocaría llevar a la práctica la teoría explicada en el anterior post. Pero como no es posible tratar las particularidades de cada caso, vamos a dar solo unas pinceladas, sin entrar en detalles.
Tal como expliqué en el anterior post, para no inventar de nuevo la rueda, nos basaremos en el proyecto TestKitchen, cuyo código fuente usaremos como base para nuestro sistema. Por tanto, conseguiremos ese código fuente añadiendo a nuestro IDE favorito el repositorio Subversion que nos ofrece la página del proyecto: http://code.google.com/p/testkitchen/source/checkout .Con el checkout correspondiente obtendremos el código en nuestro workspace local.
Una vez tenemos el código podemos ver que tiene las siguientes partes:



El primer nivel del proyecto está formado por las carpetas bin, dist y src. En src encontraremos el código fuente del proyecto. En dist encontraremos un espacio de trabajo donde poner nuestros proyectos de test y bin permanecerá vacio. En la raiz tenemos el build.xml y demás ficheros de configuración que nos permiten compilar el proyecto. Vamos allá.
Para ello necesitamos instalar apache-ant en nuestro sistema. Vamos a su página web y descargamos la versión mas reciente. http://ant.apache.org/

Una vez instalado (establecido las variables de entorno PATH y demás) podemos empezar a probar la compilación. Para ello configuramos el IDE para ejecutar ant para este proyecto, o bien, desde un terminal nos situamos en la carpeta raiz del proyecto (donde esta el build.xml) i ejecutamos:

> ant jar

El compilador gracias a ivy, buscará las dependencias y descargará aquellos paquetes que sean necesarios. Es probable que aparezcan errores por dependencias insatisfechas. Es aquí donde hay que ajustar los ficheros de dependencias para que nos baje aquellos paquetes que necesitemos o añadir las dependencias que sean necesarias en nuestro caso específico. Aquellos que no encuentre quizás tengamos que añadirlos a mano, como por ejemplo el driver jdbc de Oracle. En mi caso, modifique el código fuente, la clase KitchenTestCase que tiene métodos para ejecutar las transformaciones y trabajos de Pentaho. Por ejemplo, las transformaciones y trabajos que queremos testear estan en la carpeta dist/ETL/ .Podemos modificar el código para que los busque en otra carpeta, o incluso en un repositorio de kettle de bd.
Una vez compilado (no sin muchos problemas) empezamos a crear nuestro proyecto de test. Para ello nos situamos en la carpeta dist i ejecutamos el siguiente comando:

 ant -Dproject=<nombre del proyecto> create-project

Esto nos creará una subcarpeta con el nombre del proyecto en la carpeta dist/projects. En su interior tendremos las carpetas:
  • datasets
  • deltas
  • tests

En datasets tendremos que poner los ficheros XML con datos de prueba y datos de comprobación.
En deltas pondremos scripts SQL de preparación de bd.
En tests pondremos las clases que realizaran los tests unitarios.

A su vez, en la carpeta dist/ETL/ se crea una subcarpeta con el nombre del proyecto donde pondremos las transformaciones (ktr) y los trabajos que deseamos testear.

Editamos los ficheros XML con datos de prueba que serviran de entrada a nuestra transformación. Cada tag corresponde a un registro de entrada y lleva por nombre el nombre de la tabla, y sus atributos corresponden a los valores que adoptan los campos de ese registro.
Tambien creamos un XML con los datos esperados, del mismo modo que el anterior pero correspondiente a la tabla de salida de la transformación.
Creamos una clase heredada de KitchenTestCase con el nombre terminado en Test y modificamos aquello que sea necesario. Por ejemplo, los nombres de ficheros, las cargas de los mismos, las conexiones a la base de datos. Por mi parte he decidido no utilizar jndi y sustituirlo por una conexión jdbc normal.
 Una vez preparado, para pasar el test ejecutamos el siguiente comando:

 ant -Denv=test -Dproject=<nombre del proyecto>

Nos devolverá el resultado del test. ¿Que ha sucedido?. La classe <nombre>Test tiene varios métodos:
  • Initialize: En este método utilizamos métodos de dbdeploy para cargar la tabla de entrada de la bd, que nuestra transformación usarà, con los datos del fichero XML. Ejecuta la transformación o el job usando métodos de la API de Kettle. Esto nos pondra en la tabla de salida los resultados de la ejecución de la transformación o el trabajo.
  • test<nombre transformacion>: Carga el fichero de datos de comprobación y los compara con el resultado de ejecutar el trabajo/transformación.
Como he dicho antes, no pretendo entrar en detalles concretos, puesto que cada caso particular requiere modificaciones concretas, y sin duda, tendreis que pelearos con mas o menos problemas para que todo funcione.

jueves, 21 de febrero de 2013

Como hacer tests en Pentaho Data Integration (Parte I)

Es cierto que no es el tema más asequible y, por ello, no el mas adecuado para tratarlo en el primer post de este blog, pero, como dice aquel, "la ocasión la pintan calva". Así que, a aquellos que acaban de empezar con el Kettle, no les recomiendo esta entrada. Digamos que se situaría en un nivel avanzado. Estoy hablando de hacer tests a nuestras transformaciones y jobs creados con PDI.

Cuando llevas un cierto tiempo desarrollando con PDI, tus transformaciones empiezan a parecer arboles de gran tamaño, de los que salen múltiples ramificaciones. Usas con asiduidad bifurcaciones de flujo. Tus datos fluyen por un camino u otro de tu transformación, en función de valores que recoges por el camino de otras fuentes de datos,o bien son resultado de cálculos intermedios. Entonces aparecen los bugs, y no me refiero a errores de ejecución (esos ya los detecta el propio spoon), sino a resultados equivocados, inesperados y inapropiados.

Es en este punto que aparece la necesidad del test. Y empiezas a buscar por internet deseando encontrar el Santo Grial de los test para el PDI. Pronto te das cuenta que no existe. Y también te das cuenta que hay mas gente como tu, que llenos de iniciativa e ingenio se han montado sus propios sistemas "de ir por casa" pero que a ellos les funcionan. Uno de estos proyectos es el Testkitchen que podéis encontrar aquí. Si bien carece casi completamente de documentación y , como dice su autor, está desactualizado, me ha servido como punto de partida para empezar a experimentar con tests en PDI.

El testkitchen es un proyecto escrito en Java que utiliza los frameworks dbunit, dbdeploy y las librerías de kettle combinados para proporcionar un entorno de tests unitarios a las ETL de Pentaho. La idea es la siguiente: Supongamos que queremos probar una transformación que tiene como input unos datos guardados en una tabla A, realiza unos determinados cálculos con esos datos y finalmente arroja el resultado en otra tabla B. Escribimos un fichero XML (mock_data) que contenga los datos de la tabla origen A y otro XML con los datos que esperamos encontrar en la tabla B de resultados (golden_data). 
Testkitchen, mediante dbdeploy, rellena la tabla origen A con los datos de ese XML. A continuación ejecuta la transformación mediante una llamada a un método de la API de Kettle. Como consecuencia de la ejecución, se llena la tabla de resultados B. Testkitchen carga esos datos y, mediante dbunit, los compara con los almacenados en el fichero XML. Si el resultado és el mismo podemos garantizar que nuestra transformación funciona correctamente (al menos con el conjunto de test que hayamos preparado). Si no, es que se algo no ha funcionado como esperábamos.
Sin pensarlo demasiado podemos llegar a creer que no tiene demasiada gracia. Al fin y al cabo solo se trata de comparar resultados. Pero la ventaja radica en que este proceso es automático y eso quiere decir que se puede ha de repetir tantas veces como convenga, sobre todo cuando cambiamos algo en nuestra transformación. Cuantas mas veces se cambie, mas sentido tiene el asunto. Pensad que la alternativa implica comprobar los resultados a mano. Lo cual resulta tedioso y propenso al error humano.



sábado, 2 de febrero de 2013

Step 1: Introducción

En la vida de toda persona humana que, en su quehacer diario se pelea con datos, ya sea moviendolos, copiandolos, formateandolos, transformandolos, hay un antes y un despues de "toparse" con la herramienta Pentaho Data Integration que forma parte de la suite Pentaho Business Intelligence. 
En el despues te embarga la sensación de que el mundo es tuyo, de que ya no hay nada que no puedas hacer (siempre dentro de este ámbito claro). Y no deja de ser cierto. Sin embargo, como iremos comprobando, no debemos dejarnos llevar por la euforia y el fanatismo. Debemos aprender a distinguir entre, aquello para lo cual és más adecuado usarla, aquello para lo cual, si bien se podria usar, es mejor usar otros métodos, y finalmente aquello para lo que resulta del todo imposible o inadecuada.
Cuando piensas en el antes, te preguntas como demonios podia hacer segun que sin tener esta herramienta y cuanto costaba hacerlas.
Y es por eso que esta herramienta merece este blog entero. Creo que es justo que la gente conozca esta herramienta que puede facilitar la vida y el dia a dia de muchos profesionales.