Guía del Desarrollador de DataPort

Anuncio
VIRTUAL DATAPORT 4.0 GUÍA DEL DESARROLLADOR
NOTA
Este documento es confidencial y propiedad de denodo technologies (en
adelante denodo).
Ninguna de las partes del documento puede ser copiada, fotografiada,
fotocopiada, transmitida electrónicamente, almacenada en un sistema de
gestión documental o reproducida mediante cualquier otro mecanismo sin la
autorización previa o por escrito de denodo.
copyright © 2007
Queda prohibida la reproducción total o parcial de este documento sin la autorización por escrito de denodo technologies
Virtual DataPort 4.0
Guía del Desarrollador
ÍNDICE
PREFACIO...........................................................................................................................................................................I
ALCANCE .....................................................................................................................................................................I
QUIÉN DEBERÍA USAR ESTE DOCUMENTO..........................................................................................................I
RESUMEN DE CONTENIDOS....................................................................................................................................I
1
INTRODUCCIÓN ..................................................................................................................................... 1
EJEMPLOS Y FICHEROS DE AYUDA................................................................................................... 1
1.1
2
ACCESO A TRAVÉS DE JDBC............................................................................................................... 2
3
3.1
3.2
ACCESO A TRAVÉS DE ODBC .............................................................................................................. 4
ACCESO MEDIANTE EASYSOFT ODBC-JDBC GATEWAY.............................................................. 4
ACCESO MEDIANTE OPENLINK ODBC-JDBC BRIDGE ................................................................... 5
4.1
4.2
4.3
4.4
4.5
ACCESO A TRAVÉS DE INTERFAZ WEB SERVICE............................................................................ 8
ACCESO A VISTAS PUBLICADAS COMO WEB SERVICES ............................................................. 8
INTERFAZ WEB SERVICE GENÉRICA ................................................................................................. 8
EJECUTANDO CONSULTAS EN CLIENTES SIN ESTADO................................................................ 9
EJECUTANDO CONSULTAS EN CLIENTES CON ESTADO .............................................................. 9
PROCESANDO LOS RESULTADOS DE UNA SENTENCIA.............................................................. 10
4
5
5.1
5.2
5.3
5.4
5.4.1
5.4.2
5.5
5.6
5.6.1
5.7
5.7.1
5.7.2
5.7.3
5.7.4
API DE DESARROLLO DATAPORT..................................................................................................... 12
CONFIGURACIÓN DE LAS APLICACIONES CLIENTE ..................................................................... 13
CASO PRÁCTICO .................................................................................................................................. 13
ESTRUCTURA GENERAL DE LA API DE DESARROLLO DATAPORT............................................. 15
DATASOURCES VIRTUAL DATAPORT.............................................................................................. 16
DataSources............................................................................................................................................ 16
Conexiones Virtual DataPort................................................................................................................... 17
PROTOCOLO DE COMUNICACIONES CON EL SERVIDOR............................................................. 18
PROCESAMIENTO DE RESULTADOS DE UNA CONSULTA........................................................... 21
Implementación de Nuevos Ensambladores de Resultados................................................................... 22
MODOS DE FUNCIONAMIENTO GENERAL DE UN CLIENTE ........................................................ 25
Clientes Síncronos – Requieren control sobre el flujo de datos ............................................................ 26
Clientes Asíncronos – No requieren control sobre el flujo de datos ..................................................... 26
Cliente Iterador Asíncrono ...................................................................................................................... 28
Información sobre la Traza de Ejecución de Sentencias ........................................................................ 28
BIBLIOGRAFÍA ............................................................................................................................................................... 30
Virtual DataPort 4.0
Guía del Desarrollador
ÍNDICE DE FIGURAS
Figura 1
Figura 2
Figura 3
Figura 4
Figura 5
Figura 6
Figura 7
Figura 8
Figura 9
Figura 10
Figura 11
Figura 12
Configuración de EasySoft ODBC-JDBC Gateway.................................................................................... 5
Configuración de OpenLink ODBC-JDBC Lite (1) ...................................................................................... 6
Configuración de OpenLink ODBC-JDBC Lite (2) ...................................................................................... 7
Código de un cliente iterador asíncrono................................................................................................. 15
Estructura general de la API nativa ........................................................................................................ 16
Configuración de un VDBDataSource ..................................................................................................... 17
Superclase de todos los resultados parciales ........................................................................................ 19
Jerarquía de resultados parciales .......................................................................................................... 20
Estructura general de un ensamblador de resultados............................................................................ 21
Código de ConsolePrinter........................................................................................................................ 25
Código de un cliente síncrono................................................................................................................. 26
Código de un cliente asíncrono............................................................................................................... 27
Virtual DataPort 4.0
ÍNDICE DE TABLAS
Guía del Desarrollador
Virtual DataPort 4.0
Guía del Desarrollador
PREFACIO
ALCANCE
Denodo Virtual DataPort permite que las aplicaciones puedan acceder a vistas integradas de distintas fuentes de
información heterogéneas y distribuidas. Este documento introduce al usuario del producto los mecanismos
disponibles para que aplicaciones cliente utilicen Denodo Virtual DataPort. También se proporciona la información
necesaria para desarrollar una aplicación cliente propia.
QUIÉN DEBERÍA USAR ESTE DOCUMENTO
Este documento está dirigido a usuarios que deseen que una aplicación cliente saque partido de las funcionalidades
avanzadas de integración, extracción, inserción, actualización y borrado de datos de Virtual DataPort. También está
dirigido a desarrolladores que quieran conocer con detalle cómo desarrollar sus propias aplicaciones cliente.
La información detallada precisa para instalar el sistema y administrarlo se proporciona en otros manuales, que
serán referenciados a medida que sea necesario.
RESUMEN DE CONTENIDOS
Más concretamente, en este documento:
•
Se presentan las tareas fundamentales que son necesarias para que una aplicación cliente acceda a las
vistas unificadas creadas mediante Virtual DataPort.
•
Se describe cómo acceder a un servidor DataPort utilizando la API Java estándar para acceso a Bases de
Datos, JDBC.
•
Se describe cómo acceder a un servidor DataPort utilizando la interfaz para acceso a Bases de Datos,
ODBC.
•
Se describe cómo acceder a las vistas de DataPort publicadas como Servicios Web desde aplicaciones
cliente.
•
Se describe la API genérica basada en Servicios Web para la realización de cualquier sentencia VQL sobre
un servidor DataPort.
•
Se detallan todas las peculiaridades de la API nativa de desarrollo de Denodo Virtual DataPort.
•
Se incluyen o se referencian diversos ejemplos de desarrollo de clientes que usan Virtual DataPort tanto de
forma síncrona (en la cual el cliente se queda bloqueado hasta recibir la respuesta completa del servidor)
como asíncrona (en el cual el cliente controla el flujo de la comunicación con el servidor y puede tratar los
resultados de las consultas a medida que estos se van obteniendo de las fuentes).
Prefacio
i
Virtual DataPort 4.0
1
Guía del Desarrollador
INTRODUCCIÓN
Denodo Virtual DataPort es una solución global para la integración de fuentes de información heterogéneas y
dispersas, utilizando el enfoque EII (Enterprise Information Integration).
Virtual DataPort integra aquella información que es relevante para la empresa, sin importar su procedencia, formato
o nivel de estructuración, incorpora esa información en su sistema de información, en tiempo real o con precargas
configurables, y facilita la construcción de servicios telemáticos de alto valor estratégico y funcional, tanto
corporativos como de negocio, imposibles de concebir sin su aplicación.
DataPort está basado en una arquitectura cliente-servidor en la cual los clientes emiten sentencias al servidor
escritas en VQL (Virtual Query Language), lenguaje utilizado para el manejo y definición de datos (ver la Guía del
Administrador [1] y la Guía Avanzada de VQL [2])
Este documento introduce al usuario del producto los mecanismos disponibles para que aplicaciones cliente utilicen
Denodo Virtual DataPort, sacando partido de sus facilidades de integración, extracción, inserción, actualización y
borrado de datos. Véase la Guía del Administrador [1] para obtener información sobre cómo instalar, configurar y
administrar el servidor DataPort, así como para utilizarlo en la creación de vistas unificadas de datos sobre fuentes
heterogéneas y dispersas.
Existen varias formas que las aplicaciones cliente pueden utilizar para acceder a Virtual DataPort 3.5:
•
•
•
•
•
Acceso a través de JDBC (Java DataBase Connectivity) [5]. DataPort incluye un driver JDBC que las
aplicaciones cliente pueden utilizar para este propósito.
Acceso a través de ODBC (Open DataBase Connectivity) [10]. El driver JDBC de DataPort puede ser utilizado
conjuntamente con un puente ODBC-JDBC para proporcionar acceso desde clientes ODBC.
Acceso a vistas publicadas como Web Services. La herramienta de administración de Virtual DataPort (ver
la Guía del Administrador [1]) permite publicar como un Web Service cualquier vista de datos definida en
DataPort.
Acceso a través de una interfaz Web Service genérica. DataPort incluye una interfaz genérica Web Service
para ejecutar sentencias VQL sobre un servidor DataPort. Se proporciona el fichero WSDL [7] que puede ser
utilizado para generar los “stubs” precisos para acceder a esta interfaz.
Acceso a través de la API nativa. DataPort incluye también una API JAVA para la interacción con el
servidor.
En la ruta DENODO_HOME\docs\vdp se encuentra el fichero README_VDPClient con información útil
sobre las diferentes interfaces de acceso de Virtual DataPort.
En esta guía se exponen las directrices básicas para el uso de cada uno de estos modos de acceso y se indican
algunos ejemplos de uso. Se recomienda la lectura de la documentación Javadoc [3] para mayor detalle sobre clases,
atributos y operaciones.
1.1
EJEMPLOS Y FICHEROS DE AYUDA
En la ruta DENODO_HOME\samples\vdp\vdp-clients se encuentran diversos ejemplos de
implementación de aplicaciones cliente para VDP, utilizando los diferentes métodos de acceso comentados en este
documento. Para cada ejemplo se incluye su código fuente y scripts para su compilación y ejecución. Véase el fichero
DENODO_HOME\samples\vdp\vdp-clients\README para más información sobre los ejemplos.
Introducción
1
Virtual DataPort 4.0
2
Guía del Desarrollador
ACCESO A TRAVÉS DE JDBC
JDBC (Java DataBase Connectivity) es una API Java que permite realizar consultas contra una Base de datos
relacional, independientemente del Sistema de Base de Datos utilizado.
Virtual DataPort proporciona un driver que implementa las principales características de JDBC 3.0 [5]. El driver JDBC
de Virtual DataPort soporta, entre otros, los siguientes aspectos de la especificación JDBC:
Los tipos de datos soportados son los definidos por el gestor en la Guía avanzada de VQL [2] (incluye
soporte para todos los tipos básicos así como para campos de tipo array y registro).
Permite ejecutar las sentencias de creación de vistas unificadas, consulta, inserción, actualización y
borrado de las mismas soportadas en VQL [2].
Soporta también sentencias de descripción de relaciones y listado de elementos del catálogo del gestor.
Soporta el uso de PreparedStatement en Virtual DataPort, permitiendo delegar en el driver el
formateo de los parámetros de una sentencia VQL.
Soporta la consulta sobre wrappers mediante la sentencia QUERY WRAPPER [2].
Por último, también soporta la invocación de procedimientos almacenados mediante la sentencia CALL
[2].
El driver JDBC para Virtual DataPort es un driver tipo 2, por lo que requiere disponer de la librería con la API DataPort
nativa en la máquina que ejecuta la aplicación cliente.
Para realizar una conexión JDBC contra un servidor se necesitan los siguientes elementos:
Clase que implementa el driver JDBC para el gestor contra el que realizar las consultas
(com.denodo.vdp.jdbc.Driver).
Cadena de conexión, que indica la máquina, puerto y nombre de la base de datos del gestor
(jdbc:vdb://<hostName>:<port>/<databaseName>)
Nombre del usuario a utilizar en la conexión contra el gestor.
Clave de acceso del usuario que accederá al gestor.
Opcionalmente también es posible añadir una lista de parámetros de configuración específicos de Virtual DataPort
que se muestran a continuación junto con sus valores por defecto (véase la sección 5.4 para una descripción de cada
uno de estos parámetros):
i18n=es_euro
queryTimeout=80000
chunkTimeout=90000
chunkSize=100
initSize=0
maxActive=30
maxIdle=20
poolEnabled=false
Por lo tanto la sintaxis completa para el URL de conexión JDBC es la siguiente:
jdbc:vdb://<hostName>:<port>/<databaseName>?paramName1=paramValue1&...
&paramNameN=paramValueN
Por ejemplo:
jdbc:vdb://localhost:9999/admin?queryTimeout=100000&chunkTimeout=95000
Acceso a través de JDBC
2
Virtual DataPort 4.0
Guía del Desarrollador
Para que el acceso a DataPort utilizando el driver JDBC sea exitoso, el CLASSPATH de la aplicación cliente debe
incluir el fichero denodo-vdp-jdbcdriver.jar, que tras la instalación puede encontrarse en la ruta
DENODO_HOME\lib\vdp-jdbcdriver-core\
NOTA: El driver JDBC de Virtual DataPort utiliza las siguientes librerías externas: Jakarta commonscollections, Jakarta commons-pool, Jakarta commons-logging, Jakarta commons-lang y
Apache log4j). Se proporciona también en la misma ruta una versión del driver que no incluye estas librerías
(denodo-vdp-jdbcdriver-basic.jar). Esta versión puede utilizarse en aplicaciones que ya empleen
para otros propósitos implementaciones compatibles de las mismas. Es importante tener en cuenta, sin embargo, que
si no se utilizan versiones compatibles con las librerías incluídas con el producto, el driver JDBC podría no funcionar
correctamente.
En la ruta DENODO_HOME\samples\vdp\vdp-clients pueden encontrarse ejemplos de programas
cliente que acceden a DataPort a través de JDBC (ver fichero README en la citada ruta).
Acceso a través de JDBC
3
Virtual DataPort 4.0
3
Guía del Desarrollador
ACCESO A TRAVÉS DE ODBC
El driver JDBC de DataPort puede ser utilizado conjuntamente con un puente ODBC-JDBC para proporcionar acceso a
DataPort desde clientes ODBC.
En esta sección se indica cómo configurar para su uso con DataPort dos de los puentes ODBC-JDBC más utilizados
del mercado: EasySoft ODBC-JDBC Gateway [11] (ha sido probado con éxito con la versión 1.3.1) y OpenLink ODBCJDBC bridge [12] (ha sido probado con éxito con la versión 5.2).
3.1
ACCESO MEDIANTE EASYSOFT ODBC-JDBC GATEWAY
Los pasos para acceder a Virtual DataPort utilizando EasySoft ODBC-JDBC Gateway son:
1.
Instalar EasySoft ODBC-JDBC Gateway (ver instrucciones en [11]).
2.
Crear un nuevo origen de datos ODBC utilizando EasySoft ODBC-JDBC Gateway.
a.
b.
c.
d.
3.
En el Panel de Control de Windows, ir a Herramientas Administrativas.
Seleccionar ‘Orígenes de datos ODBC’.
Hacer clic en el panel ‘DSN de Sistema’ y pulsar ‘Agregar’.
Seleccionar EasySoft ODBC-JDBC Gateway y pulsar finalizar.
Rellenar la siguiente pantalla como se indica a continuación (ver Figura 1):
a.
En los campos ‘User Name’ y ‘Password’ introducir el nombre de usuario y contraseña a utilizar
en el servidor DataPort.
b.
Los campos ‘Driver Class’, ‘Classpath’ y ‘URL’ deben rellenarse con los valores correspondientes
del driver JDBC de Virtual DataPort (ver sección 2): clase del driver JDBC y URL de acceso a un
servidor DataPort.
4.
Pulsar ‘Test’ para comprobar que la conexión al servidor DataPort puede ya realizarse.
5.
Finalmente, pulsar ‘Ok’ para finalizar el proceso.
Acceso a través de ODBC
4
Virtual DataPort 4.0
Guía del Desarrollador
Figura 1 Configuración de EasySoft ODBC-JDBC Gateway
3.2
ACCESO MEDIANTE OPENLINK ODBC-JDBC BRIDGE
Los pasos para acceder a Virtual DataPort utilizando OpenLink ODBC-JDBC Bridge (llamado ODBC-JDBC-Lite) son:
1.
Instalar OpenLink ODBC-JDBC-Lite (ver instrucciones en [12]).
a.
b.
2.
El proceso de instalación puede modificar el CLASSPATH actual, por lo que es conveniente
comprobarlo tras la instalación.
Asegurese de que el fichero jvm.dll (que habitualmente se encuentra en la ruta
%JAVA_HOME%\jre\bin\server) se encuentra en el PATH del sistema.
Crear un nuevo origen de datos ODBC utilizando OpenLink ODBC-JDBC-Lite.
a.
b.
c.
d.
En el Panel de Control ir a Herramientas Administrativas.
Seleccionar ‘Orígenes de datos ODBC’.
Hacer clic en el panel ‘DSN de Sistema’ y pulsar ‘Agregar’.
Seleccionar OpenLink ODBC-JDBC Lite y pulsar finalizar.
3.
En la siguiente pantalla indicar un nombre y una descripción para el nuevo origen de datos y pulsar ‘Next’.
4.
Rellenar la siguiente pantalla como sigue (ver Figura 2):
Acceso a través de ODBC
5
Virtual DataPort 4.0
5.
Guía del Desarrollador
a.
En los campos ‘Login ID’ y ‘Password’ introducir el nombre de usuario y contraseña a utilizar en el
servidor DataPort.
b.
Los campos ‘JDBC Driver’ y ‘URL String’ deben rellenarse con los valores correspondientes del
driver JDBC de Virtual DataPort (ver sección 2): clase del driver JDBC y URL de acceso a un
servidor DataPort.
Las siguientes pantallas del wizard permiten configurar diversas opciones de uso del origen de datos. En la
primera pantalla es necesario marcar las siguientes opciones (ver Figura 3):
a.
b.
‘Drop Catalog Name from Database Metadata Calls’.
‘Disable support of quoted identifier’.
6.
Una vez finalizada la configuración, se accederá a una pantalla que permite probar el nuevo origen de
datos mediante el botón ‘Test Data Source’.
7.
Si la comprobación es exitosa, pulsar ‘Finish’ para finalizar el proceso.
Figura 2 Configuración de OpenLink ODBC-JDBC Lite (1)
Acceso a través de ODBC
6
Virtual DataPort 4.0
Guía del Desarrollador
Figura 3 Configuración de OpenLink ODBC-JDBC Lite (2)
Acceso a través de ODBC
7
Virtual DataPort 4.0
4
Guía del Desarrollador
ACCESO A TRAVÉS DE INTERFAZ WEB SERVICE
4.1
ACCESO A VISTAS PUBLICADAS COMO WEB SERVICES
La herramienta de administración de Virtual DataPort permite publicar como un Web Service cualquier vista de datos
definida en DataPort. Véase la Guía del Administrador [1] para obtener información sobre este proceso.
Estas vistas publicadas sólo permiten realizar consultas sobre las vistas. Si se desea realizar operaciones de
inserción, actualización y borrado de datos desde un entorno Web Service, es necesario utilizar el Web Service
genérico descrito en el siguiente apartado.
El proceso de publicación de la vista genera un fichero .wsdl y un fichero .war en la ruta especificada durante el
proceso de publicación.
El fichero .war contiene la implementación del Servicio Web y puede ser instalado en un contenedor web J2EE
(como, por ejemplo, Apache Tomcat [8]).
El fichero .wsdl [7] puede ser utilizado junto a una utilidad para la programación de Web Services (como, por
ejemplo, las incluidas con Apache Axis [9]) para generar los stubs necesarios para implementar un programa cliente
que acceda al Servicio Web.
En la ruta DENODO_HOME\samples\vdp\vdp-clients pueden encontrarse ejemplos de programas
cliente que acceden a una vista publicada como Servicio Web (en el fichero README de la citada ruta se explica
cómo generar y publicar las vistas accedidas por los clientes de ejemplo).
4.2
INTERFAZ WEB SERVICE GENÉRICA
Virtual DataPort también puede ser accedido a través de una interfaz Web Service genérica que permite ejecutar
cualquier sentencia escrita en VQL. Dicho servicio web se encuentra empaquetado en el fichero denodo-vdpwsclient.war situado en la ruta DENODO_HOME\webapps\vdp-wsclient. En esta ruta se
encuentra también el fichero WSDL [7] que define la interfaz de acceso al mismo.
Pueden construirse dos tipos de aplicaciones cliente que utilizan la interfaz Web Service:
•
•
Cliente sin estado. En este caso, el cliente establece una sesión con el servidor cada vez que emite una
sentencia, cerrándola una vez terminada la ejecución.
Cliente con estado. En este modo el cliente establece una sesión con el servidor, utiliza dicha sesión para
emitir sentencias sobre el mismo y la cierra una vez que ha terminado. Esto permite evitar el coste de
establecimiento de sesión para cada sentencia.
Las siguientes subsecciones describen la manera en que las aplicaciones cliente de cada uno de estos tipos pueden
ejecutar sentencias sobre un servidor DataPort. Posteriormente se describe el formato en el que se obtiene la
respuesta a dichas sentencias.
En la ruta DENODO_HOME\samples\vdp\vdp-clients pueden encontrarse ejemplos de ambos tipos de
clientes (ver fichero README en la citada ruta).
Acceso a través de Interfaz Web Service
8
Virtual DataPort 4.0
4.3
Guía del Desarrollador
EJECUTANDO CONSULTAS EN CLIENTES SIN ESTADO
Este tipo de clientes pueden utilizar directamente las operaciones executeQuery
y
executeQueryByConfig para ejecutar sentencias sobre un servidor DataPort. executeQuery recibe
los siguientes parámetros de entrada:
•
•
•
•
•
•
•
Sentencia VQL a ejecutar sobre el servidor (elemento de tipo String).
URI de conexión al servidor DataPort (String).
Identificador de usuario con el que se realizará la conexión al servidor DataPort (String).
Contraseña asociada al usuario especificado (String).
Máximo tiempo (en milisegundos) que está dispuesto a esperar el cliente hasta que finalice la sentencia
(elemento de tipo int). Este parámetro es opcional. Si no se indica (o recibe el valor 0), entonces se
espera hasta que la ejecución finalice.
Máximo tiempo (en milisegundos) que está dispuesto a esperar el cliente hasta que llegue un resultado
parcial (int). Si se sobrepasa este tiempo, Virtual DataPort devuelve un resultado parcial vacío. Es
opcional. Si no se especifica (o recibe el valor 0), el gestor devuelve todos los resultados conjuntamente al
finalizar la ejecución de la sentencia.
Número de resultados que conforman un resultado parcial (int). Si Virtual DataPort recibe este número de
resultados, los reenviará al cliente aunque no se haya cumplido el tiempo máximo de resultado parcial.
Los dos últimos parámetros permiten controlar cómo el servidor y el cliente intercambian los resultados devueltos por
la sentencia. Permitir que el servidor devuelva al cliente los resultados a medida que los tiene disponibles puede
influir en el tiempo de ejecución.
Por su parte, la operación executeQueryByConfig permite la misma funcionalidad pero agrupando los
parámetros de entrada de la siguiente forma:
•
•
Un elemento de tipo String conteniendo la sentencia VQL a ejecutar sobre el servidor.
Un elemento de tipo WSConfigVO que contiene la información necesaria para localizar el servidor y
configurar la conexión con el mismo.
Los elementos de tipo WSConfigVO están compuestos por los siguientes sub-elementos:
•
•
•
•
•
•
4.4
vdpURL. URI de conexión al servidor DataPort.
vdpUser. Identificador de usuario con el que se realizará la conexión al servidor DataPort.
vdpPassword. Contraseña asociada al usuario especificado.
vdpQueryTimeout. Máximo tiempo (en milisegundos) que está dispuesto a esperar el cliente hasta
que finalice la sentencia. Este parámetro es opcional. Si no se indica (o recibe el valor 0), entonces se
espera hasta que la ejecución finalice.
vdpChunkTimeout. Máximo tiempo (en milisegundos) que está dispuesto a esperar el cliente hasta
que llegue un resultado parcial. Si se sobrepasa este tiempo, Virtual DataPort devuelve un resultado parcial
vacío. Es opcional. Si no se especifica (o recibe el valor 0), el gestor devuelve todos los resultados
conjuntamente al finalizar la ejecución de la sentencia.
vdpChunkSize. Número de resultados que conforman un resultado parcial. Si Virtual DataPort recibe
este número de resultados, los reenviará al cliente aunque no se haya cumplido el tiempo máximo de
resultado parcial.
EJECUTANDO CONSULTAS EN CLIENTES CON ESTADO
En este modo el cliente establece una sesión con el servidor, utiliza dicha sesión para emitir sentencias sobre el
mismo y la cierra una vez que ha terminado.
Acceso a través de Interfaz Web Service
9
Virtual DataPort 4.0
Guía del Desarrollador
•
La operación openConnection permite establecer una sesión en el servidor DataPort. Recibe como
parámetro un objeto WSConfigVO que contiene la información necesaria para localizar el servidor y
configurar la conexión (ver sección anterior). Devuelve un identificador de sesión de tipo String.
•
Una vez establecida la sesión, puede utilizarse la operación executeQueryBySession para emitir
sentencias sobre el servidor DataPort. Esta operación recibe dos parámetros de tipo String:
o
o
•
4.5
La sentencia VQL a ejecutar.
El identificador de sesión devuelto por openConnection.
El cliente puede cerrar la sesión invocando la operación closeConnection, que recibe como
parámetro el identificador de la sesión que se desea cerrar.
PROCESANDO LOS RESULTADOS DE UNA SENTENCIA
El método executeQuery devuelve un elemento de tipo WSTableVO, que encapsula toda la información
devuelta por el proceso de ejecución de una sentencia. Consta de los siguientes sub-elementos:
•
error. Si no se produce un error toma el valor NULL. En caso de producirse contendrá un elemento de
tipo WSErrorVO con dos sub-elementos:
o errorCode. Contiene el código del error producido. Los códigos de error son los mismos
utilizados por la API JAVA nativa de DataPort (Véase la documentación Javadoc [3] de la clase
com.denodo.vdb.vdbinterface.common.clientResult.ErrorCodes, para el detalle de
los códigos de error posibles)).
o errorMessage. Contiene un mensaje explicativo del error producido.
•
schema. Elemento que contiene la información sobre el esquema de los resultados devueltos por la
sentencia. Es un array de elementos de tipo WSColumnMetadataVO dónde cada elemento representa
el nombre y el tipo de un atributo del resultado.
•
data. Contiene las tuplas obtenidas como respuesta a la sentencia. Es un array de elementos WSRowVO
donde cada elemento representa una tupla del resultado de la sentencia. Cada elemento WSRowVO está
compuesto a su vez por un array de elementos WSValueVO. Cada elemento WSValueVO representa el
valor de un atributo de la tupla.
Es importante recordar que DataPort utiliza un modelo de datos que soporta tipos compuestos de tipo registro y de
tipo array. Los atributos compuestos de tipo array contienen siempre a nivel interno un registro que define el
esquema de cada uno de los elementos del array (véase la Guía Avanzada de VQL [2] para más información).
De esta forma los objetos WSValueVO, empleados para representar el valor de un atributo en una tupla del
resultado, pueden ser de tres subtipos:
•
WSSimpleValueVO. Representa un valor de un tipo de dato simple. Existe un subtipo para cada uno
de los tipos simples disponibles (WSIntValueVO, WSLongValueVO, WSFloatValueVO,
WSDoubleValueVO, WSTextValueVO, WSBlobValueVO,
WSBooleanValueVO,
WSDateValueVO, WSTimeValueVO, WSMoneyValueVO, WSEnumeratedValueVO).
Todos los subtipos definen un subelemento llamado value del tipo básico de dato XML correspondiente
(int en el caso de WSIntValueVO, string en el caso de WSTextValueVO, etc.).
•
WSRegisterValueVO. Representa un valor de tipo de dato registro. Contiene un elemento
fieldValues que es un array de elementos WSRegisterFieldValueVO. Cada elemento
Acceso a través de Interfaz Web Service
10
Virtual DataPort 4.0
Guía del Desarrollador
WSRegisterFieldValueVO representa el valor de uno de los campos del registro de datos y tiene
dos subelementos:
o name. String que contiene el nombre del campo.
o value. elemento de tipo WSValueVO que contiene el valor del campo.
•
WSArrayValueVO. Representa un valor de tipo de dato array. Contiene un elemento values que es
un array de elementos WSRegisterValueVO. Cada uno de ellos representa un valor del array de
datos.
Por su parte los elementos WSColumnMetadataVO, que representan la metainformación de esquema de un
atributo devuelto en el resultado de la consulta, contienen dos subelementos:
•
columnName. Es un String que contiene el nombre del atributo.
•
columnType. Contiene un elemento de tipo WSTypeVO que describe el tipo del atributo. Los
elementos WSTypeVO contienen un subelemento typeName que indica el nombre del tipo de dato.
Los elementos WSTypeVO pueden ser también de varios subtipos:
•
WSSimpleTypeVO. Representa un atributo de un tipo simple (e.g. int, float, String,…) y no
tiene subelementos adicionales.
•
WSRegisterTypeVO. Representa un atributo de tipo registro. Contiene un subelemento fields
que es un array de elementos WSRegisterFieldMetadataVO. Cada uno de los elementos de
este array contiene la metainformación de un campo del registro y está formado por dos subelementos:
• name. Es un String que contiene el nombre del campo.
• type. Contiene un elemento de tipo WSTypeVO que describe el tipo del campo.
•
WSArrayTypeVO. Representa un atributo de tipo array. Contiene un subelemento basetype de tipo
WSRegisterTypeVO que describe el tipo de los elementos del array.
•
WSEnumeratedTypeVO. Representa un atributo de tipo enumerado. Contiene un subelemento
values de tipo array de strings con un elemento para cada valor posible del tipo enumerado.
Acceso a través de Interfaz Web Service
11
Virtual DataPort 4.0
5
Guía del Desarrollador
API DE DESARROLLO DATAPORT
Denodo Virtual DataPort también ofrece una API Java que permite ejecutar cualquier sentencia VQL sobre el servidor:
sentencias de consulta, inserción, actualización y borrado, sentencias de creación de relaciones, de enumeración de
elementos del catálogo, descripción de los mismos, etc.
Existen dos etapas fundamentales en la realización de una sentencia sobre Virtual DataPort. En la primera se
efectuará el envío de la sentencia al servidor y en la segunda se realizará la solicitud de los resultados y la recepción
e interpretación de los mismos.
Cuando el servidor recibe una petición de los resultados de una sentencia, éste devolverá todas las tuplas de dicho
resultado que haya obtenido hasta ese momento (debe recordarse que en el contexto en el que funciona DataPort
puede ser necesario acceder a la información de las fuentes en tiempo real a través de la red, lo cual puede causar
que cuando se soliciten los resultados de una consulta, no todos estén aún disponibles).
Opcionalmente se puede especificar el número máximo de elementos que el cliente desea recibir en cada resultado
parcial (“chunk”). Esta última característica es aconsejable sólo en el caso de que la cantidad de resultados que
tenga disponibles el servidor sea muy elevada, y la probabilidad de que el cliente llegue a utilizar todos estos
resultados sea baja1.
Por otro lado, existen varios tipos de mensajes que el cliente puede recibir como respuesta a una sentencia:
•
Mensajes conteniendo tuplas. Contienen parte o todas las tuplas que componen el resultado a la consulta.
•
Mensajes vacíos. Indican que el gestor no tiene más respuestas para la sentencia en ese momento.
•
Mensajes de fin. Indican que ha finalizado la ejecución de la sentencia en el servidor.
•
Mensajes de error. Se envía si se produce algún tipo de error durante la ejecución de la sentencia.
Existen fundamentalmente cuatro clases relevantes a la hora de desarrollar un cliente para el gestor Virtual DataPort:
•
com.denodo.vdb.vdbinterface.common.datasource.VDBDataSource. Define
la información necesaria para realizar la conexión contra el gestor
•
com.denodo.vdb.vdbinterface.common.connection.VDBConnection. Frontal
contra el que los clientes realizan sus consultas. Representa una conexión con el servidor.
•
com.denodo.vdb.vdbinterface.common.clientResult.PartialResult.
Engloba todos los tipos de mensaje que puede recibir el cliente.
•
com.denodo.vdb.vdbinterface.client.printer.Printer. Encargada de convertir
los resultados emitidos por el servidor al formato deseado por un determinado tipo de cliente.
1
Usar esta opción puede incrementar las comunicaciones precisas entre cliente-servidor, por lo que se aconseja utilizarla sólo cuando sea
necesaria
API de Desarrollo DataPort
12
Virtual DataPort 4.0
5.1
Guía del Desarrollador
CONFIGURACIÓN DE LAS APLICACIONES CLIENTE
Los ficheros .jar necesarios en el CLASSPATH de las aplicaciones que deseen utilizar el API Cliente de Virtual
DataPort son los siguientes:
1. En sistemas Windows:
a. %DENODO_HOME%\lib\contrib\commons-collections.jar
b. %DENODO_HOME%\lib\contrib\commons-logging.jar
c. %DENODO_HOME%\lib\contrib\commons-pool.jar
d. %DENODO_HOME%\lib\contrib\denodo-util.jar
e. %DENODO_HOME%\lib\contrib\log4j.jar
f. %DENODO_HOME%\lib\vdp-client-core\denodo-vdp-clientbase.jar
g. %DENODO_HOME%\lib\vdp-client-core\denodo-vdp-clientext.jar
2. En sistemas Unix:
a. $DENODO_HOME/lib/contrib/commons-collections.jar
b. $DENODO_HOME/lib/contrib/commons-logging.jar
c. $DENODO_HOME/lib/contrib/commons-pool.jar
d. $DENODO_HOME/lib/contrib/denodo-util.jar
e. $DENODO_HOME/lib/contrib/log4j.jar
f. $DENODO_HOME/lib/vdp-client-core/denodo-vdp-clientbase.jar
g. $DENODO_HOME/lib/vdp-client-core/denodo-vdp-client-ext.jar
El paquete Apache Log4j API es el utilizado para gestión de trazas. Un fichero de configuración tendría que incluirse
en el CLASSPATH para configurar los niveles de traza. Un fichero de ejemplo puede encontrarse en la ruta
%DENODO_HOME%\conf\vdp-admin\log4j.xml.
Los valores de algunos parámetros de configuración pueden modificarse mediante la utilización de un fichero de
configuración de propiedades que debe incluirse en el CLASSPATH. Un fichero de ejemplo se encuentra en
%DENODO_HOME%\conf\vdp-admin\VDBAdminConfiguration.properties.
El siguiente apartado proporciona un ejemplo de un caso típico de ejecución de una consulta utilizando estas clases.
Posteriormente, los siguientes apartados se ocupan, respectivamente, de la estructura general de la API y de cada
una de las clases principales en detalle. Finalmente, se ofrecen varios ejemplos adicionales de utilización para
realizar consultas sobre el servidor, tanto utilizando un enfoque síncrono (en el cual el cliente se queda bloqueado
hasta recibir la respuesta completa del servidor) como utilizando un enfoque asíncrono (en el cual el cliente controla
el flujo de la comunicación con el servidor y puede tratar los resultados de las consultas a medida que estos se van
obteniendo, sin tener que esperar a que todos estén disponibles).
5.2
CASO PRÁCTICO
Antes de comentar cada uno de los elementos de la API propietaria, se muestra un ejemplo de implementación de un
cliente típico para la ejecución de sentencias de consulta contra Virtual DataPort. En este ejemplo se utilizará un
enfoque asíncrono para el acceso a los datos del gestor (ver apartados 5.7.2 y 5.7.3 para más detalles sobre la
creación de clientes asíncronos).
import
import
import
import
import
import
import
com.denodo.vdb.vdbinterface.client.printer.standard.StandardRowVO;
com.denodo.vdb.vdbinterface.client.util.VQLStatement;
com.denodo.vdb.vdbinterface.client.util.datasource.DataSourceLocator;
com.denodo.vdb.vdbinterface.client.util.iterator.VDBResultSetIterator;
com.denodo.vdb.vdbinterface.common.clientResult.MetadataField;
com.denodo.vdb.vdbinterface.common.clientResult.vo.descriptions.type.TypeVO;
com.denodo.vdb.vdbinterface.common.clientResult.vo.sentences.ValueVO;
API de Desarrollo DataPort
13
Virtual DataPort 4.0
import
import
import
import
Guía del Desarrollador
com.denodo.vdb.vdbinterface.common.connection.VDBConnection;
com.denodo.vdb.vdbinterface.common.datasource.VDBDataSource;
com.denodo.vdb.vdbinterface.common.connection.VDBConnectionException;
java.util.*;
public class IteratorDemoClient {
public static void main(String args[]) {
(1)
(2)
(3)
(4)
(5)
String dsName = "clientDs";
String sentence = "SELECT * from view";
String url = args[0];
String login = args[1];
String passwd = args[2];
try {
VDBDataSource tempds = new VDBDataSource(dsName, "testDS", url,
login, passwd);
DataSourceLocator.addDataSource(tempds);
VDBDataSource ds = DataSourceLocator.getDataSource(dsName);
VDBConnection vdpConnection = ds.getConnection();
VQLStatement vqlStatement = vdpConnection.createVQLStatement();
vqlStatement.setPreparedStatement(sentence);
VDBResultSetIterator resultSetIterator= vqlStatement.executeQuery();
(6)
// Iterate through results
int numOfTuples = 0;
while (resultSetIterator.hasNext()) {
numOfTuples++;
StandardRowVO tuple = (StandardRowVO)resultSetIterator.next();
System.out.print(numOfTuples + ". ");
Map map = tuple.getValues();
Iterator it = map.keySet().iterator();
while(it.hasNext()) {
ValueVO valueVO = (ValueVO)map.get(it.next());
System.out.print(valueVO + "\t");
}
}
(7)
// Shows messages returned from the server
System.out.println("Messages:");
System.out.println(resultSetIterator.getMessages());
(8)
(9)
// Shows the schema of the obtained data
System.out.println("Schema:");
MetadataField[] schema = resultSetIterator.getSchema();
if (schema != null) {
for (int i=0; i<schema.length;i++) {
TypeVO type = schema[i].getType();
System.out.println(schema[i].getName() + “: “ + type);
}
System.out.println("");
}
} catch(Exception e) {
System.err.println("Error trying to access the server ... ");
} finally {
// The connection must be closed
if( vdpConnection != null) {
try {
vdpConnection.close();
} catch (VDBConnectionException e) {
System.err.println("Error closing connection ... ");
e.printStackTrace();
}
}
API de Desarrollo DataPort
14
Virtual DataPort 4.0
Guía del Desarrollador
}
}
}
Figura 4 Código de un cliente iterador asíncrono
A continuación se muestran los diferentes pasos realizados para la ejecución de la sentencia:
(1) El primer paso es localizar la información del servidor contra el que realizar la conexión. Para esta tarea
es posible o bien definir un objeto VDBDataSource a partir de los parámetros de conexión requeridos,
o bien utilizar la clase DataSourceLocator para localizar esa información a partir de un nombre (ver
5.4.1).
(2) Una vez localizada la metainformación necesaria para realizar una comunicación con el servidor, se
obtiene una conexión para dar soporte a esa comunicación (ver 5.4.2).
(3) A partir de la conexión se obtiene un objeto VQLStatement, que se prepara con la sentencia que se
desea ejecutar.
(4) En el caso de que la sentencia presentase algún parámetro variable, VQLStatement define un método
para asociar valores concretos a los parámetros.
(5) Se ejecuta la sentencia, obteniendo un iterador asíncrono con los resultados. El iterador asíncrono
proporciona también información adicional relativa a la sentencia ejecutada (ver 5.7.3)
(6) Una vez iniciada la ejecución de una consulta, hay que iterar sobre el objeto devuelto para obtener los
resultados del gestor. Por defecto, utilizando este tipo de clientes, cada tupla se representa como un objeto
StandardRowVO.
(7) Es posible también obtener los mensajes informativos o de error enviados por el gestor.
(8) El gestor también proporciona información relativa al esquema de los datos devueltos.
(9) La conexión ha de cerrarse para que sea devuelta al pool de conexiones.
5.3
ESTRUCTURA GENERAL DE LA API DE DESARROLLO DATAPORT
En la Figura 5 se muestra la estructura general de la API DataPort. El elemento esencial en las comunicaciones
cliente-servidor es la clase VDBConnection. Para establecer una conexión contra el gestor es necesario obtener
un objeto VDBDataSource a partir de la metainformación de conexión con el gestor. Utilizando la clase utilidad
DataSourceLocator se simplifica la obtención del VDBDataSource para un gestor determinado a partir
de un nombre.
DataSourceLocator
LocateDataSourceException
DataSourceException
VDBDataSource
VDBConnectionException
VDBConnection
Printer
<<use>>
VQLStatement
PartialResult
<<use>>
VDBResultSetIterator
<<use>>
StandardPrinter
API de Desarrollo DataPort
15
Virtual DataPort 4.0
Guía del Desarrollador
Figura 5 Estructura general de la API nativa
La clase VDBConnection proporciona mecanismos directos de ejecución de sentencias contra el gestor,
indicando además una clase (que extenderá Printer) para componer los resultados obtenidos. Para simplificar el
proceso de ejecución de consultas puede utilizarse la clase VQLStatement, que permite:
a) Utilizar una sentencia VQL conteniendo parámetros que serán posteriormente reescritos por unos valores
concretos (de forma similar a un PreparedStatement de JDBC)
b) Obtener un objeto que permite iterar, de forma asíncrona, sobre los resultados devueltos por el gestor.
c) Utilizar una implementación de objeto componedor de resultados por defecto (llamado
StandardPrinter, que devolverá cada tupla como un objeto de tipo StandardRowVO). Véase la
sección 5.7.3 para más detalle.
5.4
5.4.1
DATASOURCES VIRTUAL DATAPORT
DataSources
Un DataSource identifica un origen de datos del que se puede extraer información. En la API de Virtual DataPort se
representa mediante un objeto de la clase VDBDataSource.
Para definir un VDBDataSource es necesario especificar:
dataSourceName: Un nombre de DataSource.
description: Una descripción del DataSource.
dbURI: Una cadena de conexión contra el servidor (//host:port/databaseName).
userName: Un nombre de usuario para realizar la conexión
userPwd: Contraseña para el usuario.
queryTimeout: Máximo tiempo (en milisegundos) que está dispuesto a esperar la aplicación usuaria
hasta que finalice una sentencia. Este parámetro es opcional. Si no se indica (o recibe el valor 0), entonces
se espera el tiempo necesario hasta que finalice la ejecución de la sentencia.
chunkTimeout: Máximo tiempo (en milisegundos) que está dispuesto a esperar la aplicación usuaria
hasta que llegue un resultado parcial. Si se sobrepasa este tiempo, Virtual DataPort devuelve un resultado
parcial vacío. Es opcional. Si no se especifica (o recibe el valor 0), el gestor devuelve todos los resultados
conjuntamente al finalizar la ejecución de la sentencia.
chunkSize: Número de resultados que conforman un resultado parcial. Este factor, junto con el
anterior, definen el comportamiento de devolución de resultados parciales del gestor. Si Virtual DataPort
recibe este número de resultados, los reenviará al cliente aunque no se haya cumplido el tiempo máximo
de resultado parcial. Si no se especifica (o recibe el valor 0), entonces todos los resultados de la consulta
se devolverán en un único resultado parcial.
A partir de un VDBDataSource pueden obtenerse los objetos conexión para el gestor asociado a ese origen de
datos (método getConnection). Para reducir los tiempos en la creación de conexiones ante la ejecución de
sentencias contra el gestor Virtual DataPort, la clase VDBDataSource permite especificar el uso de un pool de
conexiones reutilizables. En el caso de que se desee utilizar el pool, puede indicarse su configuración con la clase
PoolConfig, indicando:
initSize: Número de conexiones con las que se desea inicializar el pool. Se establecen y crean un
número de conexiones en estado "idle", listas para ser usadas.
maxActive: Número máximo de conexiones activas que puede gestionar el pool al mismo tiempo. (cero
implica sin límite)
maxIdle: Número máximo de conexiones activas que pueden permanecer ociosas en el pool sin
necesidad de que se desocupen conexiones adicionales. (cero implica sin límite)
Para más información, ver documentación Javadoc de la API del desarrollador [3].
API de Desarrollo DataPort
16
Virtual DataPort 4.0
5.4.1.1
Guía del Desarrollador
Definición y Localización de DataSources
Para simplificar la creación de clientes, Virtual DataPort proporciona una clase utilidad,
com.denodo.vdb.vdbinterface.client.util.datasource.DataSourceLocator,
que permite obtener un VDBDataSource para un servidor DataPort a partir de su nombre.
VDBDataSource ds = DataSourceLocator.getDataSource(DATASOURCE_NAME);
Para que sea posible la localización del VDBDataSource, es necesario haberlo registrado previamente. Hay tres
formas de hacer esto:
•
La clase DataSourceLocator define un método addDataSource que permite registrar objetos
VDBDataSource creados directamente por la aplicación.
• El sistema registrará automáticamente aquellos DataSources cuyas propiedades estén accesibles en un
fichero
.properties
de
nombre
ConfigurationParameters.properties (o cualquier otro si dicho nombre se especifica con la
propiedad de la máquina virtual –DconfFile).
• El sistema registrará automáticamente aquellos DataSources cuyas propiedades estén accesibles a través
de JNDI [6] en el formato vdbDataSource.<dataSourceName>.<propertyName>. En particular
las propiedades deben de estar exportadas en un servidor JNDI colgando de la ruta java:comp/env/.
Esto permite, por ejemplo, que los DataSources puedan ser definidos en el fichero web.xml de una
aplicación web J2EE.
En la Figura 6 se muestra el nombre de todas las propiedades junto con algunos valores típicos.
# Datasource configuration used by provided clients
# to connect to Virtual DataPort.
vdbDataSource.clientDs.dbURI=//localhost:9999/vdb
vdbDataSource.clientDs.userName=demo
vdbDataSource.clientDs.userPwd=demo
vdbDataSource.clientDs.queryTimeout=80000
vdbDataSource.clientDs.chunkTimeout=90000
vdbDataSource.clientDs.chunkSize=100
# Pool parameters. Non Mandatory.
vdbDataSource.clientDs.initSize=0
vdbDataSource.clientDs.maxActive=30
vdbDataSource.clientDs.maxIdle=20
# Uncoment to disable pool.
#vdbDataSource.clientDs.poolEnabled=false
Figura 6 Configuración de un VDBDataSource
5.4.2
Conexiones Virtual DataPort
La clase VDBConnection encapsula una conexión contra un servidor Virtual DataPort. Representa un proxy a
“Virtual DataPort” (véase para más información el patrón de diseño Proxy [4]). Permite que los clientes dispongan de
un frontal sencillo para acceder al gestor, delegando en él las tareas de comunicación, y ocultando la tecnología
utilizada para la comunicación (Java RMI).
Los principales métodos de esta clase son los siguientes:
•
exec(query,printer): método que ejecuta una sentencia o query sobre el servidor. El segundo
argumento es una clase Printer. Esta clase, que se comentará con detalle más adelante, es la que
formateará los resultados recibidos desde el servidor de acuerdo con las necesidades particulares de cada
cliente.
API de Desarrollo DataPort
17
Virtual DataPort 4.0
Guía del Desarrollador
•
execDeferred(query,printer): este método también ejecuta una sentencia sobre Virtual
DataPort. La diferencia con el método exec(query,printer) está en que este último ejecuta la
sentencia e internamente solicita los resultados al gestor hasta que la consulta está completamente
finalizada, mientras que execDeferred(query,printer), simplemente ejecuta la sentencia y
retorna el control al cliente sin haber solicitado ninguno de los resultados. Para solicitar los resultados al
servidor, este método se debe combinar con getNextResult(printer) ó
getNextResult(printer,n).
•
getNextResult(printer): Este método obtiene el siguiente “chunk” de resultados (o ‘resultado
parcial’) del servidor. De nuevo la clase Printer será la encargada de ensamblar o componer el
resultado que espera recibir el cliente a partir de los datos que se reciben del servidor.
•
getNextResult(printer,n): Método similar al anterior excepto en que además se especifica
el número máximo de resultados que espera recibir el cliente.
•
openClientConnection(user,pwd,url): Método que abre una conexión con Virtual
DataPort. Si alguno de los parámetros es incorrecto, (e.g. la contraseña es incorrecta, el usuario no existe o
no se puede conectar con el servidor), este método devolverá una excepción. La utilidad de está función es
para clientes que deseen validar de forma rápida y sencilla las credenciales que introduce el usuario por
teclado (e.g. para comprobar un proceso de login).
•
cancel(): Método que detiene la ejecución de una consulta.
•
getConnectionTime(): Permite obtener el tiempo de establecimiento de conexión.
•
isCached(): Permite saber si la conexión actual ha sido obtenida de un pool de conexiones (está
siendo reutilizada) o si se ha creado una nueva.
•
close(): Método que finaliza una conexión contra un gestor (o la devuelve al pool, si se ha definido).
•
createVQLStatement(): Método que permite crear un objeto VQLStatement asociado a
este objeto conexión. Esta clase permite ejecutar sentencias parametrizadas y obtener los resultados
utilizando un iterador asíncrono (ver apartado 5.7.1)
Existen otros métodos en esta clase que son útiles para obtener y establecer los parámetros de configuración del
gestor Virtual DataPort, es decir, métodos get() y set() para el nombre del usuario, la contraseña, el
dbURI, el queryTimeout, el chunkTimeout y el chunkSize.
5.5
PROTOCOLO DE COMUNICACIONES CON EL SERVIDOR
Otro elemento relevante para la realización de una comunicación con el servidor es la jerarquía de resultados
parciales (‘chunks’ recibidos desde el servidor como respuesta a la consulta) que encapsulan los datos
intercambiados. La superclase de todos estos resultados es la clase PartialResult.
API de Desarrollo DataPort
18
Virtual DataPort 4.0
Guía del Desarrollador
PartialResult
<<setter>>+setDecorated( result : PartialResult )-decorated
: void
<<getter>>+getDecorated() : PartialResult
+accept( visitor : PartialResultVisitor ) : void
Figura 7 Superclase de todos los resultados parciales
Los tipos de resultados parciales que puede recibir un cliente son los siguientes:
•
EmptyResult: resultado parcial sin ningún tipo de datos. Lo emite el servidor cuando el cliente solicita
los resultados antes de que se disponga de algún resultado todavía no entregado.
•
EndResult: resultado parcial que emite el servidor cuando una consulta ha finalizado. Después de
recibir un mensaje de este tipo, el cliente no debe realizar otra solicitud de datos al servidor.
•
ErrorResult: resultado parcial emitido por el servidor cuando se produce un error en la ejecución de
una consulta. Se trata también de un mensaje de finalización. Después de recibir un mensaje de este tipo,
el cliente no debe de realizar otra solicitud de datos al servidor.
•
MessageResult: mensaje informativo emitido por el servidor. No es un mensaje de finalización y en
su interior contiene información sobre la ejecución de la consulta. Desde la versión 4.0, se incluye un nuevo
subtipo de mensaje llamado WarningResult, que notifica incidencias ocurridas durante la ejecución
de una sentencia.
•
MetadataResult: mensaje con los metadatos de una sentencia de tipo SELECT, QUERY WRAPPER o
CALL emitida sobre Virtual DataPort. Entre la metainformación de un conjunto de resultados se encuentra
el nombre de cada columna con su tipo (Objeto MetadataField).
•
ChunkResult: mensaje que contiene tuplas resultado de una sentencia de tipo SELECT, QUERY
WRAPPER o CALL emitida sobre el gestor.
Por otra parte, el protocolo establecido entre el cliente y el servidor para el envío y recepción de los mensajes sigue
las siguientes reglas:
•
El número de fragmentos o resultados parciales en los que puede llegar el resultado de una consulta no es
fijo.
•
La consulta se termina cuando llega un mensaje de finalización o un mensaje de error.
•
Un mensaje puede encapsular a otro mensaje (según el patrón de diseño decorador [4]). Esto permite
minimizar el número de comunicaciones entre el cliente y el servidor. Esta regla no es válida para los
mensajes de error y mensajes vacíos, que nunca pueden tener ningún otro resultado parcial en su interior.
API de Desarrollo DataPort
19
Virtual DataPort 4.0
Guía del Desarrollador
•
Si se trata de una sentencia de consulta sobre una vista (SELECT), consulta sobre un wrapper (QUERY
WRAPPER) o invocación de procedimiento almacenado (CALL), el primer mensaje que no sea vacío será el
mensaje con los metadatos referentes a la consulta efectuada (fundamentalmente, se indicarán las
columnas que componen el resultado junto con sus tipos de datos asociados). “Decorando” el mensaje de
metainformación se envía otro mensaje informativo (MessageResult) que encapsula el mapa de
propiedades de internacionalización (I18nVO) de la consulta. En la Guía avanzada de VQL [2] puede
encontrarse el listado de nombres de propiedades de internacionalización que encapsula.
•
Un mensaje de error puede contener un mensaje explicativo y un código que indique el tipo de error que se
ha producido (e.g. un error interno dentro del gestor, un error del usuario en la introducción de los datos,
etc.
Véase
la
documentación
Javadoc
[3]
de
la
clase
com.denodo.vdb.vdbinterface.common.clientResult.ErrorCodes, para el
detalle de los códigos de error posibles).
En el siguiente diagrama se muestra de forma más detallada la jerarquía de los resultados parciales, con todos los
tipos de mensajes que puede enviar el servidor como resultado de una consulta.
PartialResult
ChunkResult
EmptyResult
EndResult
ErrorResult
<<use>>
MessageResult
MetadataResult
WarningResult
1..*
ErrorCodes
MetadataField
-_name : String = null
+NO_ERROR : int = 0{readOnly}
-_type : TypeVO = null
+SYNTAX_ERROR : int = 1{readOnly}
...
+OBJECT_NOT_FOUND : int = 2{readOnly}
+SEMANTIC_ERROR : int = 3{readOnly}
<<setter>>+setName(
value : String ) : void
+INTERNAL_ERROR : int = 4{readOnly}
<<getter>>+getName() : String
+STORE_ERROR : int = 5{readOnly}
<<setter>>+setType( value : TypeVO ) : void
+UNABLE_TO_CONNECT : int = 6{readOnly}
: TypeVO
+ERROR_GETTING_RESULTS : int = 7{readOnly} <<getter>>+getType()
...
+DEPENDS_ON_DELETE : int = 8{readOnly}
+NOTSUPPORTED_OPERATION : int = 9{readOnly}
+DUPLICATE_OBJECT : int = 10{readOnly}
+INSUFFICIENT_PRIVILEGES : int = 11{readOnly}
+LICENSE_ERROR : int = 12{readOnly}
+SYNCHRONIZE_ERROR : int = 13{readOnly}
+UNKNOWN : int = 99{readOnly}
...
Figura 8 Jerarquía de resultados parciales
Como ya se ha comentado, cuando se emite una sentencia de consulta (SELECT) sobre Virtual DataPort, el cliente
obtiene un ChunkResult. Dentro de un objeto ChunkResult, hay un conjunto de tuplas (ChunkRow), y
cada tupla contiene un conjunto de valores (ValueVO). Un valor puede ser simple (SimpleVO), de tipo array
(ArrayVO) o de tipo registro (RegisterVO). Los valores simples (SimpleVO) pueden ser de cada uno de los
tipos de dato soportados (ver [2]). Por ejemplo: enteros (IntVO), fecha (DateVO), etc.
A su vez, un MessageResult, puede tener encapsulado además de un mensaje informativo, un objeto de tipo
MessageVO que puede ser de tipo descriptivo (VDBObject) o de tipo listado (VDBObjectList). Desde la
versión 4.0, se añade un subtipo WarningResult que contiene notificaciones sobre eventos producidos durante
la ejecución.
API de Desarrollo DataPort
20
Virtual DataPort 4.0
Guía del Desarrollador
Existe un objeto VDBObject por cada elemento del catálogo de Virtual DataPort (wrapper, vista base o derivada,
procedimiento almacenado, operador, tipo, etc. Véase [1] para más detalle sobre estos elementos) cuya descripción
se puede solicitar al gestor. También existe un objeto VDBObject para representar la traza de ejecución de una
sentencia (ver sección 5.7.4).
Para conocer en detalle la estructura de los resultados parciales que puede recibir un cliente, se puede consultar la
documentación Javadoc [3].
5.6
PROCESAMIENTO DE RESULTADOS DE UNA CONSULTA
Las necesidades de las distintas aplicaciones cliente en cuanto al formato deseado para recibir los resultados de una
consulta sobre DataPort pueden diferir mucho.
Por ello la solución adoptada en DataPort separa la lógica de comunicación, de la cual se encarga el objeto conexión,
de la lógica de transformación y ensamblado de los resultados parciales que van siendo devueltos desde el servidor,
de la cual se encargará una nueva jerarquía de clases que tienen como superclase a la clase Printer. De este
modo, con la aparición de un nuevo tipo de cliente, sólo se tendrá que proporcionar una nueva subclase de
Printer, que transforme los resultados que llegan desde el servidor.
PartialResultVisitor
+format( result : EmptyResult ) : void
+format( result : EndResult ) : void
+format( result : ChunkResult ) : void
+format( result : MetadataResult ) : void
+format( result : MessageResult ) : void
+format( result : WarningResult ) : void
+format( result : ErrorResult ) : void
Printer
<<getter>>+isFinished() : boolean
<<setter>>+setFinished( flag : boolean ) : v
+format( result : EmptyResult ) : void
+format( result : EndResult ) : void
+format( result : ChunkResult ) : void
+format( result : MetadataResult ) : void
+format( result : MessageResult ) : void
+format( result : WarningResult ) : void
+format( result : ErrorResult ) : void
+format( exception : Exception ) : Object
<<getter>>+getClientResult() : Object
+log( message : String ) : void
<<getter>>+getErrorCode() : int
+reset() : void
Figura 9 Estructura general de un ensamblador de resultados
Un desarrollador puede crear sus propias clases Printer o puede utilizar algunas de las implementaciones que
Virtual DataPort incluye y que son adecuadas para la mayoría de casos (paquete
com.denodo.vdb.vdbinterface.client.printer):
API de Desarrollo DataPort
21
Virtual DataPort 4.0
Guía del Desarrollador
•
ConsolePrinter. Formatea textualmente los resultados y los envía a un stream de salida (como, por
ejemplo a la salida estándar).
•
standard.StandardPrinter: Clase Printer que ensambla los resultados de cualquier tipo
de sentencia emitida sobre Virtual DataPort. Los resultados, así como el plan de ejecución asociado, son
devueltos encapsulados en el objeto standard.StandardTableVO. Un objeto
StandardTableVO define métodos para obtener las tuplas de resultados del gestor (getRows()),
el esquema de los datos devueltos (getSchema()), los mensajes incluidos en la respuesta como un
String (getMessage()) y la traza de eventos asociada a la consulta (getTrace()). Cada tupla del
resultado será devuelta como un objeto StandardRowVO que contendrá un campo por cada atributo
presente en la respuesta.
Consúltese la documentación Javadoc [3] para obtener información detallada sobre la estructura de las clases
Printer predefinidas.
5.6.1
Implementación de Nuevos Ensambladores de Resultados
Para aquellos casos en los que se desee añadir una nueva implementación para Printer, en la Figura 9 se
muestran los métodos que deben implementar todas las instancias de la misma. En primer lugar debe definirse cómo
formatear todos los tipos de mensajes que se pueden generar: esto se realiza implementando una serie de métodos
de la interfaz PartialResultVisitor. También deben implementarse o redefinirse los siguientes métodos
de la clase Printer:
• isFinished(): método que devuelve verdadero (true) cuando el printer determina que la consulta
ha finalizado. Como el printer es quien procesa los mensajes recibidos por el cliente, es éste quien
debe decidir cuándo una consulta ha finalizado. Típicamente, esto sucede cuando llega un mensaje de error
o un mensaje de finalización; aunque nada impide que un printer, por las características intrínsecas de
un tipo de cliente, finalice prematuramente una consulta.
•
setFinished(boolean): método que permite finalizar manualmente una consulta. Un ejemplo de
uso de esta característica podría ser cuando se pulsa un botón de cancelación en una ventana de una
herramienta gráfica.
•
getClientResult(): método que devuelve el resultado de la consulta adaptado al formato que
espera recibir el cliente.
•
log(String): método que permite hacer un log de las operaciones que va realizando el cliente. Cada
subclase debe redefinir este método para redirigir los mensajes a la salida adecuada según el cliente. Por
ejemplo, un cliente de línea de comandos debe redirigir estos mensajes a la salida estándar y un cliente
gráfico debe redirigir los mensajes a una ventana gráfica.
•
getErrorCode(): si se produce un error, con este método se podrá extraer el tipo de error que se ha
producido durante la ejecución de la consulta. Véase la documentación Javadoc [3] para obtener una lista
de los códigos de error posibles, con su correspondiente descripción.
•
reset(): método que restaura el estado de la clase para finalizar una consulta e iniciar una nueva.
API de Desarrollo DataPort
22
Virtual DataPort 4.0
•
Guía del Desarrollador
format(Exception): método para formatear los errores no controlados y por lo tanto aquellos que
generan una excepción. Las excepciones también pueden necesitar un procesado diferente según el tipo de
cliente. Es el printer quien debe encargarse de su procesado.
A modo de ejemplo, la Figura 10 muestra la implementación del Printer predefinido ConsolePrinter, que
formatea textualmente los resultados obtenidos y los escribe en un stream de salida (por defecto, la salida estándar).
// Import needed for the log
import java.io.PrintStream;
import java.util.Iterator;
import com.denodo.vdb.vdbinterface.client.printer.Printer;
import com.denodo.vdb.vdbinterface.common.clientResult.ChunkResult;
import com.denodo.vdb.vdbinterface.common.clientResult.EmptyResult;
import com.denodo.vdb.vdbinterface.common.clientResult.EndResult;
import com.denodo.vdb.vdbinterface.common.clientResult.ErrorResult;
import com.denodo.vdb.vdbinterface.common.clientResult.MessageResult;
import com.denodo.vdb.vdbinterface.common.clientResult.MetadataField;
import com.denodo.vdb.vdbinterface.common.clientResult.MetadataResult;
import com.denodo.vdb.vdbinterface.common.clientResult.VQLException;
import com.denodo.vdb.vdbinterface.common.clientResult.vo.sentences.ChunkRow;
import com.denodo.vdb.vdbinterface.common.clientResult.vo.sentences.ValueVO;
/**
* Asynchronous printer, receives a query result and forward it to a
* PrintStream like the standar output or a file.
*/
public class ConsolePrinter extends Printer{
/**
* The Stream the output will be forwarded to. Standard output by
* default.
*/
private PrintStream _out=System.out;
/**
* Temporal metadata container.
*/
private String _metadata=null;
/**
* Empty Constructor.
*/
public ConsolePrinter() {}
/**
* Constructor that replaces the output stream the printer will use.
* @param out New output stream.
*/
public ConsolePrinter(PrintStream out){_out=out;}
/**
* Defins the behavior when an empty result arrives.
* @param result Empty message.
*/
public void format(EmptyResult result) throws VQLException {
log("Info: received new empty result");
}
/**
* Defines the behavior when a finalization message arrives from
* the server.
API de Desarrollo DataPort
23
Virtual DataPort 4.0
Guía del Desarrollador
* @param result Finalization message.
*/
public void format(EndResult result) throws VQLException {
_out.println("_________________________");
log("Info: received end result");
setFinished(true);
if (result.getDecorated()!=null) {
result.getDecorated().accept(this);
}
}
/**
* Defines the behavior when a chunk arrives from the server.
* @param result Partial result message.
*/
public void format(ChunkResult result) throws VQLException {
log("Info: received new chunk result");
Iterator chunkRows=result.getResults().iterator();
while (chunkRows.hasNext()) {
_out.print("| ");
ChunkRow singleRow=(ChunkRow)chunkRows.next();
Iterator values=singleRow.getValues().iterator();
while (values.hasNext()) {
_out.print((ValueVO)values.next() + " | ");
}
_out.println();
}
if (result.getDecorated()!=null) {
result.getDecorated().accept(this);
}
}
/**
* Defines the behavior when a message with the metadata from a query
* arrives from the server.
* @param result Message with the metadata.
*/
public void format(MetadataResult result) throws VQLException {
log("Info: received metadata result");
_metadata=new String("[ ");
Iterator fields=result.getFields().iterator();
while (fields.hasNext()) {
MetadataField field=(MetadataField)fields.next();
_metadata=_metadata+(field.getName()) + " ";
}
_metadata=_metadata+"]\n";
log(_metadata);
if (result.getDecorated()!=null) {
result.getDecorated().accept(this);
}
}
/**
* Defines the behavior when an informative
* message arrives from the server.
* @param result Informative message.
*/
public void format(MessageResult result) throws VQLException {
log("Info: received message result");
if(result.getMessage()!=null)log(result.getMessage());
if(result.getObject()!=null)log(result.getObject().toString());
if (result.getDecorated()!=null){
result.getDecorated().accept(this);
API de Desarrollo DataPort
24
Virtual DataPort 4.0
Guía del Desarrollador
}
}
/**
* Defines the behavior when an error message arrives.
* @param result Error message.
*/
public void format(ErrorResult result) throws VQLException {
setFinished(true);
log(result.getMessage());
if (result.getDecorated()!=null) {
result.getDecorated().accept(this);
}
}
/**
* Defines the behavior when an exception is generated during a query.
* @param exception gemerated exception.
*/
public Object format(Exception exception) throws VQLException{
log("error: "+ exception.getMessage());
return null;
}
/**
* Forwards the message to the output stream.
*/
public void log(String message){
_out.println(message);
}
}
Figura 10 Código de ConsolePrinter
5.7
MODOS DE FUNCIONAMIENTO GENERAL DE UN CLIENTE
En este apartado se va a mostrar el método general de creación de un nuevo cliente para el gestor Virtual DataPort
utilizando la API JAVA nativa.
Existen tres formas típicas de crear un cliente, dependiendo del nivel de control que se desee tener sobre el flujo de
datos con el servidor tras el envío de la consulta:
•
•
•
Cliente síncrono. En este caso, el cliente, tras emitir una consulta, queda bloqueado hasta que se obtienen
todos los resultados de la misma.
Cliente asíncrono. Este modo permite un mayor control de los intercambios de datos con el servidor. Está
especialmente indicado para poder procesar los resultados de una consulta a medida que están
disponibles, sin necesidad de esperar a que la consulta haya terminado.
Cliente iterador asíncrono. Es un caso particular de cliente asíncrono que se ofrece ya implementado por
conveniencia para el desarrollador. Es la opción recomendada para la mayor parte de aplicaciones
cliente.
Los detalles de cada uno de estos tipos de cliente se describen en los siguientes subapartados.
API de Desarrollo DataPort
25
Virtual DataPort 4.0
5.7.1
Guía del Desarrollador
Clientes Síncronos – Requieren control sobre el flujo de datos
En este caso, el cliente, tras emitir una consulta, queda bloqueado hasta que se obtienen todos los resultados de la
misma en un único bloque.
La creación de este tipo de clientes es muy sencilla y sólo se deben realizar las dos acciones siguientes:
a)
Implementar el Printer que ensamblará los resultados o utilizar alguno de los ya proporcionados con
Virtual DataPort. Ver sección 5.6.
b)
Invocar el método exec(query,printer) de la clase VDBConnection. Este método se
encargará de solicitar todos los datos al gestor hasta que la transmisión haya concluido. El resultado que
devuelve esta función es el objeto que ha compuesto la clase Printer a medida que los resultados
parciales han ido llegando desde el servidor. Un aspecto importante es que la aplicación no retorna el
control hasta que el proceso de comunicación ha finalizado completamente.
Un ejemplo de los pasos a seguir para ejecutar una sentencia sobre Virtual DataPort siguiendo este método se
muestra en la Figura 11 (se utiliza el Printer predefinido ConsolePrinter):
// Sentence to execute against the server
String sentence = ”SELECT * FROM @ecb”;
// The printer for assembling query results must be chosen
Printer assembler = new ConsolePrinter(System.out);
try {
// We get a connection to Virtual DataPort
VDBDataSource ds = DataSourceLocator.getDataSource("clientDs");
VDBConnection connection = ds.getConnection();
Object result = null;
// Query is executed. The format of the final result is determined
// by the printer.
result = connection.exec(sentence, assembler) ;
} catch(Exception ex){
ex.printStackTrace();
} finally {
// The connection must be closed.
if( vdpConnection != null) {
try {
vdpConnection.close();
} catch (VDBConnectionException e) {
System.err.println("Error closing connection ... ");
e.printStackTrace();
}
}
}
Figura 11 Código de un cliente síncrono
5.7.2
Clientes Asíncronos – No requieren control sobre el flujo de datos
El modo asíncrono permite un control mayor sobre el intercambio de datos con el servidor. Una de sus principales
ventajas es que permite a la aplicación cliente obtener los resultados de una consulta a medida que estos van
estando disponibles, sin necesidad de esperar a que la consulta haya terminado.
API de Desarrollo DataPort
26
Virtual DataPort 4.0
Guía del Desarrollador
En el modo asíncrono, la aplicación cliente solicitará al servidor nuevos datos cuando lo crea conveniente, no
quedando bloqueado tras la emisión de la consulta. También podrá especificar el número máximo de resultados de la
consulta que espera recibir en cada una de las transmisiones que el servidor realice.
Los pasos para la construcción de este tipo de clientes son los siguientes:
a)
Realizar la implementación de la clase o clases Printer que ensamblarán los resultados (ahora se
realizarán varias llamadas a métodos de la clase VDBConnection y podría darse el caso de que en
cada llamada se usara un Printer diferente). También puede utilizarse alguno de los Printers ya
incluidos con DataPort para evitar crear uno nuevo.
b)
Invocar el método de la clase VDBConnection execDeferred(query,printer). Este
método sólo envía la consulta al gestor, sin solicitarle el envío de ningún resultado y retornando el control
al cliente. En este caso la clase Printer que se pasa como argumento es necesaria sólo por si se
produce un error en el envío de la consulta.
c)
Realizar
la
invocación
de
los
métodos
getNextResult(printer)
o
getNextResult(printer,n) de la clase VDBConnection para realizar las peticiones de
datos que se necesiten. En este caso, el cliente va a trabajar con mayor control sobre el intercambio de
datos, por lo que debe conocer las reglas de envío de resultados parciales que usa el servidor, y que están
comentadas en apartados anteriores de este documento.
En la Figura 12 se muestra un ejemplo de implementación de este tipo de clientes.
// The sentence we want to execute
String sentence = ”SELECT * FROM view”;
Printer printer = new StandardPrinter();
try {
VDBDataSource ds = DataSourceLocator.getDataSource("clientDs");
VDBConnection connection = ds.getConnection();
connection.execDeferred(sentence, printer);
while (!printer.isFinished()) {
// Each call returns the same result object but
// it contains more elements each time
StandardTableVO standardVO = (StandardTableVO) vdpConnection
.getNextResult(printer, 2);
}
} catch(Exception ex){
ex.printStackTrace();
} finally {
// The connection must be closed.
if( vdpConnection != null) {
try {
vdpConnection.close();
} catch (VDBConnectionException e) {
System.err.println("Error closing connection ... ");
e.printStackTrace();
}
}
}
Figura 12 Código de un cliente asíncrono
API de Desarrollo DataPort
27
Virtual DataPort 4.0
5.7.3
Guía del Desarrollador
Cliente Iterador Asíncrono
Este tipo de cliente es una implementación particular de cliente asíncrono que se proporciona por conveniencia para
el
desarrollador.
Es
implementado
por
la
clase
com.denodo.vdb.vdbinterface.client.util.iterator.VDBResultSetIterator.
Este cliente obtiene los resultados de forma asíncrona y los compone a través del ensamblador
StandardPrinter. Internamente genera un objeto StandardTableVO con los resultados.
La ejecución de una consulta con este cliente se puede realizar a través del objeto VQLStatement creado a
partir de una conexión a un gestor Virtual DataPort.
Un objeto VQLStatement permite la ejecución de sentencias VQL parametrizadas, de forma análoga a la clase
PreparedStatement de la API JDBC [5] de Java. Las sentencias VQL deben incluir los parámetros con la
sintaxis ?<parameterIdentifier> y se asocian al VQLStatement con el método
setPreparedStatement(String).
Si los parámetros se sustituyen indicando una lista (método setParameters(List)), entonces en la
sentencia deben de aparecer de forma numerada, empezando en 1. Por ejemplo: SELECT * FROM xyz WHERE
a > ?1 and b < ?2.
Si se utiliza la opción de enviar los parámetros en un mapa (pares nombre,valor, método
setParameters(Map)), entonces se sustituirán por las ocurrencias ?<parameterIdentifier> en la
sentencia.
Para ejecutar la sentencia se utiliza el método executeQuery() obteniendo un objeto
VDBResultSetIterator que implementa la interfaz Java java.util.Iterator. Cada tupla devuelta
se representa mediante un objeto StandardRowVO con un campo por cada atributo del esquema de salida de la
consulta.
Es necesario utilizar el método hasNext() del objeto VDBResultSetIterator cuando se desee iterar
sobre los resultados. Esto es debido a que la espera asíncrona se encuentra implementada en este método, de
manera que espera hasta que haya datos disponibles. El método next() de la misma clase lanza una excepción
NoSuchElementException si no hay datos disponibles, aunque estén llegando; por ello es necesario utilizar
antes el método hasNext().
En la Figura 4 se puede ver un ejemplo de implementación completa de este tipo de clientes.
5.7.4
Información sobre la Traza de Ejecución de Sentencias
La traza de una sentencia permite un examen detallado de su plan de ejecución. Dicho plan se presenta al
administrador en la forma de un árbol, donde cada nodo representa una vista intermedia involucrada en la ejecución
de la consulta o un acceso a una fuente a través de un wrapper. Para cada nodo en el árbol de ejecución de la
consulta, se muestran sus parámetros más relevantes. Entre estos parámetros se encuentran:
• Tipo de nodo. Si el nodo es una vista, indica el tipo de vista de que se trata (vista base, unión, join,
proyección,…). Si se trata de un acceso a una fuente (wrapper), se indica el tipo de fuente (JDBC, Web
Service, Web, …).
• Tiempo de ejecución. Tiempo invertido en la ejecución completa del nodo y de todos sus hijos.
• Momento de inicio. Momento exacto en el que se inicia el procesamiento del nodo en el plan de ejecución.
• Momento de fin de la consulta. Momento exacto en el que se finaliza el procesamiento del nodo (y de
todos sus hijos) en el plan de ejecución.
• Tiempo de obtención de primera tupla de resultados. Tiempo transcurrido hasta que el nodo recibió la
primera tupla a procesar.
API de Desarrollo DataPort
28
Virtual DataPort 4.0
•
•
•
Guía del Desarrollador
Número de tuplas procesadas. Número de tuplas procesadas por el nodo.
Estado. Indica si el nodo se ejecutó correctamente o se produjo algún error.
Parámetros avanzados. Proporcionan más detalle sobre cada tipo de nodo. Por ejemplo:
o En el caso de nodos de tipo wrapper, se indican las subconsultas exactas ejecutadas sobre cada
fuente de datos, así como los datos de conexión utilizados para acceder a cada una de ellas.
o Para cada nodo de tipo vista, se indica si se ha utilizado o no la cache, si ha sido necesario
realizar swapping, si existen reglas de reescritura asociadas a la misma, etc.
Una de las principales utilidades de la funcionalidad de traza es la depuración en el caso de que se produzcan
condiciones de error. Desde la herramienta de administración de Virtual DataPort se puede acceder a estos datos de
manera gráfica (ver la Guía de Administración de Virtual DataPort [1] para más información).
El API de Virtual DataPort permite acceder a la información de la traza del plan de ejecución. Para ello, es necesario
obtener
una
instancia
de
la
clase
com.denodo.vdb.vdbinterface.common.clientResult.vo.descriptions.queryp
lan.ExecutionPlanVO mediante la utilización del método public ExecutionPlanVO
getExecutionPlan()
de
la
clase
com.denodo.vdb.vdbinterface.client.util.iterator.VDBResultSetIterator.
Esta clase dispone de una serie de métodos de acceso a información del plan de ejecución, como el nombre de la
vista a la que se accede, el número de tuplas que esa vista concreta ha devuelto, si la vista ha completado su
proceso de extracción de datos, etc., tal y como se ha comentado anteriormente (para más información, véase la
documentación JavaDoc [3]).
El método List getSubExecutionPlans() devuelve los nodos hijo del nodo padre correspondiente, lo
cuál permite ir navegando por la estructura arbórea del plan de ejecución hasta los propios dataSources (que ya no
tienen hijos, devolviendo este método el valor null).
Es importante recordar que para que el método getExecutionPlan() devuelva una instancia de la clase
que encapsula el plan de ejecución, la consulta VQL ha de realizarse añadiendo la cláusula “TRACE” (p.e. “select
* from view trace”).
Dependiendo del tipo de nodo (vista, wrapper, procedimiento almacenado, …), existen diferentes subclases de
ExecutionPlanVO, con acceso a parámetros de información adicionales (para más información, ver la
descripción de las clases en la documentación JavaDoc [3]):
com.denodo.vdb.vdbinterface.common.clientResult.vo.descriptions.
queryplan.vdb.IDUAccessPlanVO para planes de inserción, actualización y/o borrado,
com.denodo.vdb.vdbinterface.common.clientResult.vo.descriptions.
queryplan.StoredProcedurePlanVO para procedimientos almacenados,
com.denodo.vdb.vdbinterface.common.clientResult.vo.descriptions.
queryplan.vdb.VDBAccessPlanVO para vistas.
com.denodo.vdb.vdbinterface.common.clientResult.vo.descriptions.
queryplan.wrapper.WrapperPlanVO para wrappers.
API de Desarrollo DataPort
29
Virtual DataPort 4.0
Guía del Desarrollador
BIBLIOGRAFÍA
[1] Guía del Administrador de Virtual DataPort, versión 4.0. Denodo Technologies, 2007.
[2] Guía Avanzada de VQL de Virtual DataPort, versión 4.0. Denodo Technologies, 2007.
[3] Documentación Javadoc del API del Desarrollador. DENODO_HOME/docs/vdp/api/index.html
[4] Design Patterns. Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Addison-Wesley. 1994. ISBN:
0201633612
[5] http://java.sun.com/products/jdbc/
[6] Java Naming and Directory Interface (JNDI). http://java.sun.com/products/jndi/
[7] Web Services Description Language (WSDL). http://www.w3.org/TR/wsdl
[8] Apache Tomcat. http://tomcat.apache.org/
[9] Apache Axis. http://ws.apache.org/axis/
[10] Microsoft Open DataBase Connectivity (ODBC). http://www.microsoft.com/odbc
[11] EasySoft Corporation. http://www.easysoft.com
[12] OpenLink Corporation. http://www.openlinksw.com
Bibliografía
30
Descargar