jueves, 22 de mayo de 2014

Exponiendo datos de nuestra BD a través de APIs con WSO2


En esta entrada quiero mostrar cómo usando varios elementos ya tratados en el blog podemos muy fácilmente exponer nuestros datos a través de APIs y realizar operaciones CRUD sobre ellos.

En esta entrada vimos como crear un servicio de acceso a datos muy fácilmente y en tan solo 3 minutos, que incluyera las operaciones CRUD necesarias para manipular la información de una tabla.

Luego en esta otra entrada vimos como podíamos exponer dichas operaciones de una forma RESTful, lo que en este caso la información la obteníamos como un XML y no en formato JSON.

Así que en esta otra entrada entonces se mostró como podíamos indicarle a la herramienta de WSO2 AS que queríamos también mostrar la información como un JSON.

Hasta aquí tenemos un servicio de acceso a datos desplegado en el WSO2 AS que puede ser consumido por SOAP o por REST y en este último caso las respuestas las puede dar tanto en POX como en JSON, pero eso no es todo.

WSO2 está apostando fuerte por el tema de las APIs, y con su herramienta WSO2 API Manager se ha posicionado entre las mejores empresas en brindar soluciones de este tipo.

Guiándonos por esta otra entrada podemos ir directamente al paso 2 y registrar nuestro servicio en el WSO2 API Publisher para luego gestionarlo en el WSO2 API Store y generar las claves de acceso que nos permitirán probarlo, tal y como se explica en el paso 3.

Ya aquí podemos usar curl o un cliente RESTful para consumir la API siempre usando el token de autorización generado por el API Store.

Por último si deseamos monitorizar el consumo del API solo basta configurar el BAM para que se establezca una conexión entre el AM y el BAM tal y como se muestra aquí.

lunes, 5 de mayo de 2014

Ejemplos de uso de JAX-WS con CXF.

En esta entrada quiero dejarles el código de 3 proyectos que he usado como material de entrenamiento básico en un curso que impartí para el desarrollo de servicios usando CXF, como implementación para el API de JAX-WS.

Proyecto Example3_JAX-RS: Se implementa un servicio RESTful usando la implementación CXF para JAX-WS.

Proyecto Example3_JAX-WS: Se implementa la misma funcionalidad del ejemplo anterior pero se expone como un servicio web a partir de un WSDL ya diseñado, o sea usando el enfoque top-down.

Proyecto Example4_JAX-WS: Se implementa la misma funcionalidad de los ejemplos anteriores pero el servicio está asegurado con el escenario UserNameToken y HTTPS.

En estos ejemplos se usa Spring como mecanismo para mantener todo unido y Maven para la gestión de dependencias.

En el caso del último ejemplo uso las facilidades multimódulo de Maven para separar en módulos los diferentes aspectos que me interesan(servicio, webapp y cliente) En los casos en que se quiera exponer una lógica de negocio ya existente pues se puede crear un módulo para esta lógica de negocio, lo cual siempre facilita su reutilización.

Espero les sea de utilidad.

viernes, 2 de mayo de 2014

WSO2con 2014 en Europa


Con mucha alegría he visto la noticia de que se desarrollará un evento de WSO2con en un país hispano parlante, en este caso España. Así que durante el mes de junio tendremos WSO2 en español :-D

Aquellos que puedan asistir no lo duden ni un minuto. He estado revisando la agenda recien públicada y se debatirán temas muy interesantes.

miércoles, 30 de abril de 2014

WSO2 y su propuesta para el gobierno electrónico

Los temas de gobierno electrónico están muy de moda hoy vinculados a los siguientes tópicos:
  1. SOA.
  2. BPM.
  3. Cloud Computing.
  4. Big Data.
Esta relación se hace bastante “interesante” cuando desde el punto tecnológico las arquitecturas propuestas se pueden instanciar usando una suite como la de WSO2, que abarca cada uno de los puntos anteriores a través de un conjunto de herramientas libres bajo licencia Apache 2.0.

Fig.1. Ejemplo de la relación entre el gobierno electrónico y la computación en la nube


Desde WSO2 nos presentaron un artículo titulado: “Connected Government Cloud Enabling Public Services. The Importance of Functional and Nonfunctional Requirements in Building a Multi-tenanted Digital Government Stack” en el cual nos llevan a un enfoque basado en 3 modelos diferentes que combinan la Computación en la Nube con el Gobierno electrónico.

Estos modelos son:

  • Controlado y gobernado centralmente: Los sistemas son controlados centralmente lo que implica que se provee un modelo SaaS a los gobiernos locales y además las políticas son aplicadas a nivel nacional y aplicadas a nivel local.
  • Controlado centralmente pero gobernado localmente: en este caso aplica lo mismo del modelo anterior donde el gobierno central brinda un modelo SaaS a los gobiernos locales, pero este último puede desplegar y aplicar sus políticas encima del SaaS.
  • Controlado y gobernado localmente: en este caso el gobierno central no juega un papel importante ya que los sistemas son desplegados a nivel local y el hosting y la infraestructura es gobernada por el propio gobierno local.

Para más información sobre las ventajas y desventajas de cada modelo así como el macheo entre un tipo de gobierno el tipo de modelo a aplicar pueden consultar el artículo en cuestión.

El artículo nos propone como se podría ver una solución de arquitectura para el gobierno electrónico usando los componentes de su suite.


lunes, 7 de abril de 2014

MULE vs WSO2 en el patrón de integración Scatter-Gather.

Hace unos días revisando el blog de MULE me topé con esta entrada del 3/04/2014 donde se explica como con la nueva versión 3.5 se ha añadido una funcionalidad para eliminar algunos problemas de las versiones anteriores a la hora de implementar el patrón de integración "Scatter-Gather".

Este patrón define la forma de enviar un mismo mensaje a diferentes destinos con un objetivo determinado y luego procesar la respuesta de una manera específica, tal como pueden ver en la imagen siguiente.




Un objetivo que nos llevaría a implementar este patrón puede ser el mandar un mismo request a diferentes sistemas que se encargan de procesar reservaciones de vuelos y a partir de la respuesta recibida de cada uno seleccionar la mejor para la solución final, tanto los ejemplos de MULE como de WSO2 seleccionan de las respuestas recibidas la más barata. Es solo un ejemplo pero les puede dar idea de la utilidad del patrón.

MULE antes de la versión 3.5 implementaba este patrón usando un router multicasting <all>, el cual presentaba las siguientes limitantes según se comenta en el propio artículo:
  1. Procesamiento en secuencia, o sea uno detrás del otro.
  2. Problemas en el manejo de los errores.
  3. Poca personalización de la solución para adecuarla a las necesidades específicas de los desarrolladores.
En la entrada que les comentaba con la introducción del router <scatter-gather> le han dado solución a estos problemas.

Lo interesante es que MULE hace esto ahora, pero WSO2 lo tiene hecho desde hace un tiempo ya y no con un mediador si no con la combinación de varios mediadores, lo que implica que la solución aunque parezca un poco más complicada técnicamente permite una mayor personalización para los desarrolladores. Y creo que esto es genial, el tener pequeños bloques de construcción que puedan ser usados para casi cualquier cosa y pienso que esa es la idea de WSO2. Si a esto le sumamos que podemos crear templates a partir de una solución en particular y luego usar dicho template para recrear una nueva implementación del patrón, pues nos ahorramos mucha configuración.
Solo les dejo el XML del servicio proxy para que lo vean:


<proxy xmlns="http://ws.apache.org/ns/synapse" name="ScatterGatherProxy" transports="https http" startOnLoad="true" trace="disable">  
    <description/>  
    <target>  
        <inSequence>  
            <clone>  
                <target>  
                    <endpoint name="vendorA">  
                        <address uri="http://localhost:9000/services/SimpleStockQuoteService/"/>  
                    </endpoint>  
                </target>  
                <target>  
                    <endpoint name="vendorB">  
                        <address uri="http://localhost:9001/services/SimpleStockQuoteService/"/>  
                    </endpoint>  
                </target>  
                <target>  
                    <endpoint name="vendorC">  
                        <address uri="http://localhost:9002/services/SimpleStockQuoteService/"/>  
                    </endpoint>  
                </target>  
            </clone>  
        </inSequence>  
        <outSequence>  
            <log level="full"/>  
            <aggregate>  
                <completeCondition>  
                    <messageCount min="3"/>  
                </completeCondition>  
                <onComplete xmlns:m1="http://services.samples/xsd" xmlns:m0="http://services.samples" expression="//m0:return">  
                    <enrich>  
                        <source xmlns:m1="http://services.samples/xsd" clone="true" xpath="//m0:return[not(preceding-sibling::m0:return/m1:last <= m1:last) and not(following-sibling::m0:return/m1:last < m1:last)]"/>  
                        <target type="body"/>  
                    </enrich>  
                    <send/>  
                </onComplete>  
            </aggregate>  
        </outSequence>  
    </target>  
</proxy>


La solución que propone WSO2 para este patrón la pueden encontrar en este enlace muy bien documentada y lista para ser probada con un paso a paso, así que no la recrearé en esta entrada.

sábado, 22 de marzo de 2014

WSO2 ESB: Transformando de JSON a SOAP y de SOAP a JSON.



En esta entrada quiero mostrarles una de las maneras de implementar el siguiente escenario:

Se tiene un servicio backend implementado usando SOAP que recibe un valor de temperatura en Celsius y la devuelve en Fahrenheit, como puede ser el siguiente: http://www.w3schools.com/webservices/tempconvert.asmx?wsdl del cual nos interesa la operación CelsiusToFahrenheit.

Se desea que la petición del cliente sea un json y la respuesta igual sea un json.

La solución usando el WSO2 ESB es implementar un servicio proxy que reciba un json, lo transforme a un mensaje SOAP y lo mande al servicio backend, luego la respuesta SOAP la transforme nuevamente en un json y la mande de vuelta al cliente.

El mediador que usaremos para poder cambiar de un formato de mensaje a otro será el payloadfactory y verán lo útil que es a partir de las últimas versiones del WSO2 ESB, ya que nos permite tanto generar mensajes SOAP como JSON con bastante facilidad.

Para este servicio backend y usando el mediador PayloadFactory el servicio proxy queda como sigue:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="JsonToXMLProxy"
       transports="https http"
       startOnLoad="true"
       trace="disable">
   <description/>
   <target>
      <endpoint>
         <address uri="http://www.w3schools.com/webservices/tempconvert.asmx" format="soap11"/>
      </endpoint>
      <inSequence>
         <log>
            <property name="TEMPERATURA_ENTRADA" expression="json-eval($.celsius)"/>
         </log>
         <payloadFactory media-type="xml">
            <format>
               <web:CelsiusToFahrenheit xmlns:web="http://www.w3schools.com/webservices/">
                  <web:Celsius>$1</web:Celsius>
               </web:CelsiusToFahrenheit>
            </format>
            <args>
               <arg evaluator="json" expression="$.celsius"/>
            </args>
         </payloadFactory>
         <header name="Action"
                 value="http://www.w3schools.com/webservices/CelsiusToFahrenheit"/>
      </inSequence>
      <outSequence>
         <log>
            <property xmlns:p="http://www.w3schools.com/webservices/"
                      name="TEMPERATURA_SALIDA"
                      expression="//p:CelsiusToFahrenheitResponse/p:CelsiusToFahrenheitResult"/>
         </log>
         <payloadFactory media-type="json">
            <format>
                            "Temperatura" : {
                                "EnFahrenheit" : $1
                            }
            </format>
            <args>
               <arg xmlns:p="http://www.w3schools.com/webservices/"
                    evaluator="xml"
                    expression="//p:CelsiusToFahrenheitResponse/p:CelsiusToFahrenheitResult"/>
            </args>
         </payloadFactory>
         <property name="messageType" value="application/json" scope="axis2"/>
         <send/>
      </outSequence>
   </target>
</proxy>

Para probar el servicio usamos el siguiente comando curl:

curl -X POST -H "Content-Type: application/json" -d "{ \"celsius\": \"20\" }" "http://localhost:8280/services/JsonToXMLProxy"

Y la respuesta es la siguiente:

"Temperatura" : {
                   "EnFahrenheit" : 68
                }


Al ESB llega un mensaje como el siguiente:

POST /services/JsonToXMLProxy HTTP/1.1
User-Agent: curl/7.25.0 (i386-pc-win32) libcurl/7.25.0 OpenSSL/0.9.8u zlib/1.2.6 libssh2/1.4.0
Host: 127.0.0.1:4444
Accept: */*
Content-Type: application/json
Content-Length: 19

{ "celsius": "20" }

Este mensaje json primero es capturado por un log que imprime en consola el valor de celsius usando la siguiente expresión: json-eval($.celsius)

2014-03-21 22:44:22,976] INFO - LogMediator To: /services/JsonToXMLProxy, MessageID: urn:uuid:60f0298e-f66d-4f9c-a2a9-5480ee2569a5, Direction: request, TEMPERATURA_ENTRADA = 20

Luego usando el mediador payloadfactory se crea un mensaje de acuerdo a la estructura que espera el servicio backend. Para saber su estructura siempre me apoyo en la herramienta SOAPUI, probando primero el servicio. El valor que se le pasa en el atributo se obtiene a partir de evaluar como json la expresión $.celsius.

Algo importante a tener en cuenta es especificar el Header, lo cual se hace usando el mediador header.
Y así de esta manera se termina la secuencia de entrada.

El mensaje creado es enviado al endpoint definido y su respuesta que viene en este formato, debe ser procesada:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.w3schools.com/webservices/">
   <soapenv:Body>
      <web:CelsiusToFahrenheitResponse>
         <!--Optional:-->
         <web:CelsiusToFahrenheitResult>68</web:CelsiusToFahrenheitResult>
      </web:CelsiusToFahrenheitResponse>
   </soapenv:Body>
</soapenv:Envelope>

Cuando este mensaje llega al ESB lo primero que hacemos es obtener en un log el valor de la temperatura, y se imprime como sigue en pantalla:

[2014-03-21 22:44:23,109] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:c76239bb-16cf-459d-99e5-5296d5aba938, Direction: response, TEMPERATURA_SALIDA = 68

Luego para crear la respuesta que enviaremos al cliente nos apoyamos en otro mediador payloadfactory en la secuencia de salida, definiendo que el tipo será json y especificando la estructura del mensaje de salida. El valor del argumento se obtiene a partir de conocer la estructura del mensaje SOAP que llega al ESB desde el servicio backend. Importante no dejar de incluir la propiedad de nombre messageType.

Y eso es todo, hay otras maneras de implementar este escenario bien sea usando el mediador script o el XSLT, pero en este caso me gusta más usar el payloadfactory.

Espero les sea de utilidad.

lunes, 17 de marzo de 2014

WSO2 API Manager + BAM. Monitorizando el consumo de las APIs

En la entrada anterior vimos como publicar como APIs en el WSO2 API Manager los servicios contenidos en una aplicación JAX-RS desplegada en el WSO2 Application Manager.

También vimos como desde una aplicación web en JAVA se accedían a dichas APIs y nos había quedado pendiente analizar la implementación a través del estudio del código fuente de ambas aplicaciones y el monitoreo de las APIs usando el WSO2 BAM.

En esta entrada veremos como monitorizar las APIs para lo cual haremos uso del siguiente enlace donde se explica paso a paso como configurar el BAM y el APIM.

El WSO2 API Manager a través de las funcionalidades que expone en la aplicación web API Manager nos permite ver los siguientes tipos de estadísticas:

  • Uso de todas las APIs y uso de todas las APIs por creador.
  • Promedio de los tiempos de respuesta.
  • Uso de un API por subscriptor.
  • Uso de un API por subscriptor y por versión.
  • Número de subscripciones por API.

De todas estas estadísticas la única disponible antes de configurar el BAM es el número de subscripciones por API. De ahí la importancia de incorporar el BAM a este escenario pues es la manera de saber cómo están siendo usadas y se están comportando nuestras APIs.

A partir de aquí asumimos que ambas herramientas han sido ya configuradas.
Si accedemos de nuevo a la aplicación web del API Publisher en https://localhost:9443/publisher y vamos a la opción “Suscripciones” debajo de “MIS APIS” veremos luego de varios consumos de la aplicación web en java como se rellenan las estadísticas. A manera de ejemplo les muestro las mías.



Podemos ver que cada una tiene una subscripción así que eso da un 33% a cada una.


Igual se muestra el número de llamadas por API.


Los tiempos de respuesta.


Últimos accesos.


Y el uso por usuario así como las invocaciones fallidas en caso de haberlas.


Así como pueden ver de una manera muy bien documentada por WSO2 podemos integrar el APIM con el BAM para lograr almacenar las estadísticas de uso de las APIs y llevar el control de su consumo.

A manera de señalamiento al parecer hay un problema con las fechas y hora en el APIM. Es algo que hay que revisar pero si se fijan en las estadísticas no están correctas las horas y las fechas que muestran.
Espero les sea de utilidad.

Hace poco más de un mes publiqué una entrada introductoria al WSO2 API Manager, APIM, que incluía un ejemplo como usar esta herramienta, el cual pueden consultar para entender lo que haré en esta entrada.
Básicamente estaremos viendo como exponer servicios usando el APIM y como consumirlos desde una aplicación web luego de autenticarnos.

La idea siempre parte de lo que se aprecia en la siguiente imagen y lo estaremos implementando paso a paso.



Paso 1: desplegar la aplicación que contiene los servicios en el WSO2 Application Server.
Nos descargamos el fuente desde esta ubicación  y en mi caso lo guardo en una carpeta que se llama “tutorial” y tendremos la siguiente estructura de carpetas.


En este paso trabajaremos con el “pizza-shack-api” así que entramos en el directorio hasta llegar a la  ruta [tutorial]\pizza-shack-api\src\main\java\com\pizzashack\ donde se puede observar los siguientes ficheros.



El único que he cambiado es el PizzaMenu.java debido a un problema con la localización, pues  da problema con el punto y la coma en el formato de los decimales.
Tan pronto lo descargan se ve así:
 
    private PizzaMenu() {
  Random rand = new Random();
  DecimalFormat format = new DecimalFormat("#.##");
  
  MenuItem item1 = new MenuItem();
  item1.setName("Chicken Parmesan");
  item1.setDescription("Grilled chicken, fresh tomatoes, feta and mozzarella cheese");
  item1.setPrice(format.format(rand.nextInt(20) + 10 - 0.01));
  item1.setIcon("/images/1.png");
  items.add(item1);


Luego de realizar el ajuste queda así:
 
 private PizzaMenu() {
  Random rand = new Random();
        DecimalFormat format = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.ENGLISH));

  MenuItem item1 = new MenuItem();
  item1.setName("Chicken Parmesan");
  item1.setDescription("Grilled chicken, fresh tomatoes, feta and mozzarella cheese");
  item1.setPrice(format.format(rand.nextInt(20) + 10 - 0.01));
  item1.setIcon("/images/1.png");
  items.add(item1);  
  


Una vez hecho este cambio vamos a la raíz del proyecto y ejecutamos el comando Maven mvn clean package para que nos cree en la carpeta target el fichero pizzashack-api-1.0.0.war que será la aplicación web que debemos  desplegar en el WSO2 Application Server.
Iniciamos el servidor AS y bien podemos copiar  el fichero en la ubicación [AS]\repository\deployment\server\webapps\ y entrar a través de la interfaz gráfica de la herramienta e ir hasta Home> Manage > Applications > Add> JAX-WS/JAX-RS, Y agregarla por esa vía.



En ambos casos ya tendrán desplegada la aplicación que contiene el servicio, tal y como pueden ver a continuación.


Al dar clic en el contexto vemos el dashboard de la aplicación.



Aquí pueden ver las opciones para generar un cliente, copiar su endpoint o ver el diseño del mismo dando clic en WADL.
Volviendo atrás, si dan clic en “Find Services”  podrán ver el servicio que se implementa.



Y al dar clic en el enlace tenemos acceso a la descripción del servicio.
Si se fijan verán un servicio para obtener el menú a través de esta URL: http://127.0.0.1:9765/pizzashack-api-1.0.0/api/menu/  si lo probamos con un cliente veremos lo siguiente:



Nos devuelve el nombre del plato, una descripción, un icono para que sea puesto en la aplicación web que  consuma de este servicio y el precio.
Los invito llegado este punto que prueben el resto de los servicios para que vean cómo funcionan, así como revisar el fuente de cada servicio para que dominen las operaciones implementadas.

Paso 2: publicar estos servicios como APIs en el WSO2 API Manager.
El objetivo de este paso es publicar los servicios como APIs, y para ello debemos acceder al WSO2 API-M Publisher a través de esta URL: https://localhost:9443/publisher
 



Una vez autenticados debemos ir hasta   APIs / Add New API tal y como muestra la siguiente imagen.



Ahora creams las 3 APIs una por cada servicio usando la siguiente información:

Delivery API

                API Name= pizzaShack
                Context = /pizzashack/delivery
                Version = 1.0.0
                Production Endpoint URL=http://localhost:9765/pizzashack-api-1.0.0/api/delivery
                API Resources = Dejar los valores por defecto

Order API
               
                API Name= pizzashack-order
                Context = /pizzashack/order
                Version = 1.0.0
                Production Endpoint URL=http://localhost:9765/pizzashack-api-1.0.0/api/order
                API Resources = Dejar los valores por defecto

Menu API

                API Name= pizzashack-menu
                Context = /pizzashack/menu
                Version = 1.0.0
                Production Endpoint URL=http://localhost:9765/pizzashack-api-1.0.0/api/menu
                API Resources = Dejar los valores por defecto

Una vez terminada esta acción tendremos todas las APIs ya creadas y visibles a través del Browser.



CREATED significa que están en el estado de creadas. Ahora debemos entrar a cada una y modificar el estado en la opción del ciclo de vida para ponerlas como publicadas.




Si juegan un poco con el ciclo de vida verán que se lleva un control de las acciones realizadas. Algo muy útil para saber que ha pasado con el API en todo momento.
Luego de cambiar el estado de las 3 APIs se visualizan de la siguiente manera.



Pueden observar cómo ha cambiado su estado.
Así de esta manera hemos creado las 3 APIs y las hemos publicado para que estén visibles en el próximo paso.


Paso 3: Crear una aplicación y subscribir las APIs.

Lo primero es ir al Store del WSO2 API Manager, para poder configurar adecuadamente el consumo de las APIs. Deben acceder a la siguiente URL: https://localhost:9443/store
Tan pronto nos autenticamos en el Store podemos ver las 3 APIs creadas en el paso anterior.




Ahora debemos dar clic en una de las APIs, y en el combo de las aplicaciones seleccionar la aplicación por defecto o una que ustedes creen. En este ámbito se entiende por aplicación a la agrupación lógica de un conjunto de APIs sobre la cual realizaremos determinadas acciones. En mi caso creo una nueva aplicación con el nombre de “Pizza” y accediendo a cada API selecciono en el combobox de las aplicaciones la que he creado.
Al finalizar esta acción las 3 APIs están vinculadas con mi aplicación “Pizza”. La forma de ver esto es ir a la opción “My Subscriptions” en el menú superior y verán seleccionada en un combobox la aplicación y se van al final de la página verán lo siguiente.


Al inicio de la página tenemos esta configuración:



La cual es muy importante pues nos generará las claves para consumir las APIs, así que le damos al botón “Generate” y obtenemos lo siguiente:



Este token que hemos generado es del tipo “Application Access Tokens”. La herramienta WSO2 API Manager permite generar además de este tipo de token un “User Access Tokens”.
La diferencia es que el primero nos permite identificar y autenticar una aplicación completa, mientras que el segundo es para identificar y autenticar al usuario final de una aplicación. Usamos el primer token porque nos permite con un solo token acceder a todas las APIs de la aplicación “Pizza”.
Ahora podemos probar el consumo de una API usando curl con el siguiente comando:
curl -k -H "Authorization: Bearer c4H4fMWbPGw8MNY5gVM9s_DAgXoa" https://localhost:8245/pizzashack/menu/1.0.0   resalto en negrita y subrayado el token que debe corresponderse con el valor del “Access Token” que pueden observar en la imagen arriba.
Esto  nos devuelve lo siguiente.



Con lo cual ya sabemos que nuestras APIs están online.

Paso 4: configurar y desplegar una aplicación web en java que consuma las APIs usando las claves generadas.

Llegado este momento debemos ir al código de la aplicación web que se encuentra en el directorio “pizza-shack-web” y ajustar los parámetros necesarios en el fichero web.xml que se encuentra en [pizza-shack-web]\src\main\webapp\WEB-INF\web.xml

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
 version="2.4">
 <display-name>Pizza Shack Client App</display-name>

 <listener>
  <listener-class>com.pizzashack.client.web.PizzaShackContextListener</listener-class>
 </listener>
 
 <context-param>
        <param-name>serverURL</param-name>
        <param-value>http://localhost:8280/pizzashack</param-value>
    </context-param>
    <context-param>
        <param-name>loginURL</param-name>
        <param-value>http://localhost:8280/token</param-value>
    </context-param>
    <context-param>
        <param-name>consumerKey</param-name>
        <param-value>yOJ2gUwZctQ44rZYnb2BM88bUG0a</param-value>
    </context-param>
    <context-param>
        <param-name>consumerSecret</param-name>
        <param-value>4uUpUtHc7rvNknG1QqPVHLdCneIa</param-value>
    </context-param>
 
</web-app>


Luego vamos a la raíz del directorio y ejecutamos el comando Maven mvn clean package.
Esta acción nos genera la aplicación pizzashack.war  que procedemos a desplegar también en el WSO2 Application Server.
Accedemos al WSO2 AS y vamos hasta: Home> Manage > Applications> Add> Web Applications buscamos el .war recién creado y le damos al botón “Upload”.
Como la aplicación web recientemente subida al AS tiene entre sus parámetros el consumerKey y el consumerSecret la aplicación puede generar token específicos para los usuarios y así de esta manera se restringe el acceso a las APIs.


Paso 5: acceder a la aplicación y consumir las APIs.
Ahora procedemos al siguiente enlace: http://localhost:9765/pizzashack/login.jsp y ponemos las credenciales admin/admin
El sistema nos deja entrar y podemos ver la siguiente pantalla, realmente deliciosa    :-D



Ordenamos una pizza.



Y se nos genera un número de identificación.



Con este número vamos al menú superior y seleccionamos  “My Orders”.



Introducimos el número y le damos “Find order”.




Como tenemos acceso al código fuente pues podemos ver la implementación tanto de la aplicación JAX-RS como de la aplicación web en JAVA y el consumo de las APIs, esto lo estaremos analizando en entradas siguientes. Pero igual nos sigue quedando pendiente el tema del monitoreo del consumo de las APIs lo cual realizaremos en la siguiente entrada  conectando a esta solución el WSO2 BAM.

Espero les sea de utilidad.

Algunos enlaces que le pueden servir.

viernes, 14 de marzo de 2014

El ESB de WSO2 se considera el ESB más rápido en su categoría

Aunque la noticia es de mediados del mes pasado creo que es válido seguirla reproduciendo por su importancia.

Luego de realizada un ronda de pruebas entre varios ESB la siguiente gráfica refleja el comportamiento de cada cual en diferentes escenarios probados. De ser válidos los resultados no cabe duda de la afirmación que da título a esta entrada, y nos demuestra a los seguidores de la suite de WSO2 que no estamos equivocados en nuestra elección.

Solo en las pruebas de seguridad no fue  el más rápido de todos, aunque se puede apreciar que la differencia fue relativamente pequeña.

lunes, 10 de marzo de 2014

Interoperabilidad a través de un Modelo de Datos Canónicos


En temas de interoperabilidad técnica, relacionada con SOA, el patrón Modelo de Datos Canónicos reviste un especial interés, ya que cuando fue elaborado se pensó como una "bala de plata" para los temas de integración e interoperabilidad, pero hasta el día de  hoy tiene sus pro y sus contras, como todo.

Según la wikipedia este patrón permite la comunicación entre sistemas que tienen diferentes modelos de datos, reduciendo costos y estandarizando la forma de comunicarse. Su adopción pasa por el uso de algún middleware, ESB, que permita implementar el patrón con lo cual las aplicaciones se desentienden de como transformar sus datos a las estructuras de datos de otras aplicaciones.

Veamos con un ejemplo de la vida real como funciona.

Digamos que tenemos una persona X que habla español y una persona Y que habla chino.
La unica forma que tienen estas dos personas de entenderse entre si es que la información intercambiada sea transformada de un idioma a otro, bien sea del español al chino o de chino al español.

Si agregamos 20 personas más, cada una con su idioma propio y sin repetir, pues cada persona tendrá que saber como transformar la información que envía al idioma de la persona que debe recibirlo, para que se puedan comunicar.

Algo similar es lo que se presenta cuando múltiples aplicaciones tienen que intercambiar información entre si,  ya que deben implementar transformaciones para los mensajes que se mandan o se reciben.
En nuestro ejemplo de las personas la solución es usar un idioma común para todas, algo como el Esperanto. De esta manera cada persona solo tiene que saber su idioma y el Esperanto, y eso es todo. Si tiene que hablar con otra persona que no domine su idioma usa el Esperanto y así se podrán entender.

Llevando esto al ámbito técnico la solución es usar el patrón Modelo de Datos Canónicos (MDC), el cual nos indica que debemos crear un modelo que sea común a todos los sistemas, de forma tal que se mapeen en él las principales entidades y sus atributos. De esta manera si  una aplicación X quiere enviar un objeto Persona a una aplicación Y, debe convertir su objeto Persona al objeto Persona del MDC para poder enviarlo a la aplicación destino. La aplicación destino entonces convertirá el objeto persona del MDC a su modelo propio y lo podrá usar. Algunas ideas al respecto las podrán encontrar en este enlace y en este otro.

 Por lo general este patrón es bueno usarlo en organizaciones que poseen múltiples sistemas legados que además tienen diferentes BD con diferentes esquemas y modelado de las entidades de negocio, pues es el escenario ideal para su implementación cuando se requiera alguna solución de integración. Este patrón y su implementación vienen también con formas negativas de implementarlo, por lo que es importante primero entenderlo adecuadamente, ver las buenas prácticas a seguir y contar con el apoyo de la organización para poder ejecutarlo, de lo contrario puede ser todo lo contrario de lo propuesto  inicialmente. Información al respecto la pueden encontrar en este enlace.

Por último mi recomendación es que se estudien el libro "Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions" de Gregor Hohpe y Bobby Woolf donde se explica correctamente este patrón.

En la siguiente entrada sobre este tema estaremos viendo como WSO2 plantea el tema del MDC usando su ESB