sábado, 5 de enero de 2019

WSO2: Diferencia entre PayloadFactory y Enrich Mediator


Ultimamente estoy trabajando con WSO2 y me había estado resistendo a crear posts de algo tan específico. Pero creo que poco a poco vamos a hacer ejemplos básicos de esta técnologia de integración. 

Para empezar vamos a realizar un post sobre dos de los mediators más comunes que podemos utilizar dentro de una sequencia del Enterprise Integrator. Como son 'PayloadFactory' y 'Enrich'.  El primero de ellos nos permitirá modificar el cuerpo de la respuesta y crear uno nuevo a nuestra conveniencia. El segundo nos permitirá modificar el cuerpo de la respuesta pero solo añadiendole nuevos valores. 

Para el ejemplo partiremos en ambos casos de una API de prueba. Donde en la sequencia de entrada llamaremos a un wiremock que nos devolverá la respuesta mostrada a continuación. Y será esta respuesta la que va a ser modificada por los dos mediators:

{"bookstore": [
      {"name": "the starts my destination", "author": "Alfred Bester"},
      {"name": "Ender's Game", "author": "Orson Scott Card"}
]}

Con el 'PayloadFactory' mediator, vamos a indicar cual queremos que sea nuestra nueva respuesta. Nos permite incluso crear una nueva respuesta completamente estática, aunque no tenga mucho sentido. Para darle dinamismo tenemos los 'arguments', estos argumentos los indicaremos dentro del cuerpo de la respuesta como '$x', siendo 'x' el ordinal del mismo en la lista global de argumentos. Pueden ser obtenidos de 4 formas: a través de XPath o JSONPath sobre el cuerpo de la actual respuesta, mediante valores literales o con propiedades ya almacenadas en cualquiera de los ambitos dentro del EI. A continuación veremos un ejemplo con JSONPath, literales y valores del contexto:

<payloadFactory media-type="json">
        <format>
{"books":[{"book":[{"name":"$1","author":"$3"}]},{"book":[{"name":"$2","author":"$4"}]}],"total":"$5","description":"$6"}
            </format>
        <args>
            <arg evaluator="json" expression="$.bookstore[0].name" literal="true"/>
            <arg evaluator="json" expression="$.bookstore[1].name" literal="false"/>
            <arg evaluator="json" expression="$.bookstore[0].author" literal="false"/>
            <arg evaluator="json" expression="$.bookstore[1].author" literal="false"/>
            <arg literal="false" value="2"/>
            <arg evaluator="xml" expression="$ctx:description" literal="false"/>
        </args>
    </payloadFactory>

Generando la siguiente salida:

{"books":[
  {"book":[{"name":"the starts my destination","author":"Alfred Bester"}]},
  {"book":[{"name":"Ender's Game","author":"Orson Scott Card"}]}],
  "total":"2","description":"list of books"}

Ahora veremos como funciona el 'Enrich' mediator. Con el basicamente le indicaremos una fuente y un destino, pudiendo realizar 3 tipos de acciones diferentes: añadir como hijo, añadir como hermano o reemplazar. La configuración para la fuente y el destino son similares, se pueden elegir que sean de 4 tipos: personalizada en base a un XPath, envelope del mensaje original, el cuerpo del mensaje original o una propiedad de un ambito. Aunque existe una matrix de compatibilidades para los distintos tipos de fuentes y destinos, por lo que no vale cualquier combinación. Aquí vemos un ejemplo donde añadimos un hijo, un hermano y reemplazamos un valor.

<enrich>
    <source clone="false" type="inline">
        <total>2</total>
    </source>
    <target action="child" type="body"/>
</enrich>
<enrich>
    <source clone="false" type="inline">
        <description>list of books</description>
    </source>
    <target action="sibling" type="custom" xpath="//bookstore"/>
</enrich>
<property name="shortName" scope="default" type="STRING" value="Orson S. Card"/>
<enrich>
    <source clone="false" property="shortName" type="property"/>    <target action="replace" type="custom"
            xmlns:ns="http://org.apache.synapse/xsd" xpath="//bookstore[2]/author"/>
</enrich>

La salida en este caso sería la siguiente:

{"bookstore": { "name": "Ender's Game", "author": "Orson S. Card" }
,"description": "list of books", "total": 2}

Por ulitmo, con enrich una utilidad común es guardar la respuesta original, aunque también lo podemos hacer con el 'Property' mediator. Y luego restablecer dicha respuesta original. Muy util para cuando tienes que hacer llamadas intermedias en tu sequencia.

<property name="REQUEST_PAYLOAD" expression="$body" />
<!-- more code -->
<enrich>
    <source clone="true" xpath="$ctx:REQUEST_PAYLOAD" />    <target type="body" />
 </enrich>

No hay comentarios:

Publicar un comentario