Friday, February 19, 2016

Common and Error Handling Sequences WSO2 ESB & API Manager

Common and Error Handling Sequences

IMPORTANT

  • By default if backend endpoint returns SOAP Fault, ESB won’t trigger fault sequence of a proxy service. To execute fault sequence of a proxy service upon backend SOAP Fault, following property need to be set in the insequence

<property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>

  • ESB Suspends the endpoint for 30 seconds if SOAP Fault occurred at endpoint. Messages coming to ESB during that time period will be ignored and will not be sent to the endpoint. Endpoint suspension can be disabled with following setting
<?xml version="1.0"?>
<endpoint>
  <address uri="http://localhost:9000/services/SimpleStockQuoteService">
    <timeout>
      <duration>30000</duration>
      <responseAction>fault</responseAction>
    </timeout>
    <suspendOnFailure>
      <errorCodes>-1</errorCodes>
      <initialDuration>0</initialDuration>
      <progressionFactor>1.0</progressionFactor>
      <maximumDuration>0</maximumDuration>
    </suspendOnFailure>
    <markForSuspension>
      <errorCodes>-1</errorCodes>
    </markForSuspension>
  </address>
</endpoint>

Fault Sequences

Sequence: fault_email.xml
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_email" trace="disable">
  <clone continueParent="true">
    <target>
      <sequence>
        <property expression="get-property('SERVER_HOST')" name="ServerHost" scope="default" type="STRING"/>
        <property expression="fn:concat('[', $ctx:ServerHost ,']')" name="environment" scope="default" type="STRING"/>
        <property expression="fn:concat($ctx:environment, ' An Error Occurred Service : ',$ctx:proxy.name)" name="Subject" scope="transport" type="STRING"/>
        <property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
        <property name="transport.mail.Format" scope="axis2" type="STRING" value="Attachment"/>
        <property name="AttachmentFile" scope="axis2" type="STRING" value="ErrorMessage.xml"/>
        <property expression="$ctx:messageBody" name="transport.mail.bodyWhenAttached" scope="axis2" type="STRING"/>
        <header action="remove" name="To" scope="default"/>
        <property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
        <property name="RESPONSE" scope="default" type="STRING" value="true"/>
        <property name="ContentType" scope="axis2" type="STRING" value="text/html"/>
        <property name="messageType" scope="axis2" type="STRING" value="text/html"/>
        <send>
          <endpoint>
            <address trace="disable" uri="mailto:harsz89@gmail.com"/>
          </endpoint>
        </send>
      </sequence>
    </target>
  </clone>
</sequence>
This is a custom sequence developed for sending mails when there is a SOAP Fault occured. Refer [1] to configure the mail transport in ESB. It’s necessary to enable the text/html message formatter of the ESB. It can be enabled in {ESB_HOME}/repository/conf/axis2/axis2.xml by uncommenting following xml tag.

<messageFormatter class="org.wso2.carbon.relay.ExpandingMessageFormatter" contentType="text/html"/>

This sequence will attached SOAP Fault message to a file and responsible incoming message to the email body when sending the mail which is requested by the team. To get the incoming message to send within the email, it’s necessary to get the request message to a property called messageBody in insequence as follow.

<property expression="$body/*" name="messageBody" scope="default" type="STRING"/>

Example:
<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="StockQuoteProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
    </inSequence>
    <outSequence>
      <send/>
    </outSequence>
    <faultSequence>
      <sequence key="fault_email"/>
      <send/>
    </faultSequence>
    <endpoint>
      <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
    </endpoint>
  </target>
  <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
  <description/>
</proxy>

Sequence: fault_filter_based_http_status_code.xml

<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_filter_based_http_status_code" trace="disable">
  <filter regex="401" source="get-property('axis2', 'HTTP_SC')">
    <then>
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Server"/>
        <reason value="Unauthorized to access the resource"/>
        <role/>
      </makefault>
      <send/>
    </then>
    <else/>
  </filter>
  <filter regex="500" source="get-property('axis2', 'HTTP_SC')">
    <then>
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Server"/>
        <reason value="Internal Server Error Occurred"/>
        <role/>
      </makefault>
      <send/>
    </then>
    <else/>
  </filter>
</sequence>
This sequence demonstrate the capability of sending SOAP Fault to the client based on the HTTP Status code return from the backend. ESB error codes such as 500, 401 not triggers Fault Sequence. Hence sometimes, depend on the use case proxy service need to send SOAP Fault back to the client based of HTTP Status code. This sequence can used and extend to handle it.

Example:
<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="StockQuoteProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
    </inSequence>
    <outSequence>
      <sequence key="fault_filter_based_http_status_code"/>
      <send/>
    </outSequence>
    <faultSequence>
      <sequence key="fault_email"/>
      <send/>
    </faultSequence>
    <endpoint>
      <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
    </endpoint>
  </target>
  <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
  <description/>
</proxy>

Sequence: fault_filter_format_based_http_status_code.xml

Previous sequence used to send the standard SOAP Fault back to client depend on the HTTP Status code. But this sequence uses payloadfactory mediator to build a custom fault message to send back to client
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_filter_based_http_status_code" trace="disable">
  <filter regex="401" source="get-property('axis2', 'HTTP_SC')">
    <then>
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Server"/>
        <reason value="Unauthorized to access the resource"/>
        <role/>
      </makefault>
      <send/>
    </then>
    <else/>
  </filter>
  <filter regex="500" source="get-property('axis2', 'HTTP_SC')">
    <then>
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Server"/>
        <reason value="Internal Server Error Occurred"/>
        <role/>
      </makefault>
      <send/>
    </then>
    <else/>
  </filter>
</sequence>
Example:
<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="StockQuoteProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
    </inSequence>
    <outSequence>
      <sequence key="fault_filter_format_based_http_status_code"/>
      <send/>
    </outSequence>
    <faultSequence>
      <sequence key="fault_email"/>
      <send/>
    </faultSequence>
    <endpoint>
      <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
    </endpoint>
  </target>
  <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
  <description/>
</proxy>

Sequence: fault_format_endpoint_fault.xml

ESB triggers fault sequence on various endpoint failures[2]. Depend on the returned error code, ESB may need to send custom SOAP Fault messages back to the client. This sequence can be used to send custom faults messages with payloadfactory mediator and can be extend to meet the requirements.

<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_format_endpoint_fault" trace="disable">
  <switch xmlns:ns="http://org.apache.synapse/xsd" source="$ctx:ErrorCode">
    <case regex="101000">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101000</ERROR_CODE>
            <ERROR_MESSAGE>EndPoint Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Receiver Error</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101001">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101001</ERROR_CODE>
            <ERROR_MESSAGE>EndPoint Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Receiver Error</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101500">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101500</ERROR_CODE>
            <ERROR_MESSAGE>EndPoint Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Sender Error</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101501">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101501</ERROR_CODE>
            <ERROR_MESSAGE>EndPoint Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Sender Error</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101503">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101503</ERROR_CODE>
            <ERROR_MESSAGE>Network Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Connection Failure</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101504">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101504</ERROR_CODE>
            <ERROR_MESSAGE>Network Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Connection Timeout</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101505">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101505</ERROR_CODE>
            <ERROR_MESSAGE>Network Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Connection Closed</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101506">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101506</ERROR_CODE>
            <ERROR_MESSAGE>Network Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Protocol Violation</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101507">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101507</ERROR_CODE>
            <ERROR_MESSAGE>Network Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Connection Cancelled</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101508">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101508</ERROR_CODE>
            <ERROR_MESSAGE>Network Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Connection Timeout</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101509">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101509</ERROR_CODE>
            <ERROR_MESSAGE>Network Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Send Abort</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <case regex="101510">
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>101510</ERROR_CODE>
            <ERROR_MESSAGE>Network Connection Failure</ERROR_MESSAGE>
            <ERROR_DETAIL>Response Processing Error</ERROR_DETAIL>
          </Fault>
        </format>
        <args/>
      </payloadFactory>
    </case>
    <default>
      <payloadFactory media-type="xml">
        <format>
          <Fault>
            <ERROR_CODE>$1</ERROR_CODE>
            <ERROR_MESSAGE>$2</ERROR_MESSAGE>
            <ERROR_DETAIL>$3</ERROR_DETAIL>
          </Fault>
        </format>
        <args>
          <arg evaluator="xml" expression="get-property('ERROR_CODE')"/>
          <arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
          <arg evaluator="xml" expression="get-property('ERROR_DETAIL')"/>
        </args>
      </payloadFactory>
    </default>
  </switch>
  <header action="remove" name="To" scope="default"/>
  <property name="RESPONSE" scope="default" type="STRING" value="true"/>
</sequence>
Example:
<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="StockQuoteProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
    </inSequence>
    <outSequence>
      <send/>
    </outSequence>
    <faultSequence>
      <sequence key="fault_format_endpoint_fault"/>
      <send/>
    </faultSequence>
    <endpoint>
      <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
    </endpoint>
  </target>
  <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
  <description/>
</proxy>

Sequence: fault_mediator_endpoint_fault.xml

<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_mediator_endpoint_fault" trace="disable">
  <switch xmlns:ns="http://org.apache.synapse/xsd" source="$ctx:ErrorCode">
    <case regex="101000">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101001">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101500">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101501">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101503">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101504">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101505">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101506">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101507">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101508">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101509">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <case regex="101510">
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </case>
    <default>
      <makefault version="soap11">
        <code xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/" value="soap11Env:Client"/>
        <reason expression="get-property('ERROR_MESSAGE')"/>
        <role/>
      </makefault>
    </default>
  </switch>
  <header action="remove" name="To" scope="default"/>
  <property name="RESPONSE" scope="default" type="STRING" value="true"/>
</sequence>
As in the previous endpoint error handling sequence, makeFault mediator can be used instead of payloadfactory mediator to send SOAP Fault to client depend on the endpoint error code

Example:
<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="StockQuoteProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
    </inSequence>
    <outSequence>
      <send/>
    </outSequence>
    <faultSequence>
      <sequence key="fault_mediator_endpoint_fault"/>
      <send/>
    </faultSequence>
    <endpoint>
      <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
    </endpoint>
  </target>
  <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
  <description/>
</proxy>


Sequence: fault_format.xml
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_format" trace="disable">
  <payloadFactory media-type="xml">
    <format>
      <Fault>
        <ERROR_CODE>$1</ERROR_CODE>
        <ERROR_MESSAGE>$2</ERROR_MESSAGE>
        <ERROR_DETAIL>$3</ERROR_DETAIL>
      </Fault>
    </format>
    <args>
      <arg evaluator="xml" expression="get-property('ERROR_CODE')"/>
      <arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
      <arg evaluator="xml" expression="get-property('ERROR_DETAIL')"/>
    </args>
  </payloadFactory>
</sequence>


This sequence can be used to format the incoming fault message before it send to client. It’s simply changed the incoming format to user defined format by using payloadfactory mediator


<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="StockQuoteProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
    </inSequence>
    <outSequence>
      <send/>
    </outSequence>
    <faultSequence>
      <sequence key="fault_format"/>
      <send/>
    </faultSequence>
    <endpoint>
      <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
    </endpoint>
  </target>
  <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
  <description/>
</proxy>


Sequence: fault_full_log.xml

<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_full_log" trace="disable">
  <log category="ERROR" level="custom">
    <property name="text" value="An error occured"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('ERROR_MESSAGE')" name="ERROR_MESSAGE"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('ERROR_CODE')" name="ERROR_CODE"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('ERROR_DETAIL')" name="ERROR_DETAIL"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('ERROR_EXCEPTION')" name="ERROR_EXCEPTION"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('FaultTo')" name="FaultTo"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('FAULT')" name="FAULT"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('SENDING_FAULT')" name="SENDING_FAULT"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="/" name="REPLY"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('RESPONSE ')" name="RESPONSE"/>
    <property xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('HTTP_SC')" name="HTTP_SC"/>
  </log>
  <log category="ERROR" level="full"/>
</sequence>

This sequence can be used to log ful incoming SOAP Fault message. This sequence is better to use with some other error sequence depend on the requirement.


Example:

<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="StockQuoteProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
  <target>
    <inSequence>
      <property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
    </inSequence>
    <outSequence>
      <send/>
    </outSequence>
    <faultSequence>
      <sequence key="fault_full_log"/>
      <sequence key="fault_format"/>
      <send/>
    </faultSequence>
    <endpoint>
      <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
    </endpoint>
  </target>
  <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
  <description/>
</proxy>
Sequence: fault_rest_api_json.xml
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_rest_api_json" trace="disable">
  <log level="custom">
    <property name="STATUS" value="Executing custom 'fault' sequence"/>
    <property xmlns:ns3="http://org.apache.synapse/xsd" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" expression="get-property('ERROR_CODE')" name="ERROR_CODE"/>
    <property xmlns:ns3="http://org.apache.synapse/xsd" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" expression="get-property('ERROR_MESSAGE')" name="ERROR_MESSAGE"/>
  </log>
  <payloadFactory media-type="xml">
    <format>
      <rs:fault xmlns:rs="http://wso2.com">
        <rs:code>$1</rs:code>
        <rs:type>Status report</rs:type>
        <rs:message>Runtime Error</rs:message>
        <rs:description>$2</rs:description>
      </rs:fault>
    </format>
    <args>
      <arg xmlns:ns3="http://org.apache.synapse/xsd" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" evaluator="xml" expression="$ctx:ERROR_CODE"/>
      <arg xmlns:ns3="http://org.apache.synapse/xsd" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" evaluator="xml" expression="$ctx:ERROR_MESSAGE"/>
    </args>
  </payloadFactory>
  <filter xmlns:ns3="http://org.apache.synapse/xsd" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xpath="$ctx:CUSTOM_HTTP_SC">
    <then>
      <property expression="$ctx:CUSTOM_HTTP_SC" name="HTTP_SC" scope="axis2" type="STRING"/>
    </then>
    <else>
      <property name="HTTP_SC" scope="axis2" type="STRING" value="500"/>
    </else>
  </filter>
  <property name="RESPONSE" scope="default" type="STRING" value="true"/>
  <header action="remove" name="To" scope="default"/>
  <property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
  <property action="remove" name="ContentType" scope="axis2"/>
  <property action="remove" name="Authorization" scope="transport"/>
  <property action="remove" name="Host" scope="transport"/>
  <property action="remove" name="Accept" scope="transport"/>
  <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
  <send/>
</sequence>
This sequence can be used in rest apis to return the error message in json format. Following JSON message will return as response upon a endpoint failure

{
"fault":
{
"code":101503,
"type":"Status report",
"message":"Runtime Error",
"description":"Error connecting to the back end"
}}

Example:
<?xml version="1.0"?>
<api xmlns="http://ws.apache.org/ns/synapse" name="xml_to_json_api_in" context="/test">
  <resource methods="GET" uri-template="/endpoint" protocol="http" faultSequence="fault_rest_api_json">
    <inSequence>
      <send>
        <endpoint>
          <http trace="disable" uri-template="http://localhost:8080/test/endpoint">
            <timeout>
              <duration>60000</duration>
              <responseAction>fault</responseAction>
            </timeout>
          </http>
        </endpoint>
      </send>
    </inSequence>
    <outSequence>
      <sequence key="xml_to_json_out_message"/>
      <send/>
    </outSequence>
  </resource>
</api>

Sequence: fault_rest_api_xml.xml
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="fault_rest_api_xml" trace="disable">
  <log level="custom">
    <property name="STATUS" value="Executing default 'fault' sequence"/>
    <property expression="get-property('ERROR_CODE')" name="ERROR_CODE"/>
    <property expression="get-property('ERROR_MESSAGE')" name="ERROR_MESSAGE"/>
  </log>
  <filter regex="soap1[1-2]" source="get-property('MESSAGE_FORMAT')">
    <then>
      <property name="SOAP_FAULT_CODE" scope="default" type="STRING" value="Server"/>
      <makefault version="soap11">
        <code expression="$ctx:SOAP_FAULT_CODE"/>
        <reason expression="$ctx:ERROR_MESSAGE"/>
      </makefault>
    </then>
    <else>
      <payloadFactory media-type="xml">
        <format>
          <rs:fault xmlns:rs="http://repsol.es">
            <rs:code>$1</rs:code>
            <rs:type>Status report</rs:type>
            <rs:message>Runtime Error</rs:message>
            <rs:description>$2</rs:description>
          </rs:fault>
        </format>
        <args>
          <arg evaluator="xml" expression="$ctx:ERROR_CODE"/>
          <arg evaluator="xml" expression="$ctx:ERROR_MESSAGE"/>
        </args>
      </payloadFactory>
      <filter regex="^(?!.*(POST|PUT)).*$" source="$axis2:HTTP_METHOD">
        <then>
          <property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
        </then>
        <else/>
      </filter>
    </else>
  </filter>
  <filter xpath="$ctx:CUSTOM_HTTP_SC">
    <then>
      <property expression="$ctx:CUSTOM_HTTP_SC" name="HTTP_SC" scope="axis2" type="STRING"/>
    </then>
    <else>
      <property name="HTTP_SC" scope="axis2" type="STRING" value="500"/>
    </else>
  </filter>
  <property name="RESPONSE" scope="default" type="STRING" value="true"/>
  <header action="remove" name="To" scope="default"/>
  <property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
  <property action="remove" name="ContentType" scope="axis2"/>
  <property action="remove" name="Authorization" scope="transport"/>
  <property action="remove" name="Host" scope="transport"/>
  <property action="remove" name="Accept" scope="transport"/>
  <send/>
</sequence>
This sequence can be used in rest apis to return the error message in xml format. Following xml message will return as response upon a endpoint failure

<rs:fault xmlns:rs="http://wso2.com">
<rs:code>101503</rs:code>
<rs:type>Status report</rs:type>
<rs:message>Runtime Error</rs:message>
<rs:description>Error connecting to the back end</rs:description>
</rs:fault>

Example:
<?xml version="1.0"?>
<api xmlns="http://ws.apache.org/ns/synapse" name="xml_to_json_api_in" context="/test">
  <resource methods="GET" uri-template="/endpoint" protocol="http" faultSequence="fault_rest_api_xml">
    <inSequence>
      <send>
        <endpoint>
          <http trace="disable" uri-template="http://localhost:8080/test/endpoint">
            <timeout>
              <duration>60000</duration>
              <responseAction>fault</responseAction>
            </timeout>
          </http>
        </endpoint>
      </send>
    </inSequence>
    <outSequence>
      <sequence key="xml_to_json_out_message"/>
      <send/>
    </outSequence>
  </resource>
</api>

Common Sequences

Sequence: json_to_xml_in_message.xml

<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="json_to_xml_in_message" trace="disable">
  <property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
</sequence>
  • This sequence can be used to transform the json message to xml. For example if endpoint accepts xml message and incoming message to the ESB is json, then using this sequence ESB will convert the json to its xml representation and send to the endpoint. This will convert json format of the incoming message to its xml format. If it need further customize representation, it can be achieve through script mediator of payloadfactory mediator

Example:
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse" context="/test" name="test">
  <resource faultSequence="fault" methods="POST" protocol="http" uri-template="/endpoint">
    <inSequence>
      <send>
        <sequence key="json_to_xml_in_message"/>
        <endpoint>
          <http trace="disable" uri-template="http://localhost:8080/test/endpoint">
            <!-- Consumes JSON data -->
            <timeout>
              <duration>60000</duration>
              <responseAction>fault</responseAction>
            </timeout>
          </http>
        </endpoint>
      </send>
    </inSequence>
    <outSequence>
      <send/>
    </outSequence>
  </resource>
</api>


Sequence: json_to_xml_out_message.xml
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="json_to_xml_out_message" trace="disable">
  <property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
</sequence>
  • This sequence can be used to transform the json message to xml. For example if client accepts xml message and incoming message from the endpoint to ESB is json, then using this sequence ESB will convert the json to its xml representation and send back to the client. This will convert json format of the outgoing message to its xml format. If it need further customize representation, it can be achieve through script mediator of payloadfactory mediator

Example:
<?xml version="1.0"?>
<api xmlns="http://ws.apache.org/ns/synapse" context="/test" name="test">
  <resource faultSequence="fault" methods="GET" protocol="http" uri-template="/endpoint">
    <inSequence>
      <send>
        <endpoint>
          <http trace="disable" uri-template="http://localhost:8080/test/endpoint">
            <!--Returns JSON Outout-->
            <timeout>
              <duration>60000</duration>
              <responseAction>fault</responseAction>
            </timeout>
          </http>
        </endpoint>
      </send>
    </inSequence>
    <outSequence>
      <sequence key="json_to_xml_out_message"/>
      <send/>
    </outSequence>
  </resource>
</api>

Sequence: xml_to_json_in_message.xml

  • This sequence can be used to transform the xml message to json. For example if endpoint accepts json message and incoming message to the ESB is xml, then using this sequence ESB will convert the xml to its json representation and send to the endpoint. This will convert xml format of the incoming message to its json format. If it need further customize representation, it can be achieve through script mediator of payloadfactory mediator
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="xml_to_json_in_message" trace="disable">
  <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
</sequence>
Example :
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse" context="/test" name="test">
  <resource faultSequence="fault" methods="POST" protocol="http" uri-template="/endpoint">
    <inSequence>
      <send>
        <sequence key="json_to_xml_in_message"/>
        <endpoint>
          <http trace="disable" uri-template="http://localhost:8080/test/endpoint">
            <!-- Consumes XML data -->
            <timeout>
              <duration>60000</duration>
              <responseAction>fault</responseAction>
            </timeout>
          </http>
        </endpoint>
      </send>
    </inSequence>
    <outSequence>
      <send/>
    </outSequence>
  </resource>
</api>

Sequence: xml_to_json_out_message.xml

  • This sequence can be used to transform the xml message to json. For example if client accepts json message and incoming message from the endpoint to ESB is xml, then using this sequence ESB will convert the xml to its json representation and send back to the client. This will convert xml format of the outgoing message to its json format. If it need further customize representation, it can be achieve through script mediator of payloadfactory mediator
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="xml_to_json_out_message" trace="disable">
  <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
</sequence>
Example:
<?xml version="1.0"?>
<api xmlns="http://ws.apache.org/ns/synapse" context="/test" name="test">
  <resource faultSequence="fault" methods="GET" protocol="http" uri-template="/endpoint">
    <inSequence>
      <send>
        <endpoint>
          <http trace="disable" uri-template="http://localhost:8080/test/endpoint">
            <!--Returns XML Outout-->
            <timeout>
              <duration>60000</duration>
              <responseAction>fault</responseAction>
            </timeout>
          </http>
        </endpoint>
      </send>
    </inSequence>
    <outSequence>
      <sequence key="xml_to_json_out_message"/>
      <send/>
    </outSequence>
  </resource>
</api>

Sequence: log_in_message.xml
  • This sequence can be used to log the incoming message to the ESB
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="log_in_message" trace="disable">
  <log level="full">
    <property name="IN_MESSAGE" value="IN_MESSAGE"/>
  </log>
</sequence>
Example:

<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="test" startOnLoad="true" trace="disable" transports="https http">
  <target>
    <endpoint name="endpoint_urn_uuid_a4889f4d-5945-4ca0-9e24-50efe3f504a5">
      <address trace="disable" uri="http://localhost:9000/services"/>
    </endpoint>
    <inSequence>
      <sequence key="log_in_message"/>
    </inSequence>
    <outSequence>
      <send/>
    </outSequence>
    <faultSequence/>
  </target>
</proxy>
Sequence: log_out_message.xml
  • This sequence can be used to log the outgoing message from the ESB
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="log_out_message" trace="disable">
  <log level="full">
    <property name="OUT_MESSAGE" value="OUT_MESSAGE"/>
  </log>
</sequence>
Example:
<?xml version="1.0"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="test" startOnLoad="true" trace="disable" transports="https http">
  <target>
    <endpoint name="endpoint_urn_uuid_33a885f4-9840-4874-8145-d3e89d1704c0">
      <address trace="disable" uri="http://localhost:9000/"/>
    </endpoint>
    <inSequence/>
    <outSequence>
      <sequence key="log_out_message"/>
      <send/>
    </outSequence>
    <faultSequence/>
  </target>
</proxy>

NOTE : Sequences can be mixed up to achieve necessary requirements


[2] - https://docs.wso2.com/display/ESB460/Error+Handling+and+Error+Codes

2 comments: