In a Service Oriented Architecture (SOA), service calls are the primary communication mechanism. Service interaction leverages a well-defined interface definition called Web Service Description Language (WSDL). A service usually receives a request message and replies with a response message. However, in certain circumstances, for example, when either a back-end system or a database that a service requires is not available, the service might respond with a fault message. Depending on the interface definition, these faults can be clearly defined or not defined at all.
Unmodeled faults are faults that are not defined in the WSDL file of the corresponding Web service. When such a Web service is invoked from within a Business Process Execution Language (BPEL) process, there is no way to catch with a specific fault handler any unmodeled faults that might be thrown during the Web service call. This article shows you how to facilitate fault handling within a BPEL process so you can make use of modeled faults, even though the Web service does not expose any.
You see how to create and populate a modeled fault based on the SOAP fault information within a service message object (SMO) using an IBM WebSphere Enterprise Service Bus 6.1 (hereafter called ESB) custom mediation primitive. Once modeled, faults can be processed by specific fault handlers and it is possible to react differently to different faults. This article also introduces a human task based failover mechanism which enables the user to take corrective action and to rerun the service invocation.
Figure 1 shows an application scenario used throughout this article. A BPEL process invokes a mediation flow using a Service Component Architecture (SCA) binding. The mediation module calls the Web service (SOAP/HTTP), catches any unmodeled faults, transforms them into modeled faults, and returns those modeled faults to the BPEL process, where they are caught and handled.
Figure 1. Overall scenario
To start the scenario, first create the Web service, which is a sample stock quote service. This service provides basic stock quote information to consumers. For a given stock number, a corresponding stock quote is returned. For simplicity, the stock information is stored in a hash map.
Table 1: Example stock quotes
| Stock number symbol | Stock quote |
|---|---|
| StockA | 200 |
| StockB | 700 |
| StockC | N.A. |
Various exceptions can occur; for example, exceptions can result from faulty user input or lack of availability of business data. Specifically, an exception is thrown if either the passed stock number does not exist (such as StockD), or if the stock quote for a given stock number is not available (StockC).
The service implementation uses the
SOAPFaultException to explicitly raise faults so that the exact SOAP 1.1 fault message contents can be determined. The following list shows the elements contained in a SOAP fault exception:
-
The
faultcodeelement is mandatory. Four values are possible:- VersionMismatch
- The SOAP receiver encountered an invalid namespace for the SOAP Envelope element.
- MustUnderstand
- A child element with a
must understandattribute set toTRUEwas not understood. - Client
- The client's message contained incorrect information or was incorrectly formed.
- Server
- A problem occurred during message processing on the server.
-
The
faultstringelement is mandatory. It provides a human readable explanation for the fault. -
The
faultactorelement is optional. It contains the URI of the Web service which caused the exception. -
The
faultdetailelement is optional and contains additional information regarding the fault.
Listings 1 and 2 display the SOAP fault element contained in a response SOAP message in the case when a SOAP fault exception was thrown by the service provider.
Listing 1. SOAP fault when stock number is not available
<soapenv:Envelope <soapenv:Header/>
<soapenv:Body>
<soapenv:Fault>
<faultcode>Client</faultcode>
<faultstring>stock no. not available</faultstring>
<faultactor>http://localhost:9080/WebServiceProject/services
/StockQuoteService</faultactor>
<detail encodingStyle="">
<Info>stock no. must be StockA, StockB or StockC</Info>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope> |
Listing 2. SOAP fault when stock quote. is not available
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<soapenv:Fault>
<faultcode>Server</faultcode>
<faultstring>stock quote not available</faultstring>
<faultactor>http://localhost:9080/WebServiceProject/services
/StockQuoteService
</faultactor>
<detail encodingStyle="">
<Info>no stock quote available for stock no. StockC</Info>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
|
The Java implementation of the SOAP fault exception is depicted in Listing 3.
Listing 3. SOAP fault exception implementation
public class StockQuoteServiceException extends SOAPFaultException{
public StockQuoteServiceException(QName faultcode, String faultstring,
String faultactor, Detail faultdetail){
super(faultcode, faultstring, faultactor, faultdetail);
}
public Detail getDetail() {
return super.getDetail();
}
public String getFaultActor() {
return super.getFaultActor();
}
public QName getFaultCode() {
return super.getFaultCode();
}
public String getFaultString() {
return super.getFaultString();
}
}
|
Listing 4 shows a part of the stock quote service implementation. If a StockNo is passed to a service which is not available, then a StockQuoteServiceException is created and thrown.
Listing 4. get stock quote service implementation
public String getStockQuote (String stockNo) throws
StockQuoteServiceException{
faultactor =
http://localhost:9080/WebServiceProject/services/StockQuoteService";
try{
faultdetail = soapFactory.createDetail();
}catch (SOAPException se){
se.printStackTrace();
}
if (!stock.containsKey(stockNr)){
faultcode = new QName("Client");
faultstring = "StockNrNotAvailableException";
try{
Name infoName = soapFactory.createName("info");
SOAPElement infoElement = soapFactory.createElement(infoName);
infoElement.addTextNode("stock nr. must be StockA, StockB or
StockC");
faultdetail.addChildElement(infoElement);
}catch (SOAPException se){
se.printStackTrace();
}
throw new StockQuoteServiceException(faultcode,faultstring,
faultactor,faultdetail);
} |
In WebSphere Integration Developer 6.1 (hereafter called Integration Developer), business processes are defined in BPEL, which handles the invocation of Web services and their orchestration into larger-grained processes in a graphical fashion.
In IBM's Service Component Architecture, of which BPEL processes are a part, WSDL serves as the primary way of specifying interfaces between service components. A BPEL process is exposed through a WSDL interface, and BPEL uses the WSDL interfaces of other services to invoke them.
Comparing modeled and unmodeled faults
In this scenario, the stock quote service, which is invoked by a BPEL process, is exposed by the fairly simple WSDL interface as shown in Figure 2.
Figure 2. Stock quote service interface
The getStockQuote operation takes a string as an input message and returns another string as a result. However, there is no fault message associated with this operation. Therefore, the consumer of this service is unaware of the various faults that the service might return.
If we chose to directly invoke this service from within our BPEL process, our only option to handle the fault would be a common Catch all fault handler to which all faults are directed. A distinct handling based on the nature of the fault would not be possible.
For this reason we prefer a WSDL interface which exposes the various kinds of faults to which our service consumer can react. The interface in Figure 3 resembles the previous interface; however, this interface extends the previous one by adding two fault messages (StockNoNotExist, StockQuoteNotAvailable).
Figure 3. Fault enhanced Stock Quote Service interface
These types define the following modeled fault types:
Figure 4. Modeled fault types
Considering the semantics of the two faults, you can make the following distinction:
- StockNoNotExist indicates that the user entered an invalid stock quote number. A sensible reaction to this fault would be to ask the user to correct the input to the process.
- StockQuoteNotAvailable points to a missing quote for an existing stock number, such as when the stock has been suspended from trading. There is nothing the consumer of the service can do about this event; therefore, this problem might be logged as a result.
Using the fault-aware interface for the service invocation, you can model a detailed, distinct error handler to implements these actions.
Figure 5 shows the invocation activity of the stock quote Web service associated with the two modeled faults (StockQuoteNotAvailable, StockNrNotExist).
Figure 5: Web service invocation with fault handlers
Now the BPEL process and the service are ready for deployment. However, the fault information provided by the service is still too generic to be consumed by the process. Some fault transformation is required to adapt the service response. A mediation module bridges that gap between the business process module and the stock quote Web service.
Figure 6 shows the assembly diagram of the StockQuoteMediationModule. A mediation flow with the same name provides the fault handling logic; an SCA export (StockQuoteMediationModuleExport) links to the business process; and a Web service import (StockQuoteServiceImport1) calls the stock quote Web service.
Figure 6. StockQuote Mediation Module Assembly Diagram
If you define a mediation flow, you also need to specify a source and a target interface. In this case the source interface contains the modeled fault (FaultStockQuoteService), and the target interface (StockQuoteServicePartner) is the Web service interface to call.
Figure 7. Mediation: Operation mapping
In the next step, you see how to map the unmodeled fault to the modeled fault in the response flow. A Mediation Module, running in IBM WebSphere Process Server V6.1 (hereafter called Process Server), provides the capability to catch the unmodeled fault.
Figure 8 shows the response part of the mediation flow.
Figure 8. Mediation: Response flow
If the Web service call is successful the mediation flow takes the upper path and the response is returned to the input response terminal/callout (because of the incompatible message types a simple business object map is required). If an unknown exception has occurred during the Web service call, the fail terminal is triggered (surrounded with a red circle).
In our scenario, the fail terminal is wired to a custom mediation primitive which is wired to a fault node. This fault node appears on the Integration Developer mediation flow canvas if you have defined one or more modeled faults in conjunction with the operation of the source interface. The unmodeled fault information is included in the context part of the service message object. (/context/failInfo/failureString). The failureString contains the SOAP body which in turn contains the SOAP fault (see Listing 1 and Listing 2).
To extract the SOAP fault information and pass a modeled fault back to the caller, you need a custom mediation primitive. The use of code within the custom mediation primitive facilitates flexible error information parsing.
Functions provided by the custom mediation primitive:
- Extract the SOAP fault information (
faultcode, faultstring, faultactor, faultdetail) fromfailureStringcontained in the context part of the service message object:javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder(); String soapFault = smo.getContext().getFailInfo().getFailureString(); java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream (soapFault.getBytes()); org.w3c.dom.Document document = builder.parse(bis); String faultcode = document.getElementsByTagName("faultcode").item(0). getChildNodes().item(0).getNodeValue(); String faultstring = document.getElementsByTagName("faultstring").item(0). getChildNodes().item(0).getNodeValue(); String faultactor = document.getElementsByTagName("faultactor").item(0). getChildNodes().item(0).getNodeValue(); String faultdetail = document.getElementsByTagName("info").item(0). getChildNodes().item(0).getNodeValue();
- Analyze the failure cause and create a corresponding fault object. If the client is responsible for the fault (by providing a stock number which does not exist) a
StockNoFaultfault object is created. If the failure is because no stock quote is available for a given stock number, aStockQuoteFaultobject is created.… com.ibm.websphere.sca.ServiceManager serviceManager = new com.ibm.websphere.sca.ServiceManager(); com.ibm.websphere.bo.BOFactory bofactory = (com.ibm.websphere.bo.BOFactory)serviceManager. locateService("com/ibm/websphere/bo/BOFactory"); … if (faultcode.equalsIgnoreCase("client")){ commonj.sdo.DataObject stockNoBO = bofactory.create("http://StockNoFault","StockNoFault"); stockNoBO.setString("faultstring",faultstring); stockNoBO.setString("faultcode", faultcode); stockNoBO.setString("faultactor", faultactor); stockNoBO.setString("faultdetail", faultdetail); }
- Put the fault object into the service message object body and pass that service message object to the input fault node using the appropriate output terminal of the custom mediation primitive. The output terminal used determines which modeled fault is thrown:
StockNoNotExistorStockQuoteNotAvailable.commonj.sdo.DataObject body = (commonj.sdo.DataObject)smo.getBody(); body.setDataObject(0,stockNoBO); smo.setBody(body); StockNoTerminal.fire(smo);
Failover techniques using human tasks
Once specific fault handling is available within the business process, you can incorporate human tasks to facilitate failover. You could use the specific fault information as the input message for a human task. Based on the fault information displayed, a human can set an appropriate output message. The information contained within that output message determines how the process flow continues after the human task has completed. By providing corresponding data, a user could decide to:
- Repeat the Web service call.
- Skip the Web service call.
- Change the initial request data for the Web service, if the call is supposed to be repeated.
Figure 9 shows the part of the BPEL process that handles the invocation of the
getStockQuote Web service. The loop facilitates the repetition of the "Invoke" activity in the case in which a fault has been thrown. If the stock number does not exist, the Mediation Module returns a fault; the BPEL process invokes the appropriate fault handler and instantiates a human task.
Figure 9. BPEL: Failover using human tasks
The output message of that human task determines whether to repeat the Web service call (remain within the loop) or to skip the call (leave the loop) and continue with the process flow. If the call is supposed to be repeated, then the human processing the task can enter another stock number. If the stock quote for an existing stock number does not exist, no human task is instantiated because the resolution of the failure is not in the caller's power. Instead, the BPEL process logs an appropriate message, exits the loop, and no additional Web service call is initiated.
The last section illustrates the execution of the overall scenario. To trigger a StockNoNotExistfault, start a process instance and enter a stock number which does not exist (remember: only StockA, StockB, and StockC exist).
Figure 10 shows a process instance that was started. It invokes the stock quote service with a non-existent stock number (StockD), which triggers the corresponding fault handler (StockNoNotExist) which, in turn, instantiates a human task (StockNoNotExistFailover).
Figure 10: Start a new process instance (trigger StockNoNotExist fault)
Figure 11 shows the human task (StockNoNotExistFailover) which facilitates the failover. The task input message displays the request parameter which was passed to the service and which is responsible for the fault (StockD), as well as the detailed fault information; this fault information was retrieved from the SOAP fault within the custom mediation.
Based on that information, the user can decide which task output message is applicable. In this scenario, the user decides to repeat the call (Retry is set to true) with another stock number (StockC).
Figure 11: Failover human task
StockNoNotExistFailover
If StockC is passed to the stock quote service and a
StockQuoteNotAvailable fault is thrown, then no human task is triggered and information is logged indicating that a failure has occurred during the service call. Because there is nothing the consumer of the service can do about this event, there is no way to repeat the call; the process exits the loop and continues the rest of the process flow.
You now know a fault handling technique for Web services. You can use this technique to catch unmodeled faults, extract fault information and generate specific faults, using the ESB. You can enable BPEL processes to differentiate various types of faults and to react accordingly.
Furthermore, you learned a failover pattern for BPEL processes, in which a user can take corrective action upon a failed service invocation.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample code | FaultHandlingPI.zip | 49 KB | HTTP |
Information about download methods
- The
SMO Structure InfoCenter topic provides an overview of the Service Message Object (SMO) mediation primitive.
- The
Unmodeled faults InfoCenter topic is in Education Assistant audo-visual presentation that introduces you to unmodeled faults and SMOs.
-
Using WebSphere ESB mediation modules describes options for designing and developing composite business services to cope with changing requirements. It discusses WebSphere ESB capabilities in relation to WebSphere Process Server and how to use ESB to enable runtime integration with Web services.
-
Web services programming tips and tricks: Exception Handling with JAX-RPC discusses how to explicitly declare faults in WSDL operations. This tip first examines the exception behavior in the absence of wsdl:fault. It then focuses on how a wsdl:fault is mapped to a checked Java exception and how a JAX-RPC runtime handles this checked exception.
-
WebSphere business integration zone provides extensive technical resources to help you leverage this set of products and tools in a wide range of business scenarios.
-
WebSphere Enterprise Service Bus technical resources help you learn how to use this IBM product for Web services connectivity, JMS messaging, and service-oriented integration to power your SOA.
- The
WebSphere Integration Developer and Websphere Process Server resources page helps you leverage this rich process integration platform for enterprise services based on SOA.
- The
WebSphere MQ resources provides a wide range of technical resources related to IBM's premier message product line.

Marco Lezajic is an IT specialist at IBM Boeblingen Lab in Germany. He holds a diploma degree in computer science of the University of Furtwangen. He belongs to the lab based services POC team and provides technical consultancy on WebSphere Business Integration solutions. His expertise includes WebSphere Process Server, WebSphere Enterprise Service and Web Sphere Integration Developer.

Boris Feist is an IT specialist at IBM Boeblingen Lab in Germany. He holds a diploma degree in computer science of the University of Albstadt-Sigmaringen. He belongs to the lab based services team and provides technical consultancy on WebSphere Business Integration solutions. His expertise includes WebSphere Process Server, WebSphere Enterprise Service and Web Sphere Integration Developer.



