sábado, 26 de septiembre de 2015

"IMPORTANCIA DE 'LOG' EN LOS SERVICIOS"


El manejo de LOGs a nivel de servicios es muy importante, ya que en el refleja la traza de cómo el flujo de los mensajes se va transmitiendo entre servicio y servicio. Este manejo de LOGs debe ser realizado de la mano con un mecanismo estandarizado de auditoría en donde el 'idTransaccion' refleje la relación que existe de las trazas generadas en los servidores distribuidos, a nivel de servicios. Esto permitirá a los administradores de servidores y/o operadores de estos poder identificar, ante alguna caída de un servicio embebido dentro del servicio compuesto, la causa exacta del problema.

En lo relacionado a ¿Que debemos imprimir en los LOGs?, esto es muy importante ya que recordemos que los LOGs no deben ser gigantes, ya que estos se almacenan en disco. Debido a ello, se debe estandarizar que es lo que debemos imprimir en ellos. Una recomendación para esta tarea de manejo de LOG es la siguiente:

  • Cada línea de LOG generada, debe indicar: "Fecha, Hora y idTransaccion", muy a parte del mensaje que se desea imprimir.
  • Se debe imprimir todo mensaje REQUEST y RESPONSE de cada servicio compuesto.
  • Se debe de imprimir el tiempo de duración en segundos y/o milisegundos, al final de cada servicio compuesto.
  • Se debe imprimir todo mensaje REQUEST y RESPONSE de cada servicio ‘proxy client’ que se consume en el flujo.
  • Se debe de imprimir datos importantes de los servicios o BD como: "URL endPoint, nombre PACKAGE/OWNER/PROCEDURE, nombre JNDI, etc"
  • No se deben imprimir datos como passwords (si lo hacen deben figurar como encriptados).
  • No se deben imprimir un llamado a LOG dentro de un bucle (dentro de una lógica), que podría generar, en algún posible escenario, infinita generación de LOG.   

Estas son algunas de las recomendaciones para la aplicación de LOGs respectivamente. Por otro lado, es muy importante que los servicios no manejen 'System.out' embebidos (si es que están desarrollado en JAVA), ya que estos escriben directamente en la consola del server. Debido a este problema, en algunos proyectos SOA se acostumbra destinar un servicio de tipo 'Util' a este trabajo de Loggin (siguiendo la orientación de servicios), para que ante cada necesidad de impresión de LOG se invoque a dicho servicio. Desde mi punto de vista, por un lado está bien la lógica según la orientación respectiva, pero analizando este servicio por cada Request y Response que se realice ¿cuantas veces será invocado?, debido a ello en otros proyectos para este tipo de tareas se elimina el manejo de este servicio como utilitario y se reemplaza por el manejo de un ‘Framework de loggin’, Debido a ello en la actualidad hay varios opciones entre las que resalta la 'LO4J', que permite la realización de este labor de manera rápida, configurable por niveles (INFO, DEBUG, ERROR, etc) y fácilmente integrable a servidores de aplicaciones como Weblogic, WAS, etc, de manera externa a la aplicación.

Esto quiere decir que los administradores de servidores, mediante su manejo pueden definir una ruta absoluta fija en los servidores, destinada a la generación de archivos logs de todas las aplicaciones corriendo en los servidores, para que antes cualquier necesidad de búsqueda en dicha ruta encontraran el archivo "NombreServicio.log" por fecha automáticamente ordenado.

sábado, 19 de septiembre de 2015

APLICACIÓN DE 'EHCACHE' CON 'SPRING'


El manejo de 'Cache' en las aplicaciones y servicios es muy importante, ya que agiliza la obtención de los datos evitando estar constantemente golpéando la BD. La ventaja que proporcionan en si las 'caches' básicamente es eliminar los tiempos de acceso a un recurso externo, para recuperar los datos que se encuentran mantenidos en cache, pero hay que tener cuidado en tener claro cuando y como realizarlo, así mismo como configurarlo.

En esta oportunidad mostraré una forma de como trabajar con una de las librerías open source más conocidas para el manejo del 'cache' que es 'Ehcache'. Esta librería posee un principio básico que es dividir la caché en diversas 'regiones' configurables donde se ubican los objetos.

Sus características principales son:

  • Rápido y simple de usar.
  • Pequeño (menos de 700 kb) y con pocas dependencias.
  • Escalable: permite, por un lado, escribir a disco y, por otro, trabajar con muchos caches en paralelo.
  • Flexible: permite trabajar con Objects o Serializables y configurarlo mediante xml o programaticamente.
  • Extensible: se pueden adicionar plug-ins, loaders, listeners, JMX y exceptions handlers. Trabaja con varias APIs como JTA o frameworks como Hibernate.
  • Distribuído: posee muchas opciones de replicación de los datos.
El propósito de este post es mostrar de froma detallada su integración con 'Spring', configuración y aplicación, mediante un dummy.

Las librerias requeridas para desarrollar este dummy son las siguientes:



Es necesario que desde 'Spring' se maneje un archivo de configuración exclusivo para 'EhCache' (applicationCache.xml):



Así mismo 'EhCache' maneja un archivo 'xml' referenciado desde 'applicationCache.xml', en donde maneja toda la configuración personalizada del cache, para cada escenario donde se desee aplicar:



Se debe de tener muy claro el significado de la definición de cada propiedad que se maneja. Aquí el detalle de cada una de ellas:



La prueba del 'dummy' la realizaremos mediante una clase main, que levantará el contexto de 'Spring' y ejecutará 2 metodos de prueba (estos trabajan independientes, se puede comentar y probar el que desee):



Metodo#1: Simulación del consumo de DB (1 vez), luego se obtendrá del 'EhCache' el mismo dato durante '10' seg. Despues golpeará la BD otra vez:


El resultado de la prueba es que al ejecutar en un tiempo de 20 segundos, solo se ha obtenido de BD (simulada) la 1ra fecha (2015/09/19 09:33:17) y como ven la hora se mantiene ya que las demás consultas son obtenidas del 'EhCache' configurado, para que mantenga la información por 10 segundos, poteriormente a ellos volvera a actualizar la información con la BD:



Metodo#2: Simulación del consumo de DB (1 vez), luego se obtendrá del 'EhCache' el mismo dato durante '10' seg. Despues golpeará la BD otra vez y se iran agregando 5 registros a la lista anterior existente:



El resultado de la prueba es que al ejecutar en un tiempo de 20 segundos, solo se ha obtenido de BD (simulada) la 1ra lista de Mensajes con una cantidad de registros de 5 y como ven la hora se mantiene ya que las demás consultas son obtenidas del 'EhCache' configurado, para que mantenga la información por 10 segundos, poteriormente a ese tiempo volvera a actualizar la información con la BD y como se aprecia la lista ahora devuelve 10 registros, ya que existe una simulación que cada 10 segundos se le agregarán 5 registros (por efecto de la prueba respectiva):



Para los interesados las fuentes se pueden descargar aquí: http://www.mediafire.com/download/aasn2aysfu2aoyi/Dummy_Spring_EhCache.zip


viernes, 18 de septiembre de 2015

'STORE PROCEDURE' EN SERVICIOS ...

Al hablar de este tema es muy probable que exista un debate, con relación al manejo de 'Store Procedure' para el acceso a datos dentro de los Servicios, con relación a un proyecto SOA. Ya que actualmente existe profesionales que son partidarios de los SPs y otros muchos que no. Desde mi punto de vista, he tenido el privilegio que manejar ambos escenarios (SPs y SQL embebido) y  el manejo de los SPs a nivel de servicios es lo mejor debido a muchos puntos entre los que resaltan:
  • Permite segmentar (desacopla) la 'capa de aplicación' (BD) con relación a la 'capa de servicios', permitiendo que exista un equipo/área destinada solo a labores exclusivas de BD (componentes).
  • Agiliza el desarrollo, ya que defiendo los parámetros INPUT/OUTPUT del SP, permite que ambos equipos (Integración y BD), puedan trabajar en paralelo y tener todo documentado.
  • Facilita el mantenimiento, ya que ante un problema, cambio y/o mejora a nivel de datos, el impacto no requerirá modificar la fuente, solo el SP respectivamente y esto sería mucho más rápido.
Por otro lado, los que están en contra del manejo de SPs, dirán que es un esfuerzo mayor, para el servicio ya que se añade una capa extra de transformación. En este caso yo respondería, lo mismo dicen para el uso ESB y al igual que en dicho caso pienso que el sacrificio vale la pena debido a la mayor cantidad de beneficios que consigo trae su manejo.


jueves, 17 de septiembre de 2015

'SERVER SENT EVENTs' (SSE) con 'SPRING MVC' y 'REST'

'Server Sent Events' (SSE) es una tecnología web desde el navegador que recibe actualizaciones automáticas de un servidor a través del protocolo HTTP, en el cual el cliente (Interfaz web) envía una solicitud y el servidor tiene una conexión hasta que un nuevo mensaje está completado, luego, envía el mensaje de vuelta al cliente mientras se mantiene la conexión abierta de modo que pueda ser utilizado para otro mensaje una vez que esté disponible. Una vez que un nuevo mensaje esté completado, se envía la respuesta al cliente desde la misma conexión inicial (NO se generan multiples conexiones). Posteriormente, la aplicacion cliente debe tener un mecanismo para la recepción multiple de los mensajes (eventos), que serán constantemente enviados desde el servidor de forma individual, sin cerrar la conexión después de procesar cada mensaje.

Una de las aplicaciones de SSE es realizada para la implementación a nivel de SOA del patrón ''UI MEDIATOR'', que recomienda como solución la colocación de un mediador entre el servicio que el usuario ejecuta y el punto final del servicio, tal como lo muestra la imagen:

 

Es importante mencionar el 'SSE' actualmente está soportado por las ultims versiones de: CHROME, FIREFOX y OPERA, pero tengo entendido que SAFARI a la fecha aún no lo soporta.

Para completar esta idea se ha preparado dummy (la parte del Backend), desarrollado en SPRING MVC con REST(JSON), que cumple con el rol de 'Mediador', la idea es que una 'interfaze usuario' (NO implementada) envíe una solicitud al 'Servicio Mediador' (REST), este internamente y en paralelo simulará el consumo de otros servicios (esto incurrirá en tiempos distintos por c/u) y ante la recepción de los response de cada servicio del flujo, retornará eventos en JSON hacia la interface usuario.

La clase: 'SSEControlImpl.java', será la encargada de exponer los REST, y por medio de los objetos: 'SseEmitter' y 'ResponseBodyEmitter', se agregarán y responderá los eventos JSON por etapas:



La clase 'EAIProxyServiceImpl.java', será la encargada de la simulación (hardcode) de los 'proxys client' de otros servicios para completar el flujo, las transformaciones de los objetos a 'JSON', serán realizadas por medio de la api 'GSON': 



Para los llamados en paralelo de los servicios embebidos y la obtención de sus respuesta para poder enviar los eventos respectivos a la interfaz usuario, por cada servicio que no tenga dependencia, se creará una clase: 'MensajeThread0X' y se procederá a ejecutar de la siguiente manera:



En mi caso lo he desplegado con 'Tomcat7', es importante recordar que el soporte 'SSE' a nivel de SPRING, está disponible con sus librerías 4, en mi caso he usado las 4.2.1:

Para las pruebas del dummy las he reproducido propiamente desde el navegador ingresando a las URLs, amboss servicios tienen el mismo retorno de los eventos, solo que manejan diferente objeto para dicho manejo:

Servicio#1:
http://localhost:8080/DummySpringMvc_SSE/eai/json/sse/getMediador01



Servicio#2:
http://localhost:8080/DummySpringMvc_SSE/eai/json/sse/getMediador02



Para descargar las fuentes del dummy 'SSE' pulsar aquí: http://www.mediafire.com/download/ovqb9q1e60i8lgk/DummySpringMvc_SSE.zip


sábado, 12 de septiembre de 2015

Aplicación de Seguridad en REST con 'SPRING-OAUTH2'

Todos saben que la seguridad a nivel de servicios es muy importante, sobre todo en los escenarios donde es necesaria la comunicación con servicios que están fuera de los límites del 'inventario de dominio u empresa' que se ha definido (un servicio de un proveedor externo), en estos casos existen soluciones a nivel de servicios que se pueden aplicar en arquitecturas SOA como los son:WS-Se curity, Https, SSL, etc, pero para el caso de arquitecturas REST, en realidad no existen muchas en el mercado y las pocas que existen no son muy utilizadas y/o conocidas.

En estas oportunidad hablaré un pocos de 'OAuth2', que en si es un protocolo de autorización que permite a terceros (clientes) acceder a contenidos de un usuario (alojados en aplicaciones de confianza, servidor de recursos). Es decir brinda el acceso a aplicaciones consumidoras, para que pueden acceder al contenido del servicio requerido previa validación y autenticación representada en un token.

La logica en si, tal como lo muestra la imagen, se sigue una lógica que es la siguiente:
  1. El 'usuario' requiere información y la solicita a la 'aplicacion cliente' (consumidora).
  2. La 'aplicacion cliente' solicita una autenticación contra el 'servidor de autenticación' (OAuth2). Se envía los parámetros: (grant_type,client_id,client_secret,username,password).
  3. Si todo está OK, el 'servidor de autenticación' responde los parámetros: (access_token,token_type,refresh_token,expires_in).
  4. Si todo está NOK, el 'servidor de autenticación' responde los parámetros:
  5.  (error,error_description), automáticamante.
  6. La 'aplicación cliente' obtiene el Token de acceso requerido y se comunica con el 'Servidor de Recursos' (el servicio principal), mandandole entre sus parámetros propios del servicio el parámetro: (access_token), previamente recuperado.
  7. El 'Servidor de Recursos' responde la información requerida a la 'aplicacion cliente'.

Actualmente, existe soluciones que brindan 'OAuth2' para su aplicación estas son:
  • Apache Oltu
  • Spring-OAuth2
  • Etc.
En esta oportunidad mostraré una de ellas que es: 'Spring-OAuth2', mediante el desarrollo de un dummy. Asi mismo, dicho dummy preparado fué desarrollado bajo las siguientes tecnologías y herramientas: 
  • Eclipse 3.8 (STS)
  • JDK 6
  • Spring 3.1
  • Spring MVC.
  • JSON.
  • Log4j
  • Tomcar 7.

A.
CONFIGURACIONES PREVIAS:


Dos de las buenas prácticas importante que se deben de considerar para el desarrollo de servicios, para su independencia y facil mantenimiento son:
  • Configurar un archivo de configuración 'logs' genérico y externo al servicio propiamente. 
  • Configurar un archivo de configuración '.properties' propio del servicio y externo a el. 
Para conseguir estos dos puntos, debemos definir variables donde se almacerán las rutas absolutas tanto para Log4j ( -Dlog4j.config="D:\java\xampp\tomcat" ), como para .properties ( -Dproperties.config="D:\JAVA\MIDDLEWARE\propertiesWebLogic" ), en mi caso he definido estás como rutas base.

 

Estos JVM arguments serán usados en el servicio de la siguiente manera, para tener el manejo externo respectivo de los archivos de configuración. Así mismo, es importante considerar que los archivos deberá ser creados en dichas rutas previamente (deben existir):




B. DESARROLLO DEL DUMMY:
El servicio dummy preparado cuenta con la siguiente estructura:


En si la idea es que por medio de este servicio se brinde el rol de: 'servidor de autenticación'  y  con ellos brindar acceso al 'Servidor de Recursos', podemos si deseamos manejarlo con un proxy de acceso.

Toda la seguridad en el servicio brindada por 'Spring-OAuth2', se manejará desde el archivo: 'applicationSecurity.xml', aquí los datos no deberá ser incrustados a modo Hardcore, sinó que serán referenciados por medio de Spring a un archivo .properties externo. 


En dicho archivo se manejará toda la información importante y configurable requerida por el servicio, así mismo, algunos datos propios de 'OAuth2', tal como menciono anteriormente podrían ser cargados de BD, pero para ello se debería modificar algunas partes en el: 'applicationSecurity.xml', que no son propias del dummy en estos momentos:


La parte mencionada como 'servidor de autenticación' está definida por 'OAuth2', mediante la exposición de un servicio con la estructura antes ya explicada. Este servicio en nuestro caso sería este:
http://localhost:8080/DummySpringMvcOauth/oauth/token?grant_type=password&client_id=dummySpringOauth&client_secret=secretDummySpringOauth&username=rguerra&password=@javaman

Al momento de ser consumirdo el servicio, existen dos clases que se encargan tanto de la 'autenticación' como de la validación del 'clientId', estas clases son: (CustomUserAuthenticationProvider.java y ClientDetailsServiceImpl.java)

La clase: CustomUserAuthenticationProvider.java, implementa  (AuthenticationProvider) que se encarga de lla validación del 'client_id' y el 'client_secret'  ingresado como parámetro, en base a ello se agregan a una lista 'autenticados'.


Así mismo, la clase: ClientDetailsServiceImpl
, implementa (ClientDetailsService) que se encarga de agregar una serie de permisos al usuario autorizado previamente.


Vale resaltar que ambas dos lógicas mostradas en esta parte, por mi parte las estoy realizando contra un .properties, pero se pueden tener registradas en una BD tanto el repositorio de usuarios/credenciales válidos como tambien lo relacionado a permisos.

Luego, la parte mencionada como 'servidor de recursos' se puede considerar trabajarlo como un proxy al servicio requerido, ya que este requeriá que se le envíe un parametro adicional (access_token), de los parámetros propios del servicio: 

http://localhost:8080/DummySpringMvcOauth/eai/json/personas/?access_token=df711ba5-0414-4c3c-bf16-4f8d4435358e

Si todo es OK se obtendra la respuesta correcta y propia del servicio requerido.



C. PRUEBA DEL DUMMY:

La prueba del servicio Dummy, se puede realizar de 2 maneras. Considerar que para benefinicios del dummy y cuenta con 2 tipos de 'Servidores de Recursos', uno que funciona sin parámetros propios del servicio y otro que funciona con un parámetro própio del servicio. Así mismo, los servicios REST manejados están implementados vía las funcionalidad brindadas por Spring MVC.


  • DESDE EL NAVEGADOR:
Armando las URL's podemos simular la lógica del flujo que 'OAuth2', propone para sus validaciones de la siguiente manera:

Paso#1: http://localhost:8080/DummySpringMvcOauth/oauth/token?grant_type=password&client_id=dummySpringOauth&client_secret=secretDummySpringOauth&username=rguerra&password=@javaman

Respuesta#1
:
{ "access_token":"a5c7d1f1-6028-4f92-8c35-71ed86272965",
    "token_type":"bearer",
    "refresh_token":"107d7139-484e-4bee-a13a-9059012ddb8a",
    "expires_in":119 }



Paso#2A:  Una vez ya con el Token (access_token) ya obtenido:
http://localhost:8080/DummySpringMvcOauth/eai/json/personas/?access_token=cc953b49-9c57-4aa5-96fd-7d1b0180570f


Respuesta#2A:
[{"id":1,"nombre":"CESAR GUERRA","correo":"cguerra@hotmail.com","telefono":"9877989898"},{"id":2,"nombre":"CATHERINE COTRINA","correo":"ccotrina@hotmail.com","telefono":"9896669898"},{"id":3,"nombre":"JUAN VERA","correo":"jvera@hotmail.com","telefono":"9238989898"},{"id":4,"nombre":"MARTIN CALAGUA","correo":"mcalagua@hotmail.com","telefono":"9898955598"}]


Paso#2B: http://localhost:8080/DummySpringMvcOauth/eai/json/CESAR%20GUERRA?access_token=cc953b49-9c57-4aa5-96fd-7d1b0180570f

Respuesta#2B:
{"id":1,"nombre":"CESAR GUERRA","correo":"cguerra@hotmail.com","telefono":"9877989898"}

Error: Ante un posible error de ya sea de tipo autenticación, parámetrización, etc, 'OAuth2' responderá de la siguiente manera por ejemplo:

{ "error":"invalid_grant","error_description":"Bad credentials" }


  • A NIVEL DE CÓDIGO:
A nivel de código se ha armado una clase tester que simularía la lógica requerida por: 'Aplicación Cliente', con relación al 'Servidor de Autenticación' para obtener el Token requerido y posteriormente ya sin problema consumir el 'Servidor de Recursos':

Ejecutamos la clases: TestMvcOauth.java, que procesará toda la lógica y generá el log respectivo:


Los logs serán generados de manera externa al servicio, por medio de log4j tal como se explicó inicialmente:


Finalemnte, con esto se ha tratato de demostrar una forma de las existes para el manejo de 'OAuth2', específicamente la brindada por Spring. En si se buscado la forma de hacer la explicación lo más detallada ya que en la actualidad veo que no existen, mucha explicación a este nivel sobre 'OAuth2', espero les sea beneficioso.

Para descargar las fuentes del servicio dummy, pulsar aquí:
http://www.mediafire.com/download/lce72exhd8ke2hn/DummySpringMvcOauth.zip

jueves, 3 de septiembre de 2015

'UDDI' PROTOCOLO VIVO Ó YA MUERTO.

En un entorno SOA, uno de los requerimientos principales es la necesidad de poder cambiar la URL de los servicios en el momento deseado (IP, PUERTO, etc), ya sea en los servicios compuesto como en los proxys, esto sin poder afectar a los otros servicios que son dependientes de los servicios cambiados (brinda un label identificador del servicio). Usualmente esto sucede al cambiar de ambiente (DESA, QA, PROD) sin tener que modificar directamente a nivel de fuentes los servicios. En estos casos la solución como mecanismo estándar sería aplicar lo que se conoce como UDDI, que tiene como objetivo registrar la URL para interactuar con los servicios del catálogo de registros. En si UDDI vendría a ser un equivalente a un DNS solo que este es parte de la estructura de red y no esta disponible para los desarrolladores, solo del equipo de Red.

Así mismo, UDDI es un protocolo que prácticamente se ha dejado del lado y es considerado muerto, por ejemplo ORACLE lo utilizó con el nombre de OSR hasta las versiones 'SOA Suite 11g', pero ya no ha sido considerado en su 'SOA Suite 12c'. Por otro lado, empresa grandes como APACHE aún no desean que muera y han sacado: 'JUDDI' (https://juddi.apache.org) ...