Middleware Abstraction Layer. Un MAL necesario.

Implementar una arquitectura orientada a servicios (SOA) no es una tarea trivial. Menos aliviar su implementación. Hoy esto es pan caliente para los críticos del buzzword, que intentan demostrar como es casi imposible hacer SOA con estadísticas como : 1 proyecto exitoso por 4 fracasos de cada 5 intentos.

No obstante SOA si es posible. SOA es abstracción, y cuando desarrollamos abstrayendo desarrollamos para reusar. Mientras más capaces seamos de abstraer y desacoplar a un cliente de un servicio, más capaces seremos de reusar y extender el servicio, así como probar el cliente en ambientes desconectados.

Lo que más complica la implementación de SOA es lo díficil que es crear capas de abstracción genéricas y reusables. SOA es caro porque necesita de desarrolladores capaces de crear mucha abstracción.

El proyecto
Hoy estamos intentando adjudicarnos un proyecto de consultoría para revelar el impacto que tendrá llevar a cabo SOA en una empresa cliente. Un problema es que el cliente ya tiene su propia solución de integración basada en una capa middleware que consta de servidores de mensajería y muchos conectores de inbound y outbound para invocar servicios legacy desde otros servicios legacy. Es una solución propietaria, desarrollada por una empresa proveedora. En principio un buen diseño, pero tiene falencias. No fue construida con una una visión SOA, su mantención es cara y en el tiempo será insustentable. No obstante digo que es un problema no por sus falencias (pues en un final funciona) sino porque definitivamente llevar a cabo SOA en este cliente va a estar condicionado en principio por que porciento de la solución actual es reusable cuando se seleccionen las herramientas y se diseñe una plataforma SOA. Y como ya dijimos que abstracción significa reusabilidad, entonces estará condicionado por cuan abstractos hayan sido diseñado los componentes que permiten el acceso a los servicios legacy en el middleware, o sea los conectores. Quedese sintonizado pues de adjudicarnos el proyecto crearemos una bitácora en nuestro blog sobre el trabajo que hagamos.

Middleware Abstraction Layer
Un buen diseño de una solución SOA está condicionado por un buen diseño de la capa de abstracción necesaria para desacoplar los clientes de los servicios. de nada sirve implementar una arquitectura donde los clientes de los servicios conozcan todos los detalles de su invocación como:
Que tipo de servicio es?
Cual es el protocolo de invocación?
Como lo invoco?
Como parseo la respuesta?
Que códigos de error retorna?
Es transaccional?

Los datos mínimos que el cliente de un servicio debe conocer son
Su nombre.
Que parámetros recibe como parte del contrato de invocación.
Que estructura de datos retorna también como parte del contrato de invocación.

Con esto debiera bastar para poder invocarlo. Todo lo demás puede permanecer escondido detrás de la capa de abstracción.

Ejemplo de una capa MAL genérica bien diseñada
Pensando como un desarrollador cliente, invocar un servicio desde un lenguaje de programación debería ser tan sencillo como invocar un método de un objeto en el mismo lenguaje. Un buen diseño de una capa de invocación debe esconder tanto como se pueda del servicio en sí.

Por ejemplo invocar desde Java al servicio para obtener el libro de direcciones de una persona (que vive en una arquitectura SOA, quizas en un ESB) debería ser algo como:

// le pedimos a la fabrica de servicios que instancie
// el servicio getAddressBook
Service service = ServiceFactory.getService("getAddressBook");

// lo invocamos pasando como parámetro el nombre de la persona
// esta información forma parte del contrato de
// invocación de la interface del servicio documentada
Response response = service.call(new Object[] {"Mary Lebow"} );

// addressBook es lo que realmente esperamos
// forma parte del contrato de respuesta
// de la interface del servicio documentada
AddressBook addressBook = new AddressBook();

// le pedimos a la respuesta de la capa MAL
// que via instrospección llene el objeto addressBook
response.parseJSON(addressBook);

LOG.info("Mary Lebow vive en la calle: " + addressBook.getAddress().getStreet());
LOG.info("Su telefono de casa es " + addressBook.getPhoneNumbers()[0]);

Otro ejemplo. En caso que la respuesta venga en formato XML (quizás por definición del servicio) podriamos ejecutar consultas a la respuesta usando XPath, que tal algo como:

// se ejecuta una consulta a través de XPath
// al objeto response que delega en el XML
LOG.info("Su telefono celular es " + response.xPathQuery("/addressbook/phoneNumbers[0]"));

En este caso las clases ServiceFactory y Response pertenecen a la capa MAL. El cliente se abstrae de saber definiciones relacionadas a metadata del servicio. Al mismo tiempo La responsabilidad de la capa MAL es la de traducir la llamada delegando el requerimiento hacia la capa de servicios (por ejemplo invocar un endpoint HTTP como un Web Service REST o colocar un mensaje en una cola MQ) e interpretar la respuesta. Por ejemplo arrojar una excepción si el reason code es diferente de 200, u otro ejemplo invocando diferentes dominios de parsers de la respuesta (JSON, XML, YAML) para formar objetos en el lenguaje nativo (en el ejemplo Java).

Además el diseño de mi capa MAL está basado en la especificación del protocolo HTTP. Por ejemplo el objeto Response puede contener metadata sobre la invocación que podría ser interpretada por clientes agentes para tomar decisiones:
response.getType() // retorna XML, JSON, HTML, LARGO-POSICION
response.status() // versión y nombre del protocolo de invocación usado, por ejemplo HttpXmlRequest v1.1
response.reasonCode() // el código de respuesta, 200 OK, 404 Servicio no encontrado, etc.
response.authenticate() // si necesita de autenticacion y cual es el m+etodo de hacerlo

Lo que debemos tener es una única capa MAL por plataforma o lenguaje de programación usado como cliente, por ejemplo una capa para Java, otra para Python, otra para C, etc.

Conclusiones
La principal ventaja de SOA es conseguir reusar servicios. Su principal desventaja es lo díficil que es facilitar el uso de los servicios abstrayendo a los clientes de la arquitectura. La abstracción debería estar siempre en la mente de un buen desarrollador, por tanto SOA es posible.

Agregar un comentario

Su dirección de correo no se hará público. Los campos requeridos están marcados *