Inicio > Business Analytics > Uso de servicios REST y ficheros complejos con ODI 12c (I)

Uso de servicios REST y ficheros complejos con ODI 12c (I)

odirwsHace unos días me encontré frente a una tabla de direcciones con coordenadas UTMS en la que faltaban las coordenadas de diez registros de entre más de tres mil. Iniciar el proceso para que los usuarios afectados actualizasen los datos de los registros de su responsabilidad llevaría inevitablemente cierto tiempo hasta su resolución, así que decidí echar mano de Google.
Rápidamente identifiqué la API necesaria (Geocoding) y elegí el formato  para la respuesta. Verifiqué el funcionamiento con una invocación manual, exploré el fichero .json de respuesta (> 6Kb) y hallé los 50 bytes con los datos que buscaba. Los comprobé con la función inversa, introduciendo las coordenadas obtenidas en Google Maps, que me ubicó en la dirección original. Veamos un ejemplo:

https://maps.googleapis.com/maps/api/geocode/json?address=Aragó+180,+Barcelona&key=************************

Tras esta verificación pensé: ya sólo me faltan nueve. Así que siendo pragmático, hice unos cuantos cut&paste y completé en unos minutos las coordenadas de los diez registros. Pero me quedé con una inquietud: ¿qué habría ocurrido si en lugar de sólo diez hubieran habido más de tres mil registros sin coordenadas?
La respuesta fue clara: automatizarlo con ODI. Y así fue como se originó la decisión de escribir este post, ilustrando la solución a dos necesidades bastante cotidianas:

  • Utilizar un servicio REST para obtener datos de la web
  • Procesar un fichero JSON

Tanto el orden de las necesidades como “el sentido” del flujo de datos pueden variar, así como su relación con alguna de las tablas en BD (que en nuestro caso, será una tabla con direcciones), no obstante espero que el ejemplo sea suficientemente ilustrativo.
Una segunda motivación para este post es la “actualización de conocimientos”. Estas dos tareas ya eran posibles con ODI 11g, pero veremos que ODI 12c simplifica su ejecución y a la vez nos ayuda a conservar los desarrollos más ordenados.

Utilizar un servicio REST para obtener datos externos

La llamada es sencilla, la API sólo requiere dos parámetros:

  • la dirección buscada (formateando adecuadamente los espacios, numeración y comas)
  • la clave de desarrollador para poder utilizar la API (que es constante)

Quizá lo más complicado sea parsear la respuesta, pues hay cierta redundancia de datos, y utilizar el formato XML en lugar de JSON tampoco variaría mucho. Así pues, iremos por partes: primero obtendremos los datos de la respuesta del servicio y después procesaremos la respuesta (fichero .json).
Para configurar el servicio, lo primero que necesitamos crear es un “Data Server” al que llamaremos “GoogleGeocod”, que apuntará a la URL del endpoint del servicio REST: https://maps.googleapis.com.
Acto seguido, crearemos un esquema físico bajo el nuevo servicio:

ps_geocode

En él utilizaremos como URI el recurso correspondiente al formato json: /maps/api/geocode/json.

ds_geocode

A continuación pasaremos a la pestaña “Operaciones”, donde definiremos una operación “GET” para realizar la llamada que nos devuelva la coordenadas. En la casilla QueryParameter especificaremos los parámetros necesarios para la llamada al servicio (como hemos visto en el ejemplo):

  • address. Asignaremos como valor una variable de Proyecto, a la que hemos llamado #P_ADDRESS
  • key. Será un literal con el valor de nuestra clave obtenida para el uso de la API (ocultada por seguridad, pero debemos introducir en este momento la clave)

addParams

Para invocar servicios más complejos que lo requieran, podría ser necesario declarar en este momento “Header Parameters” o “Template Parameters”. Lo haríamos de similar manera en las columnas respectivas.
Aquí mismo podríamos declarar otras operaciones (llamadas a la misma API con diferentes parámetros) o llamadas a otras funcionalidades diferentes ofrecidas por google bajo maps.googleapis.com para su uso en otros proyectos.
Hecho esto, ya sólo falta desarrollar un paquete que encapsule y coordine la ejecución ordenada de las siguientes tareas:

  • Iteración que procese todos los registros de la tabla de direcciones
  • Inicializar la variable #P_ADDRESS usada como parámetro
  • La llamada al servicio REST
  • La llamada al maping que procese el fichero de respuesta y actualice la tabla de direcciones

El paquete, al que llamaremos “GetCoordinates” utilizará la ODI Tool OdiInvokeRESTfulService, piedra filosofal de esta solución, de la que encontraremos la descripción detallada de los parámetros en la documentación oficial.

Getutms_Package

El paquete utilizará un par de variables para controlar la iteración, además de P_ADDRESS, que ya utilizamos en la declaración de las operaciones del servicio y a la que asignamos la dirección para la que buscamos las coordenadas (recuperada de la tabla vía refresh de la variable).

En nuestro ejemplo, establecemos las siguientes propiedades del paso “GetCoordinates”

Propiedad

Valor

Observaciones

Context

Global

Logical Schema

GeoCode

Main Operation

getCoordinates

Nombre con que declaramos la operación en el esquema físico bajo la tecnología RESTFul Service en la topología

Request Template

[P_ADDRESS=#P_ADDRESS]

Damos valor a los parámetros “variables”, en nuestro caso la cadena con la dirección para la que buscamos las coordenadas

Response File

<path_fichero.json>

Podemos utilizar un literal y sobre escribir el fichero en cada iteracción, o una segunda variable para diferenciar los nombres de fichero y que permita identificar su contenido.

Append response file

No

Para separar cada respuesta en un fichero. Indicaríamos Yes para ir añadiendo las respuestas sobre un único fichero

Retry Count

Número de reintentos antes de dar la petición por fallida (en caso de errores 502, 503 o 504). Valor por defecto=3.

Retry Interval (ms)

3000

Milisegundos de espera entre reintentos

Trace File

<path_fichero.trc>

Nombre del fichero de traza con los parámetros de invocación, status e información de la respuesta. Es opcional y lo informaremos en esto momento para ver los detalles, pero no lo usaremos en producción salvo cuando necesitemos depurar.

Append trace file

No

Nuestra llamada es sencilla y estos parámetros son suficientes, pero la ODI Tool OdiInvokeRESTfulService nos permite también trabajar con otros dos tipos de escenarios de llamadas a REST Webservices más complejos:

  • Paginación
  • Subida troceada (”Chunk upload”)

En dichos escenarios será útil saber que existen propiedades adicionales para manejar su complejidad, entre las que cabe destacar las siguientes.

Propiedad

Observaciones

Next Request Resolver

Permite utilizar expresiones XPATH o JSONPath para extraer información a utilizar en las invocaciones sucesivas.

Total Count Field Resolver

Cuando el servicio es paginado y la respuesta contiene el número de registros, éste será extraído utilizando nuevamente una expresión XPATH o JSONPath.

Response Data Container

Nueva expresión XPATH o JSONPath para extraer los datos de la respuesta; su valor deberá ser acumulado para obtener la respuesta total

Resolver Overwrite Class

Si determinar la siguiente página es tan complicado que el uso del parámetro NEXT_REQUEST_RESOLVER no es suficiente, podemos implementar nuestra propia clase java e indicarla en este parámetro

Llegados a este punto, vamos a reflexionar sobre lo que hemos visto en esta primera parte del post:

  • Invocar un WEBService REST ha sido muy fácil (de acuerdo, la función es muy simple), pero si “googleamos” un poco, veremos que hacer lo mismo en la versión 11g de ODI, requería teclear mucho más.
  • ODI 12c nos ayuda a reutilizar código, pues los WS quedan “inventariados” bajo la topología física junto con todas las operaciones declaradas,  y permite que estén disponibles para futuros desarrollos, a la vez que reduce su mantenimiento. Por ejemplo, si cambiáramos la clave de desarrollador para una API concreta, actualizarla en un único sitio sería suficiente, mientras que en 11g sería necesario abrir todos los paquetes en los que su contenido fuera susceptible de uso y análisis (aunque si hemos sido ordenados definiendo y almacenando los request files utilizados, el trabajo podría ser menor).

En la segunda parte de este post nos ocuparemos del procesamiento del fichero .json con la respuesta obtenida del servicio y su actualización en BD.

  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: