Mostrando entradas con la etiqueta servicio proxy. Mostrar todas las entradas
Mostrando entradas con la etiqueta servicio proxy. Mostrar todas las entradas

miércoles, 1 de julio de 2015

Acá les dejo el enlace a un nuevo post que acabo de publicar en mi blog que puntualmente los temas que toca son:
  • Compilar y empaquetar el redmine-connector
  • Desplegar y activar un conector en el WSO2 ESB
  • Como importar un conector para el Developer Studio
  • Como implementar un Servicio Proxy en este caso usando el redmine-connector haciendo uso del DS
  • Como construir y desplegar un Composite Application Project desde el DS en el WSO2 ESB
  • Como realizar un test de un servicio Rest en nuestro caso haciendo uso del plugins RestClient del Mozilla Firefox y desde el SoapUI
Nos les adelanto nada más solo sigan este enlace:  http://wp.me/p5DCiP-10

Saludos

lunes, 3 de marzo de 2014

Introducción al ESB de WSO2 a través de ejemplos prácticos. IV

En entradas anteriores ya hemos tocado el tema del ESB de WSO2 para proxiar un servicio de acceso a datos, agregarle seguridad Username Token y  como desarrollar una arquitectura de seguridad usando el ESB en combinación con el Identity Server de WSO2.

En esta entrada les quiero mostrar cómo hacer un encadenamiento de servicios, Service Chaining, para consultar varios servicios y a partir de la información obtenida retornar una respuesta que integre dichos datos.

De forma general se puede ver la idea en la siguiente figura.






La descripción del escenario es como sigue:

Tenemos en una organización dada, que la información sobre las personas está distribuida en varias aplicaciones. En este caso para simplificar solo usamos 2 aplicaciones con un número reducido de datos sobre las personas.
  • En una aplicación 1 tenemos: nombre y edad.
  • En una aplicación 2 tenemos: nombre, dirección y grado escolar.
  • No se tiene acceso directo a las BD de las aplicaciones, pero se poseen servicios de acceso a datos.

Se quiere brindar un servicio que devuelva el concepto persona con los siguientes datos: nombre, edad, dirección y grado escolar, siempre que se introduzca el nombre de la persona.

Para implementar el escenario se han creado 2 servicios de acceso a datos encargados de extraer la información y un servicio proxy que concatena llamadas a estos servicios para crear una entidad persona como se desea.

Veamos cómo se hace:

Tendremos 2 servicios de acceso a datos que acceden a información de las siguientes tablas:

CREATE TABLE ws.userapp1 (
  id INTEGER NOT NULL,
  nombre VARCHAR NOT NULL,
  edad INTEGER NOT NULL,
  CONSTRAINT "userApp1_pkey" PRIMARY KEY(id)
) WITHOUT OIDS;

COMMENT ON COLUMN ws.userapp1.nombre
IS 'nombre de la persona';

COMMENT ON COLUMN ws.userapp1.edad
IS 'edad de la persona';



CREATE TABLE ws.userapp2 (
  id INTEGER NOT NULL,
  nombre VARCHAR NOT NULL,
  direccion VARCHAR NOT NULL,
  ge VARCHAR NOT NULL,
  CONSTRAINT "userApp2_pkey" PRIMARY KEY(id)
) WITHOUT OIDS;

COMMENT ON COLUMN ws.userapp2.nombre
IS 'nombre  de la persona';

COMMENT ON COLUMN ws.userapp2.direccion
IS 'direccion de la persona';

COMMENT ON COLUMN ws.userapp2.ge
IS 'grado escolar de la persona';

Los pasos para crear  servicios de acceso los pueden encontrar aquí.

Una vez creados los servicios de acceso a datos debemos diseñar el WSDL del servicio  proxy. En este caso sería el siguiente:

NOTA: vean como el nombre del element "getPersona" coincide con el nombre de la operación y dentro del namespace que se encuentra, lo cual es necesario conocerlo para poder extraer la información del mensaje de entrada usando XPATH.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://tutoriales.net/escuela_invierno" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Persona" targetNamespace="http://tutoriales.net/escuela_invierno">
  <wsdl:types>
    <xsd:schema targetNamespace="http://tutoriales.net/escuela_invierno">
      <xsd:element name="getPersona">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="nombre" type="xsd:string"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="getPersonaResponse">
        <xsd:complexType>
          <xsd:sequence>
           <xsd:element name="nombre" type="xsd:string" />
           <xsd:element name="direccion" type="xsd:string"></xsd:element>
           <xsd:element name="edad" type="xsd:int"></xsd:element>
           <xsd:element name="ge" type="xsd:string"></xsd:element>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="getPersonaRequest">
    <wsdl:part element="tns:getPersona" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="getPersonaResponse">
    <wsdl:part element="tns:getPersonaResponse" name="parameters"/>
  </wsdl:message>
  <wsdl:portType name="Persona">
    <wsdl:operation name="getPersona">
      <wsdl:input message="tns:getPersonaRequest"/>
      <wsdl:output message="tns:getPersonaResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="PersonaSOAP" type="tns:Persona">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getPersona">
      <soap:operation soapAction="http://tutoriales.net/escuela_invierno/NewOperation"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="Persona">
    <wsdl:port binding="tns:PersonaSOAP" name="PersonaSOAP">
      <soap:address location="http://www.example.org/"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Como ven recibe un String que sería el nombre de la persona y devuelve un objeto persona con la información que se pide.

A la hora de crear el servicio proxy hemos seguido la buena práctica de guardarlo todo en el registro del ESB por esa razón tanto los endpoint como las secuencias y el mismo WSDL están en el registro. Esto puede parecer un poco complicado ya que primero hay que imaginarse el servicio proxy antes de ponerse a implementarlo pero nos forza a hacerlo bien.

Estos son los endpoint a los 2 servicios de acceso a datos:

<endpoint xmlns="http://ws.apache.org/ns/synapse">
   <address uri="http://localhost:8280/services/userapp1_DataService">
      <suspendOnFailure>
         <progressionFactor>1.0</progressionFactor>
      </suspendOnFailure>
      <markForSuspension>
         <retriesBeforeSuspension>0</retriesBeforeSuspension>
         <retryDelay>0</retryDelay>
      </markForSuspension>
   </address>
</endpoint>

El primer endpoint es para consumir el servicio de datos de la aplicación 1, mientras que el endpoint 2 es para consumir el servicio de la aplicación 2.

<endpoint xmlns="http://ws.apache.org/ns/synapse">
   <address uri="http://localhost:8280/services/userApp2_DataService">
      <suspendOnFailure>
         <progressionFactor>1.0</progressionFactor>
      </suspendOnFailure>
      <markForSuspension>
         <retriesBeforeSuspension>0</retriesBeforeSuspension>
         <retryDelay>0</retryDelay>
      </markForSuspension>
   </address>
</endpoint>


Y estás son las 2 secuencias que se concatenan para extraer la información.

<sequence xmlns="http://ws.apache.org/ns/synapse">
   <property xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tutoriales.net/escuela_invierno" name="nombre" expression="//p:getPersona/nombre" scope="default" type="STRING"></property>
   <log>
      <property name="SEQ1" value="Accediendo secuencia UNO"></property>
      <property xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tutoriales.net/escuela_invierno" name="NOMBRE1" expression="get-property('nombre')"></property>
   </log>
   <payloadFactory media-type="xml">
      <format>
         <p:getbyname xmlns:p="http://ws.wso2.org/dataservice">            
            <p:nombre>$1</p:nombre>         
         </p:getbyname>
      </format>
      <args>
         <arg xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tutoriales.net/escuela_invierno" expression="//p:getPersona/nombre" evaluator="xml"></arg>
      </args>
   </payloadFactory>
   <send receive="conf:/winter/getapp2" buildmessage="true">
      <endpoint key="conf:/winter/endpoint_app1"></endpoint>
   </send>
</sequence>

La primera secuencia  captura en la propiedad "nombre" usando la expresión XPATH siguiente: //p:getPersona/nombre aquí uso p para vincularlo con el namespace http://tutoriales.net/escuela_invierno y de esta manera poder acceder a la información.

Luego uso el mediador log para imprimir los valores que tengo en las propiedades  SEQ1 y NOMBRE1, vean como en este último caso utilizo get-property('nombre') para poner como contenido de NOMBRE1 el contenido de la propiedad nombre, creada más arriba.

El siguiente mediador que se usa es el payloadFactory, para crear un mensaje nuevo de acuerdo con lo que espera el primer servicio de datos y uso el mediador send para enviarlo al endpoint correspondiente. La concatenación ocurre aquí pues en el mediador send le indico que el resultado de esta llamada se enviará a la secuencia que se encuentra en conf:/winter/getapp2 y así es como enlazo una secuencia con la otra.

<sequence xmlns="http://ws.apache.org/ns/synapse">
   <property xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://ws.wso2.org/dataservice" name="edad" expression="//p:Personas/p:Persona/p:edad" scope="default" type="STRING"></property>
   <log>
      <property name="SEQ2" value="Accediendo a la secuencia DOS"></property>
      <property xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tutoriales.net/escuela_invierno" name="NOMBRE2" expression="get-property('nombre')"></property>
      <property xmlns:ns="http://org.apache.synapse/xsd" name="EDAD2" expression="get-property('edad')"></property>
   </log>
   <payloadFactory media-type="xml">
      <format>
         <p:getbyname xmlns:p="http://ws.wso2.org/dataservice">            
            <p:nombre>$1</p:nombre>         
         </p:getbyname>
      </format>
      <args>
         <arg xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tutoriales.net/escuela_invierno" expression="get-property('nombre')" evaluator="xml"></arg>
      </args>
   </payloadFactory>
   <send>
      <endpoint key="conf:/winter/endpoint_app2"></endpoint>
   </send>
</sequence>

La secuencia 2 es muy similar a la 1 así que no la comentaré ya que se usan los mismos mediadores, lo que en este caso se consulta al servicio de datos 2 y no se llama a otra sencuencia en el mediador send. Lo que implica que la respuesta que llegue al ESB irá hacia la sencuencia de salida.

Luego viene la secuencia de salida  que se encarga de unir la información:
<sequence xmlns="http://ws.apache.org/ns/synapse">
   <payloadFactory media-type="xml">
      <format>
         <esc:getPersonaResponse xmlns:esc="http://tutoriales.net/escuela_invierno">            
            <nombre xmlns="">$1</nombre>            
            <direccion xmlns="">$2</direccion>            
            <edad xmlns="">$3</edad>            
            <ge xmlns="">$4</ge>         
         </esc:getPersonaResponse>
      </format>
      <args>
         <arg xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://ws.wso2.org/dataservice" expression="get-property('nombre')" evaluator="xml"></arg>
         <arg xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://ws.wso2.org/dataservice" expression="//p:Personas/p:Persona/p:direccion" evaluator="xml"></arg>
         <arg xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://ws.wso2.org/dataservice" expression="get-property('edad')" evaluator="xml"></arg>
         <arg xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://ws.wso2.org/dataservice" expression="//p:Personas/p:Persona/p:ge" evaluator="xml"></arg>
      </args>
   </payloadFactory>
   <send></send>
</sequence>

Como se ve en esta sencuencia solo se usa el payloadFactory para ensamblar un mensaje a partir de la información guardada en las propiedades o que viene de la respuesta del servicio de datos 2.

Por último el servicio proxy ya creado.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="merge_persona"
       transports="https http"
       startOnLoad="true"
       trace="disable">
   <description/>
   <target faultSequence="fault">
      <inSequence>
         <log>
            <property name="MAIN" value="Accediendo a la secuencia principal"/>
         </log>
         <sequence key="conf:/winter/getapp1"/>
      </inSequence>
      <outSequence>
         <sequence key="conf:/winter/salida"/>
      </outSequence>
   </target>
   <publishWSDL key="conf:/winter/Persona.wsdl"/>
</proxy>

Espero les sea de utilidad.

martes, 4 de junio de 2013

Introducción al ESB de WSO2 a través de ejemplos prácticos. II

En esta entrada estaremos viendo cómo crear un servicio proxy en el ESB de WSO2 que primero de acceso al servicio final, para luego incluirle el escenario de seguridad UT garantizando así que los usuarios tengan que autenticarse para acceder al servicio seguro.

Los pasos básicos son los siguientes:

  1. Usaremos el servicio final que creamos en esta entrada y que está desplegado en el AS.
  2. Descargaremos el ESB y lo iniciaremos de la misma forma que se inician todas las herramientas de la suite de WSO2, explicado aquí al inicio.  
  3. Crearemos el servicio proxy en el ESB a través de la UI de administración.
  4. Probaremos el consumo del servicio proxy sin seguridad y veremos la traza de los mensajes tanto en el ESB como en el AS. 
  5. Le asignaremos el escenario de seguridad UT al servicio proxy y veremos las modificaciones a realizar para que funcione correctamente.

Comencemos.!!!

Paso 1:
El servicio ya lo tenemos creado y este es su dashboard en el AS.

Paso 2:
El ESB lo pueden descargar de aquí y luego de descompactarlo lo inician siguiendo las instrucciones antes mencionadas. Verán al final de los logs de inicio de la herramienta la url a través de la cual podrán acceder a su administración. Recuerden que por defecto el usuario es admin y la contraseña es admin.


Paso 3:
Para crear el servicio proxy vayan a la opción del menú que está en la pestaña  Main y ahí en Services/Add/Proxy Service. Verán lo siguiente:

Seleccionen la opción Custom Proxy.
Como pueden apreciar la creación de un servicio proxy pasa por 3 pasos, este que es el primero nos permite especificar el nombre del servicio proxy, el WSDL que expondrá, algunos parámetros generales y los protocolos que podrán ser usados.

Lo más importante aquí es especificar el WSDL. Hay 3 formas de hacerlo:
  • Especificarlo de forma inline, o sea escribir o copiar el WSDL del servicio en una caja que se habilita para esto, lo bueno que tiene es que no se pierde el WSDL
  • Especificar una URL que apunta al WSDL del servicio. Si la URL está offline entonces al reiniciarse el ESB el servicio proxy da error.
  • Primero guardar el WSDL en el registro del ESB y luego obtenerlo del registro. Se puede gestionar en el registro del ESB

Usaremos la segunda opción y apuntaremos a la URL del WSDL del servicio de datos que ya tenemos creado.


Dan clic en Next y verán lo siguiente.


Llegados a este punto quisiera explicar brevemente el flujo básico de los mensajes en el  ESB.
Se usa el concepto de tuberías y filtros porque los mensajes cuando entran al ESB llegan a una tubería identificada por una secuencia de entrada, In Sequence, y a esta secuencia se le pueden aplicar un conjunto de filtros que vendrían siendo los mediadores que posee el ESB. Luego el mensaje sale y llega al servicio final. La respuesta de este servicio llega al ESB y pasa por una secuencia de salida o out Sequence donde se le pueden aplicar filtros hasta que llega al consumidor del servicio. Esto lo pueden apreciar en la siguiente imagen.


Una vez dicho esto vamos a especificar una secuencia de entrada y una secuencia de salida.

En la imagen del paso 2 de 3 seleccionamos en la secuencia de entrada la opción “Define Inline” y veremos cómo nos da la opción de crear la secuencia.

Damos clic en Create y comenzaremos a definir la secuencia de entrada:




Si dan clic en Add Child verán lo siguiente:

Esta es la clasificación de los diferentes mediadores que existen en el ESB, cuando se paren encima de una de estas clasificaciones se les desplegará el listado. Para este ejemplo solo quiero guardar un log del paso del servicio por esta secuencia. Dan clic en la clasificación Core y luego en Log.


Si quieren ver que es cada una de estas opciones pueden dar clic en Help y verán una página donde les explican. En mi caso lo dejare como está y daré clic en Save & Close.

Ahora vamos a definir el endpoint hacia donde debe ser enviado el mensaje, en este caso el servicio de acceso a datos. Nuevamente seleccionamos la opción Inline
Y damos clic en Create.

Como pueden ver hay varios tipos de endpoint, usaré la primera opción dando clic en ella e introduciré el endpoint del servicio de acceso  a datos.

Nuevamente si quieren ver que son cada una de las opciones pueden dar clic en Help. Yo doy Save & Close y listo. Volvemos a la pantalla del paso 2 de 3 y damos Next.

Aquí es casi lo mismo que en la secuencia de entrada. Seleccionaremos la opción “Define inline” para la secuencia de salida, iremos a la categoría Core y seleccionaremos el mediador Send, que es para que nos envíe el mensaje al endpoint antes definido.



Aquí no tenemos que especificar un endpoint por eso dejamos marcada la opción None.
Damos Save & Close, luego finish y ya tenemos creado nuestro servicio proxy.


Como ven en la imagen anterior el servicio aparece marcado como proxy, nos dice que es inseguro, nos da acceso a los WSDL 1.1 y 2.0, podemos probar el servicio, y también podemos entrar a editarlo ya sea a través de la interfaz gráfica anterior o usando la vista de código fuente. Quiero mostrarles como se ve el servicio así que selecciono esta última opción:



Salimos de ahí dando clic en Cancel y vamos a la opción Try it.

Como pueden ver se muestran las mismas operaciones del servicio de acceso a dato y podemos hacer las mismas cosas. Los invito a probarlo.

Si van a la consola del ESB verán los mensajes de Log que se generan debido al uso del mediador Log en la secuencia de entrada. Pueden editar el servicio proxy y variar sus características y ver como cambie el mensaje de los logs en la consola.


Una vez terminado esto realizaremos el último paso que es asignarle seguridad al servicio web. Volvemos al listado de los servicios y en la fila de nuestro servicio proxy

Daremos clic en Unsecured.
Ya esto lo hemos visto antes así que en la ventana que nos aparece seleccionamos Yes.

Y luego seleccionamos el escenario 1.

Damos clic en Next y seleccionamos los roles que podrán acceder al servicio proxy.
Damos finish y listo. Ya nuestro servicio proxy es seguro.
Ahora verán en su dashboard como solo queda el endpoint que utiliza https.

Lo que hemos hecho es añadirle al WSDL del servicio una política de seguridad como pueden ver a continuación.


Básicamente estamos pidiendo que se use https y se incluya un username token en los mensajes.

Llegado a este punto el servicio está configurado correctamente pero cuando pruebo nuevamente la funcionalidad del try it introduciendo mi usuario y contraseña curiosamente no funciona. Cosas del opensource. Puede ser que la funcionalidad del try it esté rota en la versión 4.6.0 del ESB. Pero esto solo me da pie a usar otra herramienta para probar el servicio: el SOAPUI.

Como no era objetivo de esta entrada introducir esta herramienta no lo haré pero si les dejaré las pantallas de las pruebas y en otra entrada explicaré como usarla.

Luego de creado el proyecto en SOAPUI vemos lo siguiente si intentamos consumir el servicio.


Nos está diciendo que faltan los encabezados de seguridad. Luego de configurarlos vemos lo siguiente:



Ya aquí pueden ver que luego de configurado el proyecto podemos consumir el servicio sin problema confirmándonos que el teníamos un problema con el Try it del ESB.