AdroitLogic Private Ltd.

  • Increase font size
  • Default font size
  • Decrease font size

Schema validation and Error handling with the UltraESB

This example introduces XSD schema validation of XML payloads with the UltraESB. Additionally it shows how the UltraESB performs error handling and recovery - and how a sequence defines another sequence as its error handler.

Schema validation

The example configuration we use is as follows - and it uses the static utility method Mediation.validate() API by passing one or more XSD schema files paths within a String array, along with an XPath expression that selects the node to be validated.

    <u:proxy id="soap-proxy-1">
<u:transport id="http-8280"/>
<u:target inDestination="stockquote" outDestination="response">
<u:inSequence onErrorInvoke="sequenceErrorHandler">
<u:java><![CDATA[
String[] schemas = {"samples/resources/stock.xsd", "samples/resources/common.xsd"};
String[][] ns = {{"soap", "http://soap.services.samples/"}};
Mediation.validate(msg, schemas, "//soap:getQuote", ns);
]]></u:java>
</u:inSequence>
</u:target>
</u:proxy>

To try out this sample, start the sample configuration 203 of the UltraESB through the ToolBox, or the command line as follows

asankha@asankha:~/java/ultraesb-1.0-beta-1/bin$ ./ultraesb.sh -sample 203

Then start the sample Jetty server and the HTTP/S client through the ToolBox, and issue a Preset "1" request to the URL http://localhost:8280/service/soap-proxy-1 - for which you will get a successful response. Now, edit the request such that its not well formed XML, and you will get an error message as follows:

HTTP/1.0 500 Internal Server Error
Host: localhost:8280
SOAPAction: urn:getQuote
User-Agent: AdroitLogic ToolBox 0.1 [adroitlogic.org]
Content-Type: text/xml; charset=UTF-8
Date: Thu, 14 Jan 2010 18:58:03 GMT
Server: UltraESB/1.0-beta-1
Content-Length: 306
Connection: close

<S11:Envelope xmlns:S11="http://schemas.xmlsoap.org/soap/envelope/"><S11:Body><S11:Fault>
<faultcode>S11:Server</faultcode>
<faultstring>Validation Failed</faultstring>
<detail>Error converting org.adroitlogic.ultraesb.core.format.RawFileMessage to a DOM message</detail>
</S11:Fault></S11:Body></S11:Envelope>

Note that the validation error thrown by the 'inSequence' transferred control to the error handler sequence 'sequenceErrorHandler'. It was the 'sequenceErrorHandler' shown below that created a SOAP fault message and forwarded it back to the client.

    <u:sequence id="sequenceErrorHandler">
<u:java><![CDATA[
System.out.println("Error handler called");
Mediation.setPayloadToSOAP11Fault(msg, null, "Validation Failed", msg.getLastException().getMessage());
Mediation.sendResponseAndDrop(msg, 500);
]]></u:java>
</u:sequence>

Evaluating XPath expressions over payload

Next, we will look at the proxy service "soap-proxy-3", which will test the stock symbol, and forward requests for the symbol "ADRT" to the valid endpoint, and any other symbol to an invalid endpoint. The configuration of this proxy service is as follows

    <u:proxy id="soap-proxy-3">
<u:transport id="http-8280"/>
<u:target inDestination="stockquote" outDestination="response" errorSequence="serviceErrorHandler">
<u:inSequence>
<u:java><![CDATA[
String[][] ns = {{"soap", "http://soap.services.samples/"}};
if (Mediation.filter(msg, "//soap:getQuote/request/symbol", ns, "ADRT")) {
Mediation.sendToEndpoint(msg, "stockquote");
} else {
Mediation.sendToEndpoint(msg, "stockquote-err");
}
]]></u:java>
</u:inSequence>
</u:target>
</u:proxy>

<u:sequence id="serviceErrorHandler">
<u:java><![CDATA[
System.out.println("Service error handler called");
Mediation.setPayloadToSOAP11Fault(msg, null, "Generic service error", msg.getLastException().getMessage());
Mediation.sendResponseAndDrop(msg, 500);
]]></u:java>
</u:sequence>

<u:endpoint id="stockquote">
<u:address>http://localhost:9000/service/SimpleStockQuoteService</u:address>
</u:endpoint>

<u:endpoint id="stockquote-err">
<u:address>http://localhost:9002/service/SimpleStockQuoteService</u:address>
</u:endpoint>

The Mediation.filter() API tests if a XPath expression evaluates to true, or its resultant String value matches a regular expression. In the above example, we test the result of the XPath expression "//soap:getQuote/request/symbol" against the regex "ADRT" and we define the prefix as appropriate. The Mediation.sentToEndpoint() API call allows one to perform Content Based Routing (CBR) for the destination endpoint. Finally, the "stockquote-err" points to an invalid endpoint (i.e. port 9002) and thus a request to any symbol except "ADRT" will fail as follows:

HTTP/1.0 500 Internal Server Error
Host: localhost:8280
SOAPAction: urn:getQuote
User-Agent: AdroitLogic ToolBox 0.1 [adroitlogic.org]
Content-Type: text/xml; charset=UTF-8
Date: Thu, 14 Jan 2010 19:08:42 GMT
Server: UltraESB/1.0-beta-1
Content-Length: 277
Connection: close

<S11:Envelope xmlns:S11="http://schemas.xmlsoap.org/soap/envelope/"><S11:Body><S11:Fault>
<faultcode>S11:Server</faultcode>
<faultstring>Generic service error</faultstring>
<detail>The endpoint : stockquote-err has no ready addresses</detail>
</S11:Fault></S11:Body></S11:Envelope>

Note that the service level error handler "serviceErrorHandler" was triggered by the failure, and thus the returned message contains the "...Generic service error.." message.