jueves, 25 de septiembre de 2014

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

En esta entrada quiero mostrarles una pequeña implementación motivada a partir de una pregunta lanzada en StackOverFlow.
Basicamente se quiere obtener a partir de la consulta de un servicio de datos un listado de IDs y con ese listado se desea iterar sobre el mismo y por cada elemento lanzar una llamada a otro servicio de acceso a datos, y las respuestas obtenidas unirlas para devolver una única respuesta al cliente.
Veamos como se hace.

El servicio proxy queda como sigue:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="AddressProxy"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <property xmlns:p="http://www.example.org/Address/"
                   name="clientid"
                   expression="//p:getAddress/clientid"
                   scope="default"
                   type="STRING"/>
         <sequence key="conf:/sequencesStackOverFlow/getmpartybranch"/>
      </inSequence>
      <outSequence>
         <aggregate>
            <completeCondition>
               <messageCount min="-1" max="2"/>
            </completeCondition>
            <onComplete xmlns:add="http://ws.wso2.org/dataservice"
                        expression="//add:Addresses/add:Address">
               <send/>
            </onComplete>
         </aggregate>
      </outSequence>
   </target>
   <publishWSDL key="conf:/wsdls/Address.wsdl"/>
   <description/>
</proxy>



Como pueden ver en la secuencia de entrada primero guardo en una property el valor del clientid que es la entrada del servicio proxy, y luego hago una llamada a la secuencia getmpartybranch, que está en el registro del ESB y que veremos a continuación.


<sequence xmlns="http://ws.apache.org/ns/synapse">
   <payloadFactory media-type="xml">
      <format>
         <dat:getmpartybranch xmlns:dat="http://ws.wso2.org/dataservice">            
            <dat:clientid>$1</dat:clientid>         
         </dat:getmpartybranch>
      </format>
      <args>
         <arg xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('clientid')" evaluator="xml"></arg>
      </args>
   </payloadFactory>
   <send receive="conf:/sequencesStackOverFlow/iterOvermpartybranch">
      <endpoint>
         <address uri="http://127.0.0.1:9765/services/mpartybranch"></address>
      </endpoint>
   </send>
</sequence>



En esta secuencia creo un nuevo mensaje para consultar el servicio de acceso a datos que me dará dado el clientid el listado sobre el cual deberé iterar. Este resultado lo obtengo de invocar al servicio http://127.0.0.1:5555/services/mpartybranch y será enviado a la secuencia iterOvermpartybranch, que veremos a continuación.


<sequence xmlns="http://ws.apache.org/ns/synapse">
   <iterate xmlns:ns="http://org.apache.synapse/xsd" xmlns:ds="http://ws.wso2.org/dataservice" expression="//ds:DataCollection/ds:Datalist" id="iterate1" sequential="true">
      <target>
         <sequence>
            <property name="partybranchid" expression="//ds:partybranchid/text()" scope="default" type="STRING"></property>
            <property name="clientid" expression="//ds:clientid/text()" scope="default" type="STRING"></property>
            <log>
               <property name="PARTYID" expression="get-property('partybranchid')"></property>
               <property name="CLIENTID" expression="get-property('clientid')"></property>
            </log>
            <payloadFactory media-type="xml">
               <format>
                  <dat:getselect_addresses xmlns:dat="http://ws.wso2.org/dataservice">                     
                     <dat:objectid>$1</dat:objectid>                     
                     <dat:clientid>$2</dat:clientid>                  
                  </dat:getselect_addresses>
               </format>
               <args>
                  <arg expression="get-property('partybranchid')" evaluator="xml"></arg>
                  <arg expression="get-property('clientid')" evaluator="xml"></arg>
               </args>
            </payloadFactory>
            <log level="full"></log>
            <send>
               <endpoint>
                  <address uri="http://127.0.0.1:9765/services/getAddress" format="soap12"></address>
               </endpoint>
            </send>
         </sequence>
      </target>
   </iterate>
</sequence>



En  el mediador iteramos para llegar a cada nodo //ds:DataCollection/ds:Datalist y obtenemos las propiedades que vamos a utilizar, estas las imprimimos en consola para comprobar que efectivamente el servicio está funcionando. Algo que es muy útil cuando lo estamos desarrollando.


Luego creamos otro mensaje usando el mediador payload factory y lo enviamos al servicio de datos correspondiente. En base de datos tengo 2 tuplas en mi ejemplo, así que se realizaría 2 recorridos y se consultaría 2 veces al servicio http://127.0.0.1:9765/services/getAddress


La respuesta de esta secuencia entraría por la secuencia de salida del servicio proxy, la cual pueden ver en la definición del servicio. En la secuencia se usa el mediador aggregate para agregar las respuestas. Solo queda pendiente realizar una transformación para cumplir con el formato del mensaje de salida. Esto lo veremos en la siguiente entrada.

1 comentario: