Tips, Soluciones y Novedades en Tecnología

26/09/2015

Pentaho – solutions


En este post veremos un servicios de pentaho y como sacar provecho de ello para poder integrarlo en nuestra aplicación empresarial

para ello tenemos que analizar  un servicio especifico:

 

/pentaho/SolutionRepositoryService

 

este servicio tiene una serie de parámetros que espera recibir al ser llamado.

  • component: getSolutionRepositoryDoc
  • component: getAcl
  • component: setAcl
  • component: createNewFolder
  • component: delete

 

por cada tipo de componente que queremos solicitar hay otros parámetros que debemos enviar

getSolutionRepositoryDoc         userid password
getAcl solution path filename   userid password
setAcl solution path filename aclXml userid password
createNewFolder solution path name   userid password
delete solution path name   userid password

 

Paso 1: Listar el repositorio de pentaho: pentaho/SolutionRepositoryService?component=getSolutionRepositoryDoc &userid=xx&password=xxx

el resultado es en formatto xml.

 

<?xml version="1.0" encoding="UTF-8"?><repository path="/pentaho-solutions" product-id="POBS" version-build="49886" version-major="4" version-milestone="stable" version-minor="5" version-relase="0">
    <file description="Links for updating the system settings and web service examples" isDirectory="true" lastModifiedDate="1433353698531" localized-name="Admin Services" name="admin" visible="false">
        <file description="Tools for the content Repository" isDirectory="true" lastModifiedDate="1433353698529" localized-name="Content Repository Admin" name="Content" visible="false"/>
        <file description="resources" isDirectory="true" lastModifiedDate="1433353698533" localized-name="resources" name="resources" visible="false">
            <file description="metadata" isDirectory="true" lastModifiedDate="1433353698553" localized-name="metadata" name="metadata" visible="false"/>
        </file>
        <file description="Removes files from the content repository that are more than 180 days old." isDirectory="false" lastModifiedDate="1335477348000" localized-name="Clean Repository" name="clean_repository.xaction" param-service-url="/pentaho/ServiceAction?solution=admin&amp;path=&amp;action=clean_repository.xaction&amp;component=xaction-parameter" url="/pentaho/ViewAction?solution=admin&amp;path=&amp;action=clean_repository.xaction" visible="true"/>
        </file>
    <file description="cdb" isDirectory="true" lastModifiedDate="1436830518047" localized-name="cdb" name="cdb" visible="false">
        <file description="queries" isDirectory="true" lastModifiedDate="1436830518077" localized-name="queries" name="queries" visible="true"/>
        <file description="saiku" isDirectory="true" lastModifiedDate="1436830518013" localized-name="saiku" name="saiku" visible="true"/>
    </file>
    <file description="CDE" isDirectory="true" lastModifiedDate="1443127490702" localized-name="cde" name="cde" visible="true">
        <file description="components" isDirectory="true" lastModifiedDate="1437605131147" localized-name="components" name="components" visible="true"/>
        <file description="widgets" isDirectory="true" lastModifiedDate="1437605131393" localized-name="widgets" name="widgets" visible="true">
            <file description="" isDirectory="false" lastModifiedDate="1437605131329" localized-name="SampleWidget" name="sample.wcdf" url="/pentaho/content/pentaho-cdf-dd/Render?solution=cde&amp;path=widgets&amp;file=sample.wcdf" visible="true"/>
        </file>
    </file>
</repository>

 

  Para como se puede apreciar el xml contendrá todos los archivos y carpetas del repositorio de pentaho

y las propiedades son las siguientes:

  • lastModifiedDate
  • name
  • localized-Name
  • param-service-url
  • url
  • isDirectory
  • isVisible

Siguiendo los nodos y con estos parámetros podemos diferencias si son carpetas o archivos.

 

Ahora supongamos que en la vista nuestro frontend utiliza JSON, acá tendremos una trabajito de procesar este xml y pasarlo a json, filtrando solo los archivo y carpetas visibles

al repositorio.

un resultado en JSON considero necesario para tener todo a la mano seria este JSON.

 

{
    "data":
            [
                {
                    "localizedName": "Testing",
                    "visible": true,
                    "isDirectory": true,
                    "description": "Testing",
                    "name": "Testing",
                    "path": "",
                    "children": [{
                            "localizedName": "saiku",
                            "visible": true,
                            "isDirectory": true,
                            "description": "saiku",
                            "name": "saiku",
                            "path": "",
                            "children": [{
                                    "localizedName": "miarchivo",
                                    "visible": true,
                                    "isDirectory": false,
                                    "description": "",
                                    "name": "miarchivo.saiku",
                                    "path": "saiku",
                                    "editUrl": "/pentaho/content/saiku-ui/index.html?solution=Testing&path=saiku&action=miarchivo.saiku&dimension_prefetch=false&mode=edit&biplugin=true#query/open/miarchivo.saiku",
                                    "lastModifiedDate": "1442801950932",
                                    "param-service-url": "",
                                    "leaf": true,
                                    "type": "saiku",
                                    "solution": "Testing",
                                    "url": "/pentaho/content/saiku-ui/index.html?solution=Testing&path=saiku&action=miarchivo.saiku&dimension_prefetch=false&mode=view&biplugin=true#query/open/miarchivo.saiku"
                                }],
                            "lastModifiedDate": "1442806447920",
                            "expanded": false,
                            "solution": "Testing"
                        }],
                    "lastModifiedDate": "1442801913318",
                    "expanded": false,
                    "solution": "Testing"
                }]
    ,
    "success": true,
    "expanded": false
}

Con este JSON, ya podemos construir un TreePanel en cualquier framework javascript

image

Las extensiones en pentaho son:

Set<String> map = new HashSet<>();
       map.add("saiku");
       map.add("prpt");
       map.add("xcdf");
       map.add("wcdf");
       map.add("adhoc");
       map.add("xaction");
       map.add("waqr");

con ello podemos colocar un icon en función al tipo.

 

PASO 2 :  Crear una carpeta en el repositorio de pentaho :

  pentaho/SolutionRepositoryService?component=createNewFolder&solution=SOLUTION&path=PATH&name=NAME &userid=xx&password=xxx

      

al realizar esta peticion se recibirá un mensaje en XML

  <result>true</result>  si se creo correctamente la carpeta

 y  <result>false</result> si no pudo crearlo

 

interpretamos este resultado y enviamos al cliente.

 

PASO 3:  Eliminar un archivo o carpeta del repositorio de pentaho

  pentaho/SolutionRepositoryService?component=delete&solution=SOLUTION&path=PATH&name=NAME &userid=xx&password=xxx

al realizar esta peticion se recibirá un mensaje en XML

  <result>true</result>  si se elimino

 y  <result>false</result> si no pudo eliminarlo

 

interpretamos este resultado y enviamos al cliente.

 

PASO 4: Obtener los permisos de una carpeta o archivo de pentaho

pentaho/SolutionRepositoryService?component=getAcl&solution=SOLUTION&path=PATH&filename=FILENAME&userid=xx&password=xxx

la respuesta es un xml con la siguiente estructura

<?xml version='1.0' encoding='UTF-8'?>
<acl>
    <entry role='Admin' permissions='-1'/>
    <entry role='cto' permissions='-1'/>
    <entry role='dev' permissions='3'/>
    <entry role='Authenticated' permissions='1'/>
</acl>

 

interpretamos este xml y podemos modificarlo y enviarlo al paso siguiente.

 

PASO 5:  dar o quitar permiso a una carpeta o archivo de pentaho

pentaho/SolutionRepositoryService?component=setAcl&solution=SOLUTION&path=PATH&filename=FILENAME&aclXml=XML_IGUAL_AL_ANTERIOR&userid=xx&password=xxx

 

al realizar esta peticion se recibirá un mensaje en XML

  <result>true</result>  si se añadió los nuevos permisos

 y  <result>false</result> si no pudo añadir los permisos

 

interpretamos este resultado y enviamos al cliente.

 

Como observamos los pasos anteriores, es fácil integrar pentaho a nuestra aplicación empresarial y no depender de su consola de administración para administrar nuestros reportes.

 

Cualquier consulta no duden en escribir.

 

Saludos cordiales.

Save As saiku


En la entrada anterior vimos como integrar adhoc con nuestra aplicación  en el cual nosotros tenemos el control del repositorio de pentaho

en este post explicaremos como hacemos con saiku

 

Saiku es una de las mejores por no decir la mejor de los plugin para hacer análisis OLAP y es además open source

si queremos la independencia de la consola de pentaho, podemos hacer el mismo paso que el post anterior y podremos guardar nuestro análisis saiku según nuestra necesidad

puesto que este también dispone de un plugin:

\pentaho-solutions\system\saiku\ui\js\saiku\plugins\BIServer\plugin.js

el proceso es exactamente el mismo del post anterior para el proceso de guardado.

image

Vamos hacer algo mas, para darle a saiku la independencia total.

si abrimos saiku en modo edición en una ventana vemos que que no dispone de un botón guardar, solo dispone de un botón guardar como

entonces si modificamos el análisis no podemos guardarlo automáticamente salvo que tendríamos que navegar y remplazar el archivo y esto para mi

es un proceso engorroso cuando ya hay parámetros y esta en modo edición

 

entonces hagamos un script para poder guardar el análisis saiku sin que nos este solicitando navegar por el repositorio de soluciones de pentaho

lo primero es que tenemos que agregar un nuevo botón en la plantilla index.html para que figure como un icono mas.

 

save

después agregamos un class css .save_action y le agregamos un icono, recuerden el nombre: href=”#save_action”

.workspace_toolbar .save_action{
   background-image: url('../../../../../../mantle/images/save_32.png');
   height: 16px !important;
   width: 16px !important;
}

podemos ver que nuestro botón se agrego correctamente. obviamente que el botón save as también lo he cambiado de icono

buttom

 

Ubiquemos los siguientes archivos:

 

\pentaho-solutions\system\saiku\ui\js\saiku\views\WorkspaceToolbar.js

y en la línea 157 des pues de la función open_query crear esta función

 

save_action: function(event) {

  var SaveSolution = Settings.GET.SOLUTION;
   var SavePath = Settings.GET.PATH;
   var SaveName = Settings.GET.ACTION;

   if (SaveSolution == undefined || SavePath == undefined || SaveName == undefined) {
           if(top.mantle_initialized !== undefined && top.mantle_initialized &&
           top.parent.enableAdhocSave ) {
               if (window.ALLOW_PUC_SAVE === undefined || ALLOW_PUC_SAVE) {
                   top.parent.enableAdhocSave(isAllowed);
               }
           } else {
               this.save_query(event);
           }
   } else {
       var nwPath;
       var temp = SavePath.toString();
       if (temp == 'NaN') {
           nwPath = '';
       } else {
           nwPath = Settings.GET.PATH;
       }
       puc.save_to_solution(SaveName, SaveSolution, nwPath, null, true);
   }
    },

Lo que hace la función es  recoger las variables globales capturadas en iniciar la ejecución del análisis por las librerías de saiku.

si el análisis esta en modo edición, entonces estas variables tiene un valor valido asignado y como decía al inicio

(No podemos estar preguntando donde guardar si tenemos la ruta y queremos actualizar el análisis).

 

ahora si el análisis no tiene valores validos quiere decir que es un nuevo análisis, y entonces si no esta integrado a pentaho re direcciono al SAVE_QUERY,

para que me muestre el explorador de soluciones, también podemos directamente  llamar a SAVE_QUERY, sin preguntar si esta en un iframe de la consola de pentaho

 

save_action: function(event) {

  var SaveSolution = Settings.GET.SOLUTION;
   var SavePath = Settings.GET.PATH;
   var SaveName = Settings.GET.ACTION;

   if (SaveSolution == undefined || SavePath == undefined || SaveName == undefined) {
               this.save_query(event);
          
   } else {
       var nwPath;
       var temp = SavePath.toString();
       if (temp == 'NaN') {
           nwPath = '';
       } else {
           nwPath = Settings.GET.PATH;
       }
       puc.save_to_solution(SaveName, SaveSolution, nwPath, null, true);
   }
    },

image

Al hacer click me re direcciona a save_query, por que las variables no están definidas

 

image

Al hacer click, ya existe valores validos para las variable

- solution

- path

- name

Por ello procedemos a guardarlo sin estar preguntando donde queremos guardarlo.

 

Cualquier consulta no duden en escribir.

Saludos cordiales

Save As adhoc


adhoc, en la versión community no tiene botones guardar o guardar como, por ello cuando se requiere abrirlo en una ventana individual, no es posible actualizarlo o crear otro a partir de ello

pero estos magníficos plugins disponen de un api de integración para este cometido (saiku y adhoc), después explicare en otro post a cerca de saiku.

 

por hora veamos algunos escenario con la integración de adhoc con un proyecto web.

En muchos casos necesitamos integrar pentaho en nuestra aplicación web, pero como lo hacemos si no queremos incluirlo al BA SERVER, como un iframe o como una aplicación independiente

entonces insertamos en un iframe  /pentaho/content/saiku-adhoc/web/index.html?biplugin=true, pero si queremos administrar estos reportes desde nuestra aplicación se nos complica la cosa

y solo podremos ver los reportes guardados y creados desde el BASERVER.

 

hoy vamos a dar las pautas necesarias para aquellos que quieran integrarlo en su aplicación web.

 

para comenzar tanto saiku como adhoc tiene un plugin de integración que se encuentra en la ruta:

\pentaho-solutions\system\saiku-adhoc\web\js\adhoc\plugins\BIServer\plugin.js

 

pero veamos en funcionamiento de adhoc.

  adhoc

 

y veamos la parte mas importante del archivo anteriormente mencionado.

var puc = {
    allowSave: function(isAllowed) {
       

        if(top.mantle_initialized !== undefined && top.mantle_initialized &&
            top.parent.enableAdhocSave ) {
            if (window.ALLOW_PUC_SAVE === undefined || ALLOW_PUC_SAVE) {
                top.parent.enableAdhocSave(isAllowed);
               
            }
        }
    },
   
    refresh_repo: function() {
        if(top.mantle_initialized !== undefined && top.mantle_initialized) {
            top.mantle_refreshRepository();
        }
    },
   
    save_to_solution: function(filename, solution, path, type, overwrite) {
       
        var self = this;
       
        var query = Application.tabs._tabs[0].content.query;
        query.action.get("/json", {
            success: function(model, response) {
               
                var queryToSave = jQuery.parseJSON(response.json);

                queryToSave.maxClientSeq = query.workspace.idCounter;
               
                var savedQuery = JSON.stringify(queryToSave, null, ' ');
               
                (new SavedQuery({
                    name: filename,
                    newname: query.get('name'),
                    json: savedQuery,
                    solution: solution,
                    path: path,
                    action: filename,
                    overwrite: overwrite
                })).save({},{
                    success: function() {
                        puc.refresh_repo();}
                });
            }
        });
    }
};

 

como podemos observar hay tres metodos: allowSave,refresh_repo y save_to_solution

- allowSave : esta tiene una función principal y es la encargada de notificar a la pagina que contiene al iframe embebido, siempre en cuando la pagina tenga una variable mantle_initialized

-  refresh_repo : esta función también hace un llamado al pagina que contiene el iframe notificando que el reporte fue guardado y que refresquen el repositorio

- save_to_solution: aquí recibimos los parámetros de la pagina que contienen al iframe, el cual nos enviar los parámetros siguientes:

  • solution
  • path
  • name
  • write

 

en un .html debemos definir un iframe con src=”/pentaho/content/saiku-adhoc/web/index.html?biplugin=true” para cargar el adhoc

una vez definida creamos un archivo javascript que contenga las siguientes funciones.


/**
* JS Integration, interaccion con js iframe content report.
*
*/

var mantle_initialized = true;
var lastMessage;
/**
*
* @param {type} contentEdit
* @returns {undefined}
*/
function enableContentEdit(contentEdit) {
    console.log("enableContentEdit : " + contentEdit);
}
/**
*
* @param {type} contentEdit
* @returns {undefined}
*/
function setContentEditSelected(contentEdit) {
    console.log("setContentEditSelected : " + contentEdit);
}

/**
*  EN ESTA FUNCION ADHOC NOS DICE QUE YA SE PUEDE GUARAR ESTE REPORTE

* @param {type} adhocSave
* @returns {undefined}
*/
function enableAdhocSave(adhocSave) {
    console.log("Call : enableAdhocSave ->  " + adhocSave);
    if (adhocSave) {
        /**
         * Mostrar Boton Guardar y Guardar como
         */
    } else {
        /**
         * Ocultar Boton Guardar y Guardar como
         */
    }
}
/**
* ADHOC NOS NOTIFICA PARA REFRESCAR EL REPOSITORIO
* @returns {undefined}
*/
function mantle_refreshRepository() {
    console.log("Call refresh Tree");
}

/**
* ADHOC  NOS ENVIA UN MENSAJE SI SE PRODUJO UN ERROR AL GUARDAR EL REPORTE

* @param {type} title
* @param {type} details
* @returns {undefined}
*/
function mantle_showMessage(title, details) {
    lastMessage = title + ": " + details;
    console.log("mantle_showMessage Title : " + title + ", Detail: " + details);
}

 

ahora procedemos hacer una corrida, supongamos que inicializamos el iframe, y creamos nuestro reporte, una vez haya datos en el reporte, adhoc ejecutara la función ALLOWSAVE

y si el usuario desea guardar tendrá que seccionar una ubicación del repositorio y un nombre que desea darle al nuevo reporte

tree

 

Una vez que el usuario haya seleccionado la ubicación correspondiente procedemos a preparar estas variables

  • var solution
  • var path
  • var name
  • var write (true si el usuario selecciono un reporte del repositorio y desea sobrescribirlo)

con estos valores ya podemos decirle a ADHOC, que guarde nuestro reporte y ejecutamos el siguiente javascript

en este caso el iframe que contiene al adhoc es el siguiente

<iframe name="adhoc" ..

 

window.frames["adhoc"].gCtrlr.repositoryBrowserController.remoteSave(name,solution,'/' + path, null, write);

 

con esto se ejecutara la funcion remoteSave de plugin.js y esta enviara los parametros aa puc.save_to_solution(name,solution,path,null,write);

después de guardarlo adhoc nos notificara a

/**
* Refrescar el arbol
* @returns {undefined}
*/
function mantle_refreshRepository() {
    console.log("Call refresh Tree");
}

 

y en nuestro .html refrescaremos el repositorio en el cual se encontrara el archivo guardado.

 

pentaho

Cualquier consulta no duden en escribir.

Saludos cordiales

24/08/2015

Dashboards con DC.JS


Hoy comentare de una de las librerías JavaScript que está creciendo enormemente en el uso del BI.

ya muchas consultoras han optado esta librería, como parte de la customizacion de los Dashboards

solicitados por los usuarios tomadores de decisiones.

 

Con sus características que le da crossfilter.js,  hacen de DC.JS

una de las librerías potentes al momento de hacer Dashboards dinámicos. 

 

En este Post, voy hacer un ejemplo de como crear unos Dashboards donde la simplicidad será nuestro primer objetivo.

 

Para iniciar nuestro ejemplo tendremos que utilizar ciertos componentes que ya viene incluido en el archivo de la demo

y solo bastara extraerlo y ponerlo en marcha en un servidor que soporte HTML,CSS,JS.

 

Dependencias:

- JS files

  •     d3.js
  •     crossfilter.js
  •     dc.js
  •     colorbrewer.js
  •     jquery-1.10.2.min.js

- CSS files

  • dc.css
  • bootstrap.min.css
  • dashboard.css

 

Con esto y un example.html, ya podremos correr nuestro ejemplo.

 image

 

Aplicando un filtro:

 image

Descarga: aqui

 

Saludos cordiales.

22/01/2015

Interfaz Movil CDE


En muchos casos queremos que nuestra interfaz de Pentaho CDE, soporte dispositivos móviles, ya que nos ahorrarían gran parte del trabajo

Quiero compartirles un diseño que realice integrando Bootstrap, como sabrán tiene todos los CSSs, necesarioa para ser resizable

 

Lo único que tiene que hacerse conocer las “Clases CSS” necesarios según la documentación Panels de Bootstrap

para que forme los cuadros del dashboard.

 

Ahora nos bajamos el archivo del tema y lo colocamos en un directorio como este biserver-ce\pentaho-solutions\Dashboard\theme\

Download Theme Movil CDE

 

El resultado que se vera al implementar la interfaz seria:

 

Para Movil

image

 

Para PC

 image

 

Podemos construir interfaz, de cualquier estructura guiándose la documentación de bootstrap, e integrando con los tgas de CDE.

 

Ejemplos.

image

 

Patrón de referencia.

 image 

 

 

Escudriñar bien el archivo de ejemplo para hacer mas implementaciones.

 

Versión de BA Server 4.5

 

Si el ejemplo No se visualiza, actualizar la url de los recurso en el CDE. (En caso de colocar en otro directorio)

 

Espero puedan utilizarlo y sacarle provecho, Saludos.