Mondrian con OLEDB for OLAP 9.0. ¡Por fin se por qué no funciona!

Sin que sirva de precedente, voy a romper una promesa y antes de contaros por qué es tan importante el XML/A, voy a desvelaros el resultado de mis quebraderos de cabeza con Mondrian. Al final, tras mucho indagar, parece que el cliente OLE DB for OLAP 9.0 no funciona con Mondrian por el siguiente motivo:



  • Si la base de datos es SSAS en lugar de Mondrian, el cliente primero intenta establecer una conexión XML/A. Para eso, manda un comando EXECUTE vacío. SSAS le devuelve una respuesta XML/A que contiene un elemento «root» que a su vez está vacío, pero todo esto sirve para iniciar una sesión SOAP (ver los tag en petición y respuesta). A partir de aquí, el resto de mensajes XML/A llevan ese código de sesión. Al parecer, las sesiones SOAP son la base para conseguir que el funcionamiento del acceso a SSAS sea transaccional.


En cambio, con Mondrian pasa lo siguiente:



  • Mondrian devuelve correctamente la respuesta XMLA con el tag ROOT vacío… pero sin embargo, la respuesta SOAP no lleva el inicio de sesión en la cabecera (debe ser un error de Mondrian, porque J2EE sí que soporta sesiones SOAP) : 



  • Entonces, como el cliente no obtiene la respuesta esperada (no consigue iniciar una sesión), trata de realizar una conexión ODBO. Concatena «msolap.asp» a la URL del servlet XMLA de Mondrian y manda una petición ODBO. Lógicamente, como la URL no existe, Tomcat devuelve un error 404 (que es una página web, y no una respuesta ODBO). En ese punto, el cliente OLEDB devuelve un error a la aplicación. Conclusión… no tiene demasiada buena pinta… no parece que Mondrian soporte transacciones XML/A, y a lo mejor es ese precisamente el problema.


Para más información, os recomiendo que leais:


ODBO, XMLA y OLEDB for OLAP 9.0

La verdad es que pocos días me siento tan excitado como hoy. Hay veces que la información que se lee en Internet puede ser contraproducente, y me temo que he sido víctima de una de estas confusiones… ¿y dónde está la confusión? Bien… creo que será mejor que comience la historia desde el principio.
Llevaba días tratando de conectar mi base de datos Mondrian a los Office Web Controls sin éxito. ¿Por qué? Tratando de investigarlo, lei que los Office Web Control son clientes ODBO (OLE DB for OLAP) y que este es un protocolo binario y propietario de Microsoft, específicamente concebido para conectarse a Analysis Services. Bueno, esta es una verdad a medias… porque hay proveedores ODBO para otras bases de datos (por ejemplo SAP), pero esa es otra historia. Para conectar un cliente ODBO a una base de datos XMLA, es al parecer necesario un puente: el Simba O2X (http://www.simba.com/odbo-to-xmla.htm). Además, en la propia página de Simba, leí que Simba O2X no funciona con Mondrian, y que para Mondrian se está desarrollando un proyecto específico bajo el nombre de «Pentaho Spreadsheet Services» (todavía no está disponible). Vaya por Dios… Leoncio, nunca lo conseguiremos. Ya teníemos servido el clásico problema de la interoperatividad (parece mentira que pasen los años que pasen, la informática siempre se acabe enfrentando a los mismos problemas y tropezando con las mismas piedras, ¿verdad?). ¿Así que tendría que esperar a Pentaho Spreadsheet Services? Soy un ser de naturaleza impaciente… y necesitaba otra respuesta. ¿Cómo es posible que los Office Web Controls y Analysis Services no hablen el mismo idioma?
Al más puro estilo de Hollywood, me puse a espiar las conversaciones entre los Office Web Controls y Analysis Services… ¡y no podía ser! ¡Se veía XML! Bueno, todo hay que decirlo… antes de espiar este diálogo, configuré mi Analysis Services 2005 para permitir el acceso a través de HTTP, así que SQL Server y los OWC estaban hablando por HTTP, y yo estaba ahí, agazapado, escuchándolos. Entonces fue cuando vi el XML. Por cierto, para hacer accesible SQL Server Analysis Services a través de HTTP, sólo tienes que seguir estos pasos:
http://www.microsoft.com/technet/prodtechnol/sql/2005/httpssas.mspx
¿Qué significaba ese XML que NO debía estar ahi? ¿Acaso el ODBO se encapsula en XML cuando se transporta a través de HTTP?
Os voy a desvelar las respuestas….


  • El cliente OLE DB for OLAP de Analysis Services 8.0 usa un protocolo binario. Si la conexión a Analysis Services se realiza a través de HTTP, a la URL que se le proporcione al cliente OLE DB, se le añade la página «msolap.asp» y a ésta página, se postean los mensajes en un formato binario. El user Agent con el que se identifica el cliente es «Light DCube».



  • El cliente OLE DB for OLAP de Analysis Services 9.0 es nativo XMLA al menos cuando habla con Analysis Services 9.0. Eso significa que en teoría, los Office Web Controls conectándose a través del cliente OLE DB 9.0, deberían poder hablar directamente con cualquier base de datos XML/A (por ejemplo Mondrian)

En la práctica no he conseguido comunicar Mondrian con los Office Web Controls, probablemente porque el soporte XMLA de Mondrian 2.1.1 no es tan completo como el de Analysis Services, pero el simple hecho de descubrir que el proveedo OLE DB for OLAP de Analysis Services 9.0 habla XMLA, me ha alegrado el día. Lo cierto del caso es que en ningún sitio pone que el cliente OLE DB sea XMLA… siempre se da como referencia de cliente XMLA el ADOMD.NET, de hecho en muchos sitios hablan de ADOMD como cliente XMLA y OLE DB como cliente ODBO. Pues bien, ¡ahora ya sabéis que también las aplicaciones que utilizan clientes OLE DB pueden comunicarse a través de XMLA! Si alguien de Microsoft me lee y estoy equivocado, por favor que desmienta esta barbaridad… bueno, o que la confirme. Los que sepáis de qué hablo, os alegraréis porque es una gran noticia. Los que todavía os estéis preguntando por qué me siento tan feliz hoy, tendréis que esperar a mi próximo post, que os adelanto que se titulará «XML/A es tu amigo».

Compilando Mondrian (2ª parte)

«last updated July, 2005». Así comienza el documento titulado «Guide for Mondrian developers» (http://mondrian.sourceforge.net/developer.html). Para que os hagáis una idea, los binarios de Mondrian 2.0.1 están compilados en diciembre de 2005, y los de Mondrian 2.1.1 el 30 de mayo de 2006. Si es que la documentación no sirve para nada si no se actualiza… Llevo varios días tratando de compilar Mondrian usando este documento, y de momento he descubierto ya los siguientes errores:
  • En la documentación menciona que se debe establecer la variable de entorno «TOMCAT_HOME», apuntando al directorio de instalación de Tomcat. Sin embargo, en el «build.xml» para el ANT se aprecia que la variable de entorno de la que se obtiene el path de TOMCAT debe ser «CATALINA_HOME», y no «TOMCAT_HOME».
  • Hay un archivo BAT (indocumentado) llamado «build.bat», que aparentemente establece el CLASSPATH para que se pueda compilar Mondrian sin problemas… sin embargo, no funciona si el ANT se ha instalado en un directorio que contenga espacios (por ejemplo, si cuelga de «program files»). El fallo es fácil de corregir; sólo hay que poner unas comillas en la línea que lanza «ANT.EXE» al final del script. Sin embargo, a pesar de esta corrección, el build.bat sigue sin funcionar… así que lo he descartado y he seguido los pasos que indica la documentación (lanzar directamente el ANT).
  • A pesar de que leáis lo contrario en muchos sitios, con Mondrian 2.1.1 se debe usar XALAN 2.7, y NO 2.6. En muchos sitios se indica que se debe usar Xalan 2.6, pero esta información es válida sólo para Mondrian 2.0.1. En la documentación de Mondrian, para variar, no se da ninguna información al respecto. Este detalle es importante, porque la jerarquía de paquetes de Xalan 2.6 y 2.7 es totalmente distinta. Hay que usar el paquete correcto para evitar las «ClassNotFoundException».
  • Tampoco se menciona cual es el CLASSPATH que se debe utilizar para compilar Mondrian… por el método de ensayo y error, y gracias a la página «http://www.jarfinder.com/» (no se qué sería de mi sin ella), de momento he llegado a la conclusión de que deben añadirse al Classpath:
    • xml-apis.jar (es parte de la distribución de XALAN)
    • xercesImpl.jar (es parte de la distribución de XALAN)
    • javacup.jar (viene con el propio Mondrian, pero por algún extraño motivo, hay que meterla explícitamente en el CLASSPATH).
    • commons-math-1.1.jar (hay que descargársela del proyecto Jakarta). Con Mondrian ya viene la commons-math-1.0.jar, pero a mi al menos, no me funciona con esta librería. De nuevo, parece que el proyecto usa clases que no están en esta versión de la librería… así que conviene actualizarla.
  • Si os estáis tratando de compilar el paquete «ZIP» de Mondrian que se descarga de Sourceforge, tened en cuenta que le falta un archivo que resulta crítico: %MONDRIAN_HOME%srcmainmondrianrolapaggmatcherDefaultRules.xml. Descargadlo del sistema de control de fuentes Perforce, porque es imprescindible. De todas formas, es conveniente que se descargue TODO del Perforce, porque en el ZIP de la distribución faltan un montón de archivos (practicamente todas las queries que se utilizan en los tests unitarios).
  • Es recomendable usar JDK 1.5 y Tomcat 5.5 (aunque también funciona con JDK 1.4 y Tomcat 5.0, el parser XML de JDK 1.5 aparentemente corrige el bug relacionado con el «Byte Order Mark» que os comentaba en mi post anterior).
Siguiendo los pasos de la guía de Mondrian, y con estas notas que os he indicado, probablemente consigáis compilarlo (a mi al menos me han funcionado). Eso sí, si habéis partido de los fuentes descargados desde SourceForge, veréis que 71 tests unitarios fallan. No os empeñéis en intentar pasar los tests con esta versión… sencillamente, jamás funcionarán debido a que a la distribución de Mondrian 2.1.1 de Sourceforge le faltan 71 archivos (además del ya mencionado «DefaultRules.XML»). Yo os recomiendo que partáis de los fuentes directamente descargados del servidor de control de fuentes Perforce que ofrece el equipo Mondrian.
Para compilar los tests unitarios, tenéis que tener en cuenta que además de los pasos que se indican en la guía para desarrolladores, necesitaréis:
  • jUnit versión 3.8.x (con la 4.x no funciona). El JAR correspondiente debe añadirse al Classpath.
  • XMLUNIT 1.0. El JAR del XMLUnit debe estar en el CLASSPATH.
Con estos pasos ya deberíais poder compilar vuestras propias versiones de Mondrian. Para además de compilar, poder ejecutarlo de forma controlada y poder depurar lo que está pasando, os recomiendo que creeís un proyecto Eclipse partiendo del «build.xml» de Mondrian. Hay infinidad de páginas que enseñan a depurar servlets de Tomcat con Eclipse… os recomiendo esta: http://javaboutique.internet.com/tutorials/three/index.html

Compilando Mondrian (1ª parte)

Estamos desarrollando una aplicación que debe funcionar sobre bases de datos Oracle y SQL Server. La aplicación estará hecha en .NET… y aquí es donde comienzan todos mis problemas. No comprendo la estupidez de Oracle al cerrarse al estándar XMLA, pero esa es otra historia como para empezar un nuevo post. El caso es que se nos ha ocurrido usar Mondrian como una capa ROLAP con una interfaz XMLA que nos permita usar ADOMD desde nuestra aplicación .NET. Pues bien: ya llevo dos semanas con ello y cada vez estoy más desesperado.
La documentación de Mondrian es pésima y plagada de errores. He conseguido poner en marcha Mondrian 2.0.1, y me he llevado la desagradable sorpresa de que:

El caso es que quiero probar Mondrian 2.1.1, a ver si mejora el soporte XMLA. El problema de Sun lo resolveremos probablemente parcheando Mondrian para que ignore el BOM en los mensajes SOAP (eso que parece una chapuza, es la solución que recomienda Sun… es vergonzoso). Bueno, a lo que vamos… No he conseguido que la distribución binaria de Mondrian funcione en lo referente a XMLA (da una excepción «unable to internalize SOAP message»). Tras volverme loco tratando de poner en marcha la distribución binaria (sin éxito) llegué a la conclusión de que tal vez depurando Mondrian conseguiría ver algo, y para eso, el primer paso es compilar Mondrian.

Pues aquí me tenéis, compilando Mondrian. Ahora mismo compila, pero no pasa los tests unitarios… en serio, creedme que Mondrian es la cosa más desordenada que he visto en mi vida. En ningún sitio se indican las versiones adecuadas de las librerías que se deben usar en su compilación, apenas hay información en Internet, hay librerías que estoy viendo que son necesarias y de las que en los documentos ni siquiera se menciona su existencia, archivos que faltan y hay que bajárselos directamente del sistema de control de fuentes… en fin, a años luz de cualquier proyecto comercial (incluso a años luz de Oracle).

Ya os iré contando…

A ver si saco un ratillo y escribo un «howto» sobre cómo compilar Mondrian 2.1.1… bueno, ¡si consigo que pase los tests unitarios tras la compilación!

Reflexiones sobre la dimensión Tiempo

Hoy he estado trabajando corrigiendo la dimensión “tiempo” de uno de mis cubos para Analysis Services 2005. Resulta que ayer, escribiendo unas queries MDX, me di cuenta de que para analizar si determinado patrón se produce siempre en una determinada época del año (por ejemplo, queremos comparar las ventas realizadas durante toda la época de rebajas) lo tenemos complicado si sólo disponemos de la dimensión “tiempo”. Me explico

Supongamos que queremos estudiar la evolución de las ventas durante los meses de rebajas. Si partiésemos de un cubo en el que una de las dimensiones fuese “promociones” y la otra fuese el “tiempo”, el tema estaría chupado… ¿no? Bastaría con seleccionar las ventas por meses y filtrar para “[promociones].[rebajas]”. Lo que pasa es que no siempre tenemos esa segunda dimensión por la que filtrar, y muchas veces nos vemos obligados a filtrar en función del nombre del mes. Eso es exactamente lo que quería hacer ayer… filtrar la ocurrencia de un determinado evento todos los meses de verano. Lo curioso es que la expresión MDX que me surgió, resultó ser mucho más complicada de lo que esperaba: ¡me obligó a escribir un set en el que se agrupaban los meses de verano! Eso es básicamente porque las dimensiones son jerárquicas, y uno siempre se encuentra problemas si quiere obtener todos los hechos referentes a un valor que se repite a lo largo del mismo nivel de la dimensión. Por ejemplo:

  • 2001
    • Trimestre 1
    • Trimestre 2
    • Trimestre 3
    • Trimestre 4
  • 2002
    • Trimestre 1
    • Trimestre 2
    • Trimestre 3
    • Trimestre 4

Si queremos obtener las ventas del conjunto de “Trimestres 3” a lo largo de todos los tiempos, tenemos que andar escribiendo sets, o realizando filtrados chapuceros en función del nombre del mes. Sin embargo, si el conjunto estuviese ordenado de la siguiente forma:

  • Trimestre 1
    • 2001
    • 2002
  • Trimestre 2
    • 2001
    • 2002
  • Trimestre 3
    • 2001
    • 2002
  • Trimestre 4
    • 2001
    • 2002

El problema tendría una solución muchísimo más sencilla.

No se si equivocadamente o no, he adoptado la solución de añadir los dos niveles de jerarquías en mi dimensión tiempo… uno con agregación MOLAP y el otro (menos común) con agregación ROLAP. Más que nada, de esta forma la estructura es mucho más rica en metadatos, y le puede ayudar al analista a adoptar uno u otro tipo de análisis. Sin embargo, me marcho a la cama sin poder olvidar este problema… y es que sin duda, la solución ideal hubiese sido tener una segunda dimensión por la que filtrar. Vamos, sin ninguna duda.

Que importante es estudiar muy bien las dimensiones sobre las que vamos a querer realizar futuros estudios…

En fin, si alguien piensa que lo que he hecho es una animalada, que no dude en contestarme. Yo seguiré reflexionando sobre el problema… no puedo dejar de pensar que tiene que haber soluciones más sencillas al problema.