Ir al contenido principal

WSO2 EI Tutorial: Crear mensajes de fallos SOAP con Makefault Mediator

El ejemplo que vamos a estudiar hoy consiste en que un Cliente envía una solicitud a un backend a través de un middleware, EI. En medio del proceso hacia el EI, aparece un problema y se envía una respuesta de error al cliente. Para hacerlo, un makefault mediator es la mejor opción. De esta forma se genera un fallo SOAP personalizado cambiando la dirección del mensaje, en este ejemplo, como mensaje de respuesta. La dirección cambia gracias a la propiedad del encabezado TO que indica dónde se envía el mensaje.

Nota: EI significa Enterprise Integrator.

En el punto 2,3,4 y 5 se hablará del ejemplo 1 y 2 respectivamente, refiriéndonos al diagrama que se adjunta en esos mismos puntos.

Seguiremos el siguiente índice:

1. Makefault Mediator

Con Fault Mediator, que también se puede llamar Makefault Mediator, el mensaje actual se transforma en un mensaje de error que se envía de vuelta al cliente. Después de este mediator, se necesita un mediator send para responder al cliente con el mensaje de fallo, Fault Mediator no envía la respuesta al cliente de forma predeterminada. La solicitud original que proviene del cliente puede tener un encabezado Fault-To cuyo contenido se utiliza en el encabezado TO del mensaje de respuesta al fallo, como dije solo si Fault-To existe en la solicitud original. El mensaje de error se puede crear utilizando SOAP 1.1, SOAP 1.2 o XML simple (POX).

Ejemplo:

<makefault version=”soap12”>
   <code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
   <reason expression="get-property('ERROR_MESSAGE')"/>
</makefault>

El código devuelto por el mensaje de error. De esta manera, especifica el mensaje de fallo para los errores del lado del servidor, es decir, errores relacionados con el servidor:

<code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>

El mensaje de error se especifica como una expresión. La propiedad ERROR_MESSAGE se puede editar con un mensaje de error personalizado.

<reason expression="get-property('ERROR_MESSAGE')"/>

Nota: tns:Receiver – Para errores del lado del Servidor. tns:Sender– Para errores del lado del Cliente.

2. Configuración del EI ejemplo 1 con MSFT

Todo este código se despliega dentro del EI. La solicitud procedente del lado del cliente pasa por la secuencia principal (main sequence). En esa secuencia, si surge un error, la secuencia myFaultHandler se encarga de procesar el error, como lo indica onError en la secuencia principal. Ahora el mensaje va al mediator IN. Hay un mediator switch que busca el valor symbol en la solicitud. Puede tener dos valores MSFT o SUN. Si el valor coincide con MSFT, el mensaje se envía a un punto final cuyo nombre se ha escrito incorrectamente. Mientras que si el valor es SUN, la solicitud se envía al punto final correcto en localhost.

Cuando surge el error, quiero decir, cuando el mensaje se envía al punto final escrito incorrectamente, se lanza un error. Este evento de error es detectado por la secuencia myFaultHandler que procesa el mensaje. Dentro de esa secuencia hay un mediator makefault que nos genera un mensaje de fallo SOAP. La propiedad RESPONSE se establece en ‘true’ después del mediator makefault. Esto indica a la IE que cambie la dirección de los mensajes a ‘respuesta’ a medida que los mensajes se transforman en fallo SOAP. El valor de ReplyTo: http://www.w3.org/2005/08/addressing/anonymous, significa que la respuesta se envía al Cliente que envió la solicitud.

<definitions xmlns="http://ws.apache.org/ns/synapse">

    <sequence name="myFaultHandler">
        <makefault response="true">
            <code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
            <reason expression="get-property('ERROR_MESSAGE')"/>
        </makefault> 
       <property name=”RESPONSE” value=”true”/>
       <header name=”To” expression=”get-property(‘ReplayTo’)”/>
       <send/>
    </sequence>

    <sequence name="main" onError="myFaultHandler">
        <in>
            <switch xmlns:m0="http://services.samples" source="//m0:getQuote/m0:request/m0:symbol">
                <case regex="MSFT">
                    <send>
                        <endpoint>
                            <address uri="http://bogus:9000/services/NonExistentStockQuoteService"/>
                        </endpoint>
                    </send>
                </case>
                <case regex="SUN">
                    <send>
                        <endpoint>
                            <address uri="http://localhost:9009/services/NonExistentStockQuoteService"/>
                        </endpoint>
                    </send>
                </case>
            </switch>
            <drop/>
        </in>

        <out>
            <send/>
        </out>
    </sequence>

</definitions>

3. Ejecutando el ejemplo 1 con MSFT

Para ejecutar este ejemplo, inicie el servidor Axis2 con el servicio de back-end SimpleStockQuoteService. Hay una explicación de cómo hacerlo en el primer blog dedicado a la ESB. Por otro lado, el cliente que se utiliza para enviar solicitudes es el Cliente de Cotización de Acciones (Stock Quote Client). SOAPUI también se puede utilizar para enviar las solicitudes a la IE.

El cliente envía una solicitud de cotización de acciones con el símbolo MSFT, el que tiene el punto final incorrecto, y el backend responde con una respuesta de host desconocida. EI detecta el error y genera un mensaje de error, respuesta de error SOAP, que se envía al cliente. Si el cliente envía otra solicitud, el backend responde con una excepción de conexión rechazada como otra respuesta de fallo SOAP. Para enviar una solicitud de acciones de MSFT al EI, ejecute el siguiente comando desde el directorio <ESB_HOME>/samples/axis2Client.

Request:

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/

-Dsymbol=MSFT

Esta es la solicitud que envía el cliente (SOAPUI o Stock Quote Client):

Response desde EI:

Se generaría una excepción de conexión rechazada para la solicitud de stock SUN. Ejecute el siguiente comando desde el directorio <ESB_HOME>/samples/axis2Client para activar una solicitud de cotización de acciones de SUN al servicio de back-end.

Request:

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dsymbol=SUN

Esta es la solicitud que se envía al EI y también se puede utilizar con SOAPUI.

Request hacia EI:

Response desde EI:

4. Configuración del EI ejemplo 2 utilizando el archivo WSDL

El cliente envía la solicitud que pasa a través de un proxy. inSequence procesa la solicitud. Hay un mediator de logs que muestra el tipo de contenido del mensaje que es una propiedad que viaja en el nivel de transporte del mensaje. A continuación, hay un mediator filter. Si el tipo de contenido del mensaje no es texto/xml, devuelve un mensaje de error enviado al cliente. De lo contrario, envíe el mensaje a un punto final. En esa parte del mediator filter, hay otro mediator log para mostrar el tipo de contenido y un mensaje de error que indica: tipo de contenido incorrecto.

El próximo mediator es un makefault. Eso genera un mensaje de error que indica que el error proviene del lado del cliente, soap11Env:client. Después de eso, se elimina el encabezado TO, lo que indica que es un mensaje de solicitud. Porque ahora es un mensaje de respuesta de fallo. Y finalmente un mediator de envío (send) devuelve el mensaje de respuesta de falla al cliente. Por otro lado, outSequence redirige las respuestas del backend al lado del cliente. PublishWSDL publica el archivo WSDL.  

<proxy xmlns="http://ws.apache.org/ns/synapse" name="CheckContentType" transports="https http" startOnLoad="true" trace="disable">
<description/>
<target>
    <inSequence>
        <log level="custom">
            <property name="_______Content-Type" expression="get-property('transport','Content-Type')"/>
        </log>
        <filter source="get-property('transport','Content-Type')" regex="application/xhtml\+xml">
        <then>
            <log>
                <property name="Content-Type" expression="get-property('transport','Content-Type')"/>
                <property name="Decision" value="Exception, due to unexpected Content-Type."/>
            </log>
            <makefault version="soap11">
                <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
                <reason value="Content-Type Error"/>
                <role/>
                <detail>Content-Type: application/xhtml+xml is not a valid content type.</detail>
            </makefault>
            <header name="To" scope="default" action="remove"/>
            <send/>
        </then>
        <else>
            <log>
                <property name="Content-Type" expression="get-property('transport','Content-Type')"/>
                <property name="Decision" value="Continue the mediation flow..."/>
            </log>
            <send>
                <endpoint>
                    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                </endpoint>
            </send>
        </else>
    </filter>
</inSequence>
<outSequence>
    <send/>
</outSequence>
</target>
<publishWSDL uri="http://localhost:9000/services/SimpleStockQuoteService?wsdl"/>
</proxy>

5. Ejecutando el ejemplo 2 utilizando el archivo WSDL

Podemos utilizar el archivo WSDL publicado por el proxy para generar solicitudes de clientes. Para hacerlo, importe ese archivo wsdl en SOAPUI, por ejemplo, utilizando la URL que contiene el proxy y agrege “?wsdl” al final de la URL, como se muestra en la parte superior de la siguiente imagen. El proxy nos publica los métodos utilizados por el servicio. También el contenido del archivo wsdl es visible a través de un navegador:

El mismo URI se usa en SOAPUI para generar las solicitudes:

Este es un ejemplo de una solicitud SOAP contra el servicio utilizando un tipo de contenido correcto (texto/xml):

El mensaje se envía al backend. Ahora voy a enviar la misma solicitud pero con un tipo de contenido no válido (aplicación/xhtml+xml):

Como puede ver, y de acuerdo con la configuración de EI, se envía un mensaje de fallo/error al Cliente.

6. Conclusión

Como se ha demostrado, el uso de mediator de fallos, gestiona la generación de errores de mensajes siguiendo las buenas prácticas. Por otro lado, es muy útil porque el usuario puede personalizar el mensaje de error, indicando si el error proviene del lado del servidor o del lado del cliente.