Wednesday, August 5, 2009

BPEL fault handling

Faults in BPEL can arise in various situations:
  1. When a BPEL process invokes a synchronous web service operation, the operation might return a WSDL fault message, which results in a BPEL fault.
  2. A BPEL process can explicitly signal (throw) a fault.
  3. A fault can be thrown automatically, for example, selectionFailure or uninitializedVariable; these typically indicate a problem in your process where you've not implemented something correctly.
  4. The BPEL server might encounter error conditions in the run-time environment, network communications, or any other such reason. This kind of faults are called "Failures".

Here is an example of how to catch and access WSDL faults thrown by an External Web Service. This is the scenario:

  1. You have an external web service named "fault". This WS generates a fault because something in it fails.
  2. Then, you have a BPEL process named "faultCaller" that calls the "fault" service, so you must catch the fault thrown.
  3. Also, if a network failure appears while calling the "fault" service, then your BPEL process should handle that error.

Let's create the scenario, first the "fault" service

  1. Declare a fault message:

    <element name=" MyFault">
    <complexType>
    <sequence>
    <element name="myError" type="string"></element>
    </sequence>
    </complexType>
    </element>


    <message name="FaultMessage">
    <part name=" payload" element="tns:MyFault"></part>
    </message>


    <operation name="process">
    <input message="tns:FaultHRequestMessage"/>
    <output message="tns:FaultHResponseMessage"/>
    <fault name=" fault"message=" tns:FaultMessage"></fault>
    </operation>

  2. Then, inside your BPEL process throw an arbitrary fault:


    < bpws:throw faultName=" someFault"/>
  3. Finally, build your fault message:


    <bpws:from>
    <bpws:literal>Error from External WebService </bpws:literal>
    </bpws:from>
    <bpws:to part=" payload" variable=" myFault">
    <bpws:query queryLanguage=" urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0"> <![CDATA[/tns:myError ]]> </bpws:query>
    </bpws:to>

  4. Deploy it as

    <soap:address location=" http://localhost:8080/ode/processes/fault">


Now, create "faultCaller" service

  1. First, add the namespace for the failure handling.

    < xmlns:ext="http://ode.apache.org/activityRecovery">

  2. Declare the variable that will hold the error comming from the "fault" service.
    <bpws:variable messageType=" ns0:FaultMessage" name=" faultMaker" />


  3. Inside the invoke activity that calls the "fault" service put the fault handling activities. First lets put the failureHandling structure.

      <ext:failureHandling>
    <ext:faultOnFailure>true</ext:faultOnFailure>
    <ext:retryFor>2</ext:retryFor>
    <ext:retryDelay>30</ext:retryDelay>
    </ext:failureHandling>

  4. Now, Catch run-time environment faults, like network communications issues:
    <bpws:catch faultName="ext:activityFailure" >
    activity
    </bpws:catch>



  5. And finally, catch your own faults comming from the "fault" service.
    <bpws:catch faultName="ns0:fault" faultVariable="faultMaker" faultMessageType="ns0:FaultMessage">
    activity
    </bpws:catch>



  6. Your BPEL process should be like the following diagram:

While calling "faultCaller", you should catch your fault message error comming from "fault" service, and if you undeploy the "fault" service, then if you call again the "faultCaller" you should catch the failure.

Download the whole example from here.

4 comments:

Unknown said...

Quite helpful, thanks. :)

Unknown said...

I'm using the failure activity from ODE, but I have a very strange behavior: on Windows is working, on Linux is completing ignoring this activity, although I have the same environment. Do you have any idea which could be the reason?

Waruna said...

In my opinion, There should be a catchAll or a catch activity without any attributes. So that, it will be executed for all other fault types. In that way you can handle unexpected faults as well.

Unknown said...

+1 with Waruna