Skip Headers
Oracle® Fusion Middleware Developer's Guide for Oracle SOA Suite
11g Release 1 (11.1.1.6.3)

Part Number E10224-15
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

12 Using Fault Handling in a BPEL Process

This chapter describes how to use fault handling in a BPEL process. Fault handling allows a BPEL process service component to handle error messages or other exceptions returned by outside web services, and to generate error messages in response to business or runtime faults. This chapter also describes how to use the fault management framework to catch faults and perform user-specified actions defined in a fault policy file.

This chapter includes the following sections:

For additional information on creating fault handling in a SOA composite application, see the Fusion Order Demo application.

12.1 Introduction to a Fault Handler

Fault handlers define how the BPEL process service component responds when web services return data other than what is normally expected (for example, returning an error message instead of a number). An example of a fault handler is where the web service normally returns a credit rating number, but instead returns a negative credit message.

Figure 12-1 provides an example of how a fault handler sets a credit rating variable to -1000.

Figure 12-1 Fault Handling

Description of Figure 12-1 follows
Description of "Figure 12-1 Fault Handling"

The code segment in Example 12-1 defines the fault handler for this operation in the BPEL file:

Example 12-1 Fault Handler Definition

<faultHandlers>
     <catch faultName="services:NegativeCredit" faultVariable="crError">
      <assign name="crin">
         <copy>
           <from expression="-1000">
           </from>
           <to variable="input" part="payload"
               query="/autoloan:loanApplication/autoloan:creditRating"/>
         </copy>
       </assign>
     </catch>
</faultHandlers>

The faultHandlers tag contains the fault handling code. Within the fault handler is a catch activity, which defines the fault name and variable, and the copy instruction that sets the creditRating variable to -1000.

When you select web services for the BPEL process service component, determine the possible faults that may be returned and set up a fault handler for each one.

12.2 Introduction to BPEL Standard Faults

This section identifies the standard faults for BPEL 1.1 and BPEL 2.0.

12.2.1 BPEL 1.1 Standard Faults

This section identifies the standard faults for BPEL 1.1. Unless otherwise noted below, the Business Process Execution Language for Web Services Specification defines the following standard faults in the namespace of http://schemas.xmlsoap.org/ws/2003/03/business-process/:

  • bindingFault (BPEL extension fault defined in http://schemas.oracle.com/bpel/extension)

  • conflictingReceive

  • conflictingRequest

  • correlationViolation

  • forcedTermination

  • invalidReply

  • joinFailure

  • mismatchedAssignmentFailure

  • remoteFault (BPEL extension fault defined in http://schemas.oracle.com/bpel/extension)

  • repeatedCompensation

  • selectionFailure

  • uninitializedVariable

Standard faults are defined as follows:

  • Typeless, meaning they do not have associated messageTypes

  • Not associated with any Web Services Description Language (WSDL) message

  • Caught without a fault variable:

    <catch faultName="bpws:selectionFailure">
    

12.2.2 BPEL 2.0 Standard Faults

The following list specifies the standard faults defined within the WS-BPEL specification. All standard fault names are qualified with the standard WS-BPEL namespace.

  • ambiguousReceive

  • completionConditionFailure

  • conflictingReceive

  • conflictingRequest

  • correlationViolation

  • invalidBranchCondition

  • invalidExpressionValue

  • invalidVariables

  • joinFailure

  • mismatchedAssignmentFailure

  • missingReply

  • missingRequest

  • scopeInitializationFailure

  • selectionFailure

  • subLanguageExecutionFault

  • uninitializedPartnerRole

  • uninitializedVariable

  • unsupportedReference

  • xsltInvalidSource

  • xsltStylesheetNotFound

12.2.2.1 Fault Handling Order of Precedence in BPEL 2.0

In BPEL 2.0, the order of precedence for catching faults thrown without associated data is as follows:

  • If there is a catch activity with a matching faultName value that does not specify a faultVariable attribute, the fault is sent to the identified catch activity.

  • Otherwise, if there is a catchAll activity, the fault is sent to the catchAll fault handler.

  • Otherwise, the fault is processed by the default fault handler.

In BPEL 2.0, the order of precedence for catching faults thrown with associated data is as follows:

  • If there is a catch activity with a matching faultName value that does not specify a faultVariable attribute, the fault is sent to the identified catch activity.

  • If the fault data is a WSDL message type in which the following exists:

    • The message contains a single part defined by an element.

    • There exists a catch activity with a matching faultName value that has a faultVariable whose associated faultElement QName matches the QName of the runtime element data of the single WSDL message part.

    Then, the fault is sent to the identified catch activity with the faultVariable initialized to the value in the single part's element.

  • Otherwise, if there is a catch activity with a matching faultName value that does not specify a faultVariable attribute, the fault is sent to the identified catch activity. In this case, the fault value is not available from within the fault handler, but is available to the rethrow activity.

  • Otherwise, if there is a catch construct without a faultName attribute that has a faultVariable whose type matches the type of the runtime fault data, then the fault is sent to the identified catch activity.

  • Otherwise, if the fault data is a WSDL message type in which the message contains a single part defined by an element and there exists a catch activity without a faultName attribute that has a faultVariable whose associated faultElement's QName matches the QName of the runtime element data of the single WSDL message part, the fault is sent to the identified catch activity with the faultVariable initialized to the value in the single part's element.

  • Otherwise, if there is a catchAll activity, the fault is sent to the catchAll fault handler.

  • Otherwise, the fault is handled by the default fault handler.

12.3 Introduction to Categories of BPEL Faults

A BPEL fault has a fault name called a Qname (name qualified with a namespace) and a possible messageType. There are two categories of BPEL faults:

12.3.1 Business Faults

Business faults are application-specific faults that are generated when there is a problem with the information being processed (for example, when a social security number is not found in the database). A business fault occurs when an application executes a throw activity or when an invoke activity receives a fault as a response. The fault name of a business fault is specified by the BPEL process service component. The messageType, if applicable, is defined in the WSDL. A business fault can be caught with a faultHandler using the faultName and a faultVariable.

<catch faultName="ns1:faultName" faultVariable="varName">

12.3.2 Runtime Faults

Runtime faults are the result of problems within the running of the BPEL process service component or web service (for example, data cannot be copied properly because the variable name is incorrect). These faults are not user-defined, and are thrown by the system. They are generated if the process tries to use a value incorrectly, a logic error occurs (such as an endless loop), a Simple Object Access Protocol (SOAP) fault occurs in a SOAP call, an exception is thrown by the server, and so on.

Several runtime faults are automatically provided. These faults are included in the http://schemas.oracle.com/bpel/extension namespace. These faults are associated with the messageType RuntimeFaultMessage. The WSDL file shown in Example 12-2 defines the messageType:

Example 12-2 messageType Definition

<?xml version="1.0" encoding="UTF-8" ?> 
<definitions name="RuntimeFault"
  targetNamespace="http://schemas.oracle.com/bpel/extension"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.xmlsoap.org/wsdl/">

  <message name="RuntimeFaultMessage">
   <part name="code" type="xsd:string" /> 
   <part name="summary" type="xsd:string" /> 
   <part name="detail" type="xsd:string" /> 
  </message>
</definitions>

If a faultVariable (of messageType RuntimeFaultMessage) is used when catching the fault, the fault code can be queried from the faultVariable, along with the fault summary and detail.

12.3.2.1 bindingFault

A bindingFault is thrown inside an activity if the preparation of the invocation fails. For example, the WSDL of the process fails to load. A bindingFault is not retryable. This type of fault usually must be fixed by human intervention.

12.3.2.2 remoteFault

A remoteFault is also thrown inside an activity. It is thrown because the invocation fails. For example, a SOAP fault is returned by the remote service.

12.3.2.3 replayFault

A replayFault replays the activity inside a scope. At any point inside a scope, this fault is migrated up to the scope. The server then re-executes the scope from the beginning.

12.4 Using the Fault Management Framework

Oracle SOA Suite provides a generic fault management framework for handling faults in BPEL processes. If a fault occurs during runtime in an invoke activity in a process, the framework catches the fault and performs a user-specified action defined in a fault policy file associated with the activity. If a fault results in a condition in which human intervention is the prescribed action, you perform recovery actions from Oracle Enterprise Manager Fusion Middleware Control. The fault management framework provides an alternative to designing a BPEL process with catch activities in scope activities.

This section provides an overview of the components that comprise the fault management framework.

See Chapter 22, "Using Oracle Mediator Error Handling" for details about Oracle Mediator fault handling capabilities.

12.4.1 How to Design a Fault Policy

This section describes how to design a fault policy.

Note:

The Facades API enables you to programmatically perform the abort, retry (with a success action), continue, rethrow, and replay recovery options. For information, see Oracle Fusion Middleware Infrastructure Management Java API Reference for Oracle SOA Suite.

12.4.1.1 Understanding How Fault Policy Binding Resolution Works

A fault policy bindings file associates the policies defined in a fault policy file with the SOA composite application or the component (service component or reference binding component). The framework attempts to identify a fault policy binding in the following order:

  • Reference binding component defined in the composite.xml file.

  • BPEL process or Oracle Mediator service component defined in the composite.xml file.

  • SOA composite application defined in the composite.xml file.

During the resolution process, if no action is found that matches the condition, the framework assumes that resolution failed and moves to the next resolution level.

For example, assume an invoke activity faults with faultname="abc". There is a policy binding specified in the fault-binding.xml file:

  • SOA composite application binds to policy-id-1

  • BPEL process or Oracle Mediator service component or reference binding component binds to policy-id-2

In the fault-bindings.xml file, the following bindings are also specified:

  • SOA composite application binds to policy-id-3

  • Reference binding component or service component binds to policy-id-4

The fault management framework behaves as follows:

  • First match the resolve binding (in this case, policy-id-2).

  • If the fault resolution fails, go to the next possible match (policy-id-4).

  • If the fault resolution fails, go to the next possible match (policy-id-3).

  • If the fault resolution fails, go to the next possible match (in this case, policy-id-1).

  • If the fault resolution still fails, the fault is sent to the BPEL fault catch activity.

12.4.1.2 Creating a Fault Policy File for Automated Fault Recovery

  1. Create a fault policy file (for example, named fault-policies.xml). This file includes condition and action sections for performing specific tasks.

  2. Place the file in the same directory as the composite.xml file or place it in a different location and define the oracle.composite.faultPolicyFile property. Example 12-4 provides details.

    Example 12-4 Defining Properties

    <property
     name="oracle.composite.faultPolicyFile">oramds:/apps/faultpolicyfiles/
     fault-policies.xml
    </property>
    <property
     name="oracle.composite.faultBindingFile">oramds:/apps/faultpolicyfiles/
     fault-bindings.xml
    </property>
    
  3. Define the condition section of the fault policy file.

    • Note the following details about the condition section:

      • This section provides a condition based on faultName.

      • Multiple conditions may be configured for a faultName.

      • Each condition has one test section (an XPath expression) and one action section.

      • The test section (XPath expression) is evaluated for the fault variable available in the fault.

      • The action section has a reference to the action defined in the same file.

      • You can only query the fault variable available in the fault.

      • The order of condition evaluation is determined by the sequential order in the document.

      Table 12-1 provides examples of condition section use in the fault policy file. All actions defined in the condition section must be associated with an action in the action section.

      Table 12-1 Use of the condition Section in the Fault Policy File

      Condition Example Fault Policy File Syntax

      This condition is checking a fault variable for code = "WSDLFailure"

      An action of ora-terminate is specified.

      <condition>
        <test>$fault.code="WSDLReading Error"
        </test>
        <action ref="ora-terminate"/>
      </condition>
      

      No test condition is provided. This is a catchAll condition for a given faultName.

      <condition>
         <action ref="ora-rethrow"/>
      </condition>
      

      If the faultName name attribute is missing, this indicates a catchAll activity for faults that have any QName.

      <faultName > . . . </faultName>
      

  4. Define the action section of the fault policy file. Validation of fault policy files is done during deployment. If you change the fault policy, you must redeploy the SOA composite application that includes the fault policy.

    Table 12-2 provides several examples of action section use in the fault policy file. You can provide automated recovery actions for some faults. In all recovery actions except retry and human intervention, the framework performs the actions synchronously.

    Table 12-2 Use of action Section in the Fault Policy File

    Recovery Actions Fault Policy File Syntax

    Retry: Provides the following actions for retrying the activity.

    • Retry a specified number of times.

    • Provide a delay between retries (in seconds).

    • Increase the interval with an exponential back off.

    • Chain to a retry failure action if retry N times fails.

    • Chain to a retry success action if a retry is successful.

    Note: Exponential back off indicates the next retry attempt is scheduled at 2 x the delay, where delay is the current retry interval. For example, if the current retry interval is 2 seconds, the next retry attempt is scheduled at 4, the next at 8, and the next at 16 seconds until the retryCount value is reached.

    <Action id="ora-retry">
       <Retry>
          <retryCount>3</retryCount>
          <retryInterval>2</retryInterval>
          <exponentialBackoff/>
          <retryFailureAction ref="ora-java"/>
          <retrySuccessAction ref="ora-java"/>
       </Retry>
    </Action>
    

    Note the following details:

    • The framework chains to the retry success action if the retry attempt is successful.

    • If all retry attempts fail, the framework chains to the retry failure action.

    Human Intervention: Causes the current activity to stop processing. You can now go to Oracle Enterprise Manager Fusion Middleware Control and perform manual recovery actions on this instance.

    <Action id="ora-human-intervention">
     <humanIntervention/></Action>
    

    Terminate Process: Terminates the process

    <Action id="ora-terminate"><abort/></Action>
    

    Java Code: Enables you to execute an external Java class.

    returnValue: The implemented Java class must implement a method that returns a string. The policy can chain to a new action based on the returned string.

    For additional information, see Section 12.4.3, "How to Use a Java Action Fault Policy."

    <Action id="ora-java">
    <!-- this is user provided custom java
     class-->
    <javaAction className="mypackage.myClass"
     defaultAction="ora-terminate">
       <returnValue value="REPLAY"
        ref="ora-terminate"/>
       <returnValue value="RETRHOW"
        ref="ora-rethrow-fault"/>
       <returnValue value="ABORT"
        ref="ora-terminate"/>
       <returnValue value="RETRY" ref="ora-retry"/>
       <returnValue value="MANUAL"
        ref="ora-human-intervention"/>
    </javaAction>
    </Action>
    

    Rethrow Fault: The framework sends the fault to the BPEL fault handlers (catch activities in scope activities). If none are available, the fault is sent up.

    <Action id="ora-rethrow-fault"><rethrowFault/></Action>
    

    Replay Scope: Raises a replay fault.

    <Action id="ora-replay-scope"><replayScope/></Action>
    

Note:

The preseeded recovery action tag names (ora-retry, ora-human-intervention, ora-terminate, and so on) are only samples. You can substitute these names with ones appropriate to your environment.

Example 12-5 shows a fault policy file with fully-defined condition and action sections.

Notes:

  • Fault policy file names are not restricted to one specific name. However, they must conform to the fault-policy.xsd schema file.

  • Example 12-5 provides an example of catching faults based on fault names. You can also catch faults based on message types, or on both:

    <fault name="myfault" type="fault:faultType"> 
    

Example 12-5 Fault Policy File

<?xml version="1.0" encoding="UTF-8"?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <faultPolicy version="0.0.1" id="FusionMidFaults"
 xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns="http://schemas.oracle.com/bpel/faultpolicy"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Conditions>
      <faultName xmlns:medns="http://schemas.oracle.com/mediator/faults"
 name="medns:mediatorFault">
        <condition>
          <action ref="MediatorJavaAction"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:remoteFault">
        <condition>
          <action ref="BPELJavaAction"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:bindingFault">
        <condition>
          <action ref="BPELJavaAction"/>
        </condition>
      </faultName>
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:runtimeFault">
        <condition>
          <action ref="BPELJavaAction"/>
        </condition>
      </faultName>
    </Conditions>
    <Actions>
      <!-- Generics -->
      <Action id="default-terminate">
        <abort/>
      </Action>
      <Action id="default-replay-scope">
        <replayScope/>
      </Action>
      <Action id="default-rethrow-fault">
        <rethrowFault/>
      </Action>
      <Action id="default-human-intervention">
        <humanIntervention/>
      </Action>
      <Action id="MediatorJavaAction">
        <!-- this is user provided class-->
        <javaAction className="MediatorJavaAction.myClass"
 defaultAction="default-terminate">
          <returnValue value="MANUAL" ref="default-human-intervention"/>
        </javaAction>
      </Action>
      <Action id="BPELJavaAction">
        <!-- this is user provided class-->
        <javaAction className="BPELJavaAction.myAnotherClass"
 defaultAction="default-terminate">
          <returnValue value="MANUAL" ref="default-human-intervention"/>
        </javaAction>
      </Action>
    </Actions>
  </faultPolicy>
</faultPolicies>

12.4.1.3 Associating a Fault Policy with Fault Policy Binding

Note:

The fault policy file binding file must be named fault-bindings.xml. This conforms to the fault-bindings.xsd schema file.

  1. Create a fault policy binding file (fault-bindings.xml) that associates the policies defined in the fault policy file with the level of fault policy binding you are using (either a SOA composite application or a component (reference binding component or BPEL process or Oracle Mediator service component).

  2. Place the file in the same directory as the composite.xml file or place it in a remote location and define the oracle.composite.faultBindingFile property as shown in Step 2 of Section 12.4.1.2, "Creating a Fault Policy File for Automated Fault Recovery."

    Example 12-6 shows a fault policy bindings file that associates the fault policies defined in the fault-policies.xml file with the FusionMidFaults SOA composite application.

Example 12-6 fault-buildings.xml File

<?xml version="1.0" encoding="UTF-8" ?>
<faultPolicyBindings version="0.0.1"
 xmlns="http://schemas.oracle.com/bpel/faultpolicy"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <composite faultPolicy="FusionMidFaults"/>
    <!--<composite faultPolicy="ServiceExceptionFaults"/>-->
    <!--<composite faultPolicy="GenericSystemFaults"/>-->
</faultPolicyBindings>

12.4.1.4 Additional Fault Policy and Fault Policy Binding File Samples

This section provides additional samples of fault policy and fault policy binding files. Example 12-7 shows the fault-policies.xml file contents.

Example 12-7 fault-policies.xml File

<?xml version="1.0" encoding="UTF-8"?>
<faultPolicies xmlns="http://schemas.oracle.com/bpel/faultpolicy">
<faultPolicy version="2.0.1" 
                   id="CRM_ServiceFaults" 
                   xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:xs="http://www.w3.org/2001/XMLSchema"
                   xmlns="http://schemas.oracle.com/bpel/faultpolicy" 
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                       <Conditions>
        <!-- Fault if wsdlRuntimeLocation is not reachable -->
        <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:remoteFault">
            <condition>
                <test>$fault.code="WSDLReadingError"</test>
                <action ref="ora-terminate"/>
            </condition>
            <condition>
                <action ref="ora-java"/>
            </condition>
        </faultName>
        <!-- Fault if location port is not reachable-->
        <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension"
 name="bpelx:bindingFault">
            <!--ORA-00001: unique constraint violated on insert-->
            <condition>
                <test>$fault.code="1"</test>
                <action ref="ora-java"/>
            </condition>
            <!--ORA-01400: cannot insert NULL -->
            <condition>
                <test xmlns:test="http://test">$fault.code="1400"</test>
                <action ref="ora-terminate"/>
            </condition>
            <!--ORA-03220: required parameter is NULL or missing -->
            <condition>
                <test>$fault.code="3220"</test>
                <action ref="ora-terminate"/>
            </condition>
            <condition>
                <action ref="ora-retry-crm-endpoint"/>
            </condition>
        </faultName>
        <!-- Business faults -->
        <!-- Fault comes with a payload of error, make sure the name space is
 provided here or at root level -->
        <faultName xmlns:credit="http://services.otn.com"
 name="credit:NegativeCredit">
            <!-- you get this fault when SSN starts with 0-->
            <condition>
                <test>$fault.payload="Bankruptcy Report"</test>
                <action ref="ora-human-intervention"/>
                <!--action ref="ora-retry"/-->
            </condition>
            <!-- you get this fault when SSN starts with 1-->
            <condition>
                <test>$fault.payload="Bankruptcy Report-abort"</test>
                <action ref="ora-terminate"/>
            </condition>
            <!-- you get this fault when SSN starts with 2-->
            <condition>
                <test>$fault.payload="Bankruptcy Report-rethrow"</test>
                <action ref="ora-rethrow-fault"/>
            </condition>
            <!-- you get this fault when SSN starts with 3-->
            <condition>
                <test>$fault.payload="Bankruptcy Report-replay"</test>
                <action ref="ora-replay-scope"/>
            </condition>
            <!-- you get this fault when SSN starts with 4-->
            <condition>
                <test
 xmlns:myError="http://services.otn.com">$fault.payload="Bankruptcy
 Report-human"</test>
                <action ref="ora-human-intervention"/>
            </condition>
            <!-- you get this fault when SSN starts with 5-->
            <condition>
                <test>$fault.payload="Bankruptcy Report-java"</test>
                <action ref="ora-java"/>
            </condition>
        </faultName>
                       
                       </Conditions>
                       <Actions>
                           <Action id="ora-retry">
            <retry>
                <retryCount>3</retryCount>
                <retryInterval>2</retryInterval>
                <exponentialBackoff/>
                <retryFailureAction ref="ora-java"/>
                <retrySuccessAction ref="ora-java"/>
            </retry>
        </Action>
        <Action id="ora-retry-crm-endpoint">
            <retry>
                <retryCount>5</retryCount>
                <retryFailureAction ref="ora-java"/>
                <retryInterval>5</retryInterval>
                <retrySuccessAction ref="ora-java"/>
            </retry>
        </Action>
        <Action id="ora-replay-scope">
            <replayScope/>
        </Action>
        <Action id="ora-rethrow-fault">
            <rethrowFault/>
        </Action>
        <Action id="ora-human-intervention">
            <humanIntervention/>
        </Action>
        <Action id="ora-terminate">
            <abort/>
        </Action>
        <Action id="ora-java">
            <!-- this is user provided class-->
            <javaAction
 className="com.oracle.bpel.client.config.faultpolicy.TestJavaAction"
 defaultAction="ora-terminate" propertySet="prop-for-billing">
                <returnValue value="REPLAY" ref="ora-terminate"/>
                <returnValue value="RETRHOW" ref="ora-rethrow-fault"/>
                <returnValue value="ABORT" ref="ora-terminate"/>
                <returnValue value="RETRY" ref="ora-retry"/>
                <returnValue value="MANUAL" ref="ora-human-intervention"/>
            </javaAction>
        </Action>
                       
                       </Actions>
                   <Properties>
                           <propertySet name="prop-for-billing">
            <property name="user_email_recipient">bpeladmin</property>
            <property name="email_recipient">joe@abc.com</property>
            <property name="email_recipient">mike@xyz.com</property>
            <property name="email_threshold">10</property>
            <property name="sms_recipient">+429876547</property>
            <property name="sms_recipient">+4212345</property>
            <property name="sms_threshold">20</property>
            <property name="user_email_recipient">john</property>
        </propertySet>
        <propertySet name="prop-for-order">
            <property name="email_recipient">john@abc.com</property>
            <property name="email_recipient">jill@xyz.com</property>
            <property name="email_threshold">10</property>
            <property name="sms_recipient">+42222</property>
            <property name="sms_recipient">+423335</property>
            <property name="sms_threshold">20</property>
        </propertySet>
                   
                   </Properties>                   
</faultPolicy>
<faultPolicy version="2.0.1" 
                   id="Billing_ServiceFaults" 
                   xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:xs="http://www.w3.org/2001/XMLSchema"
        
                   xmlns="http://schemas.oracle.com/bpel/faultpolicy" 
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Conditions>
    <faultName>
    <condition>
       <action ref="ora-manual"/>
    </condition>
    </faultName>
</Conditions>
<Actions>
        <Action id="ora-manual">
            <humanIntervention/>
        </Action>
</Actions>
</faultPolicy>
</faultPolicies>

Example 12-8 shows the fault-buildings.xml file that associates the fault policies defined in fault-policies.xml.

Example 12-8 Fault Policy Bindings File

<?xml version="1.0" encoding="UTF-8"?>
<faultPolicyBindings version="2.0.1"
 xmlns="http://schemas.oracle.com/bpel/faultpolicy"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <composite faultPolicy="ConnectionFaults"/>
    <component faultPolicy="ServiceFaults">
        <name>Component1</name>
        <name>Component2</name>
    </component>
    <!-- Below listed component names use polic CRM_SeriveFaults --> 
    <component faultPolicy="CRM_ServiceFaults">
        <name>HelloWorld</name>
        <name>ShippingComponent</name>
        <name>AnotherComponent"</name>
    </component>
    <!-- Below listed reference names and port types use polic CRM_ServiceFaults
 --> 
    <reference faultPolicy="CRM_ServiceFaults">
        <name>creditRatingService</name>
        <name>anotherReference</name>
        <portType
 xmlns:credit="http://services.otn.com">credit:CreditRatingService</portType>
        <portType
 xmlns:db="http://xmlns.oracle.com/pcbpel/adapter/db/insert/">db:insert_
plt</portType>
    </reference>
    <reference faultPolicy="test1">
        <name>CreditRating3</name>
    </reference>
</faultPolicyBindings>

12.4.1.5 Designing a Fault Policy with Multiple Rejection Handlers

If you design a fault policy that uses the action handler for rejected messages, note that only one write action can be performed. Multiple write actions cannot be performed, even if you define multiple rejection handlers, as shown in Example 12-9. In this case, only the first rejection handler defined (for this example, ora-queue) is executed.

Example 12-9 Fault Policy with Multiple Rejection Handlers

<faultName xmlns:rjm="http://schemas.oracle.com/sca/rejectedmessages" 
name="rjm:FileIn"> 
        <condition> 
           <action ref="ora-queue"/> 
           
        </condition> 
       </faultName> 
        <faultName xmlns:rjm="http://schemas.oracle.com/sca/rejectedmessages" 
name="rjm:FileIn"> 
        <condition> 
           <action ref="ora-file"/> 
           
        </condition> 
       </faultName>

12.4.2 How to Execute a Fault Policy

You deploy a fault policy as part of a SOA composite application. After deployment, you can perform the following fault recovery actions from Oracle Enterprise Manager Fusion Middleware Control:

  • Retry the activity

  • Modify a variable (available to the faulted activity)

  • Continue the instance (mark the activity as a success)

  • Rethrow the exception

  • Abort the instance

  • Throw a replay scope exception

For additional information, see Oracle Fusion Middleware Administrator's Guide for Oracle SOA Suite and Oracle Business Process Management Suite for the following:

  • Instructions on executing a fault policy in Oracle Enterprise Manager Fusion Middleware Control

  • Use cases in which you define a fault policy that uses human intervention

12.4.3 How to Use a Java Action Fault Policy

Note the following details when using the Java action fault policy:

  • The Java class provided follows a specific interface. This interface returns a string. Multiple values can be provided for output and fault policy to take after execution.

  • Additional fault policy can be executed by providing a mapping from the output value (return value) of implemented methods to a fault policy.

  • If no ReturnValue is specified, the default fault policy is executed, as shown in Example 12-10.

Example 12-10 Java Action Fault Policy

<Action id="ora-java">
  <javaAction className="mypackage.myclass"
    defaultAction="ora-human-intervention" propertySet="prop-for-billing">
   <!--defaultAction is a required attribute, but propertySet is optional-->
   <!-- attribute-->
     <ReturnValue value="RETRY" ref="ora-retry"/>   
     <!--value is not nilable attribute & cannot be empty-->
     <ReturnValue value="RETRHOW" ref="ora-rethrow-fault"/>
  </javaAction>
</Action>

Table 12-3 provides an example of ReturnValue use.

Table 12-3 System Interpretation of Java Action Fault Policy

Code Description
<ReturnValue value="RETRY"
 ref="ora-retry"/>

Execute the ora-retry action if the method returns a string of RETRY.

<ReturnValue value="”
  ref=”ora-rethrow”/>

Fails in validation.

<javaAction
 className="mypackage.myclass"
 defaultAction="ora-human-intervention">

Execute ora-human-intervention after Java code execution. This attribute is used if the return from the method does not match any provided ReturnValue.

<ReturnValue value="RETRY"
 ref="ora-retry"/>
<ReturnValue value="” ref=””/>   

Fails in validation.

<javaAction
 className="mypackage.myclass"
 defaultAction=" ora-human-intervention">
<ReturnValue></ReturnValue>

Fails in validation.


To invoke a Java class, you can provide a class that implements the IFaultRecoveryJavaClass interface. IFaultRecoveryJavaClass is included in the fabric-runtime.jar file. The package name is oracle.integration.platform.faultpolicy.

The IFaultRecoveryJavaClass interface has two methods, as shown in Example 12-11.

Example 12-11 implementation of IFaultRecoveryJavaClass

public interface IFaultRecoveryJavaClass
{
public void handleRetrySuccess( IFaultRecoveryContext ctx );
public String handleFault( IFaultRecoveryContext ctx );
}

Note the following details:

  • handleRetrySuccess is invoked upon a successful retry attempt. The retry policy chains to a Java action on retrySuccessAction.

  • handleFault is invoked to execute a policy of type javaAction.

Example 12-12 shows the data available with IFaultRecoveryContext:

Example 12-12 Data Available with IFaultRecoveryContext

public interface IFaultRecoveryContext {

/**
 * Gets implementation type of the fault.
 * @return
 */
public String getType();

/**
 * @return Get property set of the fault policy action being executed.
 */
public Map getProperties();

/**
 * @return Get fault policy id of the fault policy being executed.
 */
public String getPolicyId();

/**
 * @return Name of the faulted partner link.
 */
public String getReferenceName();

/**
 * @return Port type of the faulted reference .
 */
public QName getPortType();
}

The service engine implementation of this interface provides more information (for example, Oracle BPEL Process Manager). Example 12-13 provides details.

Example 12-13 Service Engine Implementation of IFaultRecoveryContext

public class BPELFaultRecoveryContextImpl extends BPELXExecLetUtil implements
IBPELFaultRecoveryContext,  IFaultRecoveryContext{
...
}

Oracle BPEL Process Manager-specific data is available with IBPELFaultRecoveryContext, as shown in Example 12-14.

Example 12-14 Oracle BPEL Process Manager-Specific Data

public interface IBPELFaultRecoveryContext {
public void addAuditTrailEntry(String message);

public void addAuditTrailEntry(String message, Object detail);

public void addAuditTrailEntry(Throwable t);
/**
 * @return Get action id of the fault policy action being executed.
 */
public String getActionId();

/**
 * @return Type of the faulted activity.
 */
public String getActivityId();

/**
 * @return Name of the faulted activity.
 */
public String getActivityName();

/**
 * @return Type of the faulted activity.
 */
public String getActivityType();

/**
 * @return Correleation id of the faulted activity.
 */
public String getCorrelationId();

/**
 * @return BPEL fault that caused the invoke to fault.
 */
public BPELFault getFault();

/**
 * @return Get index value of the instance
 */
public String getIndex(int i);

/**
 * @return get Instance Id of the current process instance of the faulted
 *         activity.
 */
public long getInstanceId();

/**
 * @return Get priority of the current process instance of the faulted
 *         activity.
 */
public int getPriority();

/**
 * @return Process DN.
 */
public ComponentDN getProcessDN();

/**
 * @return Get status of the current process instance of the faulted
 *         activity.
 */
public String getStatus();

/**
 * @return Get title of the current process instance of the faulted
 *         activity.
 */
public String getTitle();

public Object getVariableData(String name) throws BPELFault;

public Object getVariableData(String name, String partOrQuery)
throws BPELFault;

public Object getVariableData(String name, String part, String query)
throws BPELFault;

/**
 * @param priority
 *            Set priority of the current process instance of the faulted
 *            activity.
 * @return
 */
public void setPriority(int priority);

/**
 * @param status
 *            Set status of the current process instance of the faulted
 *            activity.
 */
public void setStatus(String status);

/**
 * @param title
 *            Set title of the current process instance of the faulted
 *            activity.
 * @return
 */
public String setTitle(String title);

public void setVariableData(String name, Object value) throws BPELFault;

public void setVariableData(String name, String partOrQuery, Object value)
throws BPELFault;

public void setVariableData(String name, String part, String query,
Object value) throws BPELFault;
}

Example 12-15 provides an example of javaAction implementation.

Example 12-15 Implementation of a javaAction

public class TestJavaAction implements IFaultRecoveryJavaClass {
public void handleRetrySuccess(IFaultRecoveryContext ctx) {
System.out.println("This is for retry success");
handleFault(ctx);
}
public String handleFault(IFaultRecoveryContext ctx) {           
System.out.println("-----Inside handleFault-----\n" + ctx.toString());

                dumpProperties(ctx.getProperties());
/* Get BPEL specific context here */
BPELFaultRecoveryContextImpl bpelCtx = (BPELFaultRecoveryContextImpl) ctx;
bpelCtx.addAuditTrailEntry("hi there");
System.out.println("Policy Id" + ctx.getPolicyId());
         ...
        }

12.4.4 What You May Need to Know About Fault Management Behavior When the Number of Instance Retries is Exceeded

When you configure a fault policy to recover instances with the ora-retry action and the number of specified instance retries is exceeded, the instance is marked as open.faulted (in-flight state). The instance remains active.

Marking instances as open.faulted ensures that no instances are lost. You can then configure another fault handling action following the ora-retry action in the fault policy file, such as the following:

  • Configure an ora-human-intervention action to manually perform instance recovery from Oracle Enterprise Manager Fusion Middleware Control.

  • Configure an ora-terminate action to close the instance (mark it as closed.faulted) and never retry again.

However, if you do not set an action to be performed after an ora-retry action in the fault policy file and the number of instance retries is exceeded, the instance remains marked as open.faulted, and recovery attempts to handle the instance.

For example, if no action is defined in the fault policy file shown in Example 12-16 after ora-retry:

Example 12-16 No Action Defined

<Action id="ora-retry">
       <retry>
          <retryCount>2</retryCount>
          <retryInterval>2</retryInterval>
          <exponentialBackoff/>
       </retry>
  </Action>

The following actions are performed:

  • The invoke activity is attempted (using the above-mentioned fault policy code to handle the fault).

  • Two retries are attempted at increasing intervals (after two seconds, then after four seconds).

  • If all retry attempts fail, the following actions are performed:

    • A detailed fault error message is logged in the audit trail.

    • The instance is marked as open.faulted (in-flight state).

    • The instance is picked up and the invoke activity is re-attempted.

  • Recovery may also fail. In that case, the invoke activity is re-executed. Additional audit messages are logged.

12.4.5 What You May Need to Know Executing the Retry Action with Multiple Faults in the Same Flow

The fault policy retry action may not execute with multiple faults in the same flow. This may be because the retry count has already been reached for any of the previous faults.

For example, assume you define a fault policy with two fault conditions: fault1 and fault2. For both fault conditions, the retry action is specified with a retry count of three. Assume fault1 occurs and the retry action executes three times. You correct the problem for fault1 by modifying the payload, but ensure that fault2 is to be raised when the instance is resubmitted. You then resubmit the faulted instance using Oracle Enterprise Manager Fusion Middleware Control. You expect the second fault condition, fault2, to retry three times according to the fault policy specification. However, this does not occur because the maximum number of retries was already executed for the previous fault1 fault condition.

12.4.6 What You May Need to Know About Binding Level Retry Execution Within Fault Policy Retries

If you are testing retry actions on adapters with both JCA-level retries for the outbound direction and a retry action in the fault policy file for outbound failures, the JCA-level (or binding level) retries are executed within the fault policy retries. For example, assume you have designed the application shown in Figure 12-2:

Figure 12-2 SOA Composite Application

Description of Figure 12-2 follows
Description of "Figure 12-2 SOA Composite Application"

You specify the retry parameters shown in Example 12-17 in the composite.xml file:

Example 12-17 Retry Parameters

<property name="jca.retry.count" type="xs:int" many="false"
  override="may">2</property>
<property name="jca.retry.interval" type="xs:int" many="false"
  override="may">2</property>
<property name="jca.retry.backoff" type="xs:int" many="false"
  override="may">2</property>

In the fault policy file for the EQ reference binding component for the outbound direction, you specify the actions shown in Example 12-18.

Example 12-18 Retry Actions

<retryCount>3</retryCount>
<retryInterval>3</retryInterval>

If an outbound failure occurs, the expected behavior is for the JCA retries to occur within the fault policy retries. When the first retry of the fault policy is executed, the JCA retry is called. In this example, a JCA retry of 2 with an interval of 2 seconds and exponential back off of 2 is executed for every retry of the fault policy:

  • Fault policy retry 1:

    • JCA retry 1 (with 2 seconds interval)

    • JCA retry 2 (with 4 seconds interval)

  • Fault policy retry 2:

    • JCA retry 1 (with 2 seconds interval)

    • JCA retry 2 (with 4 seconds interval)

  • Fault policy retry 3:

    • JCA retry 1 (with 2 seconds interval)

    • JCA retry 2 (with 4 seconds interval)

12.4.7 What You May Need to Know About Defining the ora-java Option

Assume you invoke a SOA composite application with a fault policy/binding defined and see a recoverable fault in Oracle Enterprise Manager Fusion Middleware Control. After you perform a successful fault recovery retry, there is no ora-java option available for selection by default in the After Successful Retry list of the Faults tab of the Instance of process_name page.

This is the expected behavior. For the ora-java option to display, you must explicitly define it in the fault-policies.xml file during design-time. For example, perform the following steps.

  1. Create a fault-policies.xml file in which you explicitly add retrySuccessAction ref="ora-java"/> to the fault-policies.xml file.

    <Action id="ora-retry">
       <Retry>
          <retryCount>3</retryCount>
          <retryInterval>2</retryInterval>
          <exponentialBackoff/>
          <retryFailureAction ref="ora-java"/>
          <retrySuccessAction ref="ora-java"/>
       </Retry>
    </Action> 
    
  2. Deploy the composite and create an instance.

  3. Click the composite instance to invoke the instance trace of the composite.Click the component in which there is a recoverable fault (for example, Oracle BPEL Process Manager, Oracle Mediator, or Oracle BPM).Go to the Faults tab.

  4. Select the Retry option to successfully retry the fault.

    If fault recovery is successful, the After Successful Retry list is displayed.

  5. Select the list and note that the ora-java option is now listed.

For more information about recovering from faults in Oracle Enterprise Manager Fusion Middleware Control, see Oracle Fusion Middleware Administrator's Guide for Oracle SOA Suite and Oracle Business Process Management Suite.

12.5 Catching BPEL Runtime Faults

BPEL runtime faults can be caught as a named BPEL fault. The bindingFault and remoteFault can be associated with a message. This action enables the faultHandler to get details about the faults.

12.5.1 How to Catch BPEL Runtime Faults

The following procedure shows how to use the provided examples to generate a fault and define a fault handler to catch it. In this case, you modify a WSDL file to generate a fault, and create a catch attribute to catch it.

To catch BPEL runtime faults:

  1. Import RuntimeFault.wsdl into your process WSDL. RuntimeFault.wsdl is seeded into the MDS from soa.mar inside soa-infra-wls.ear during its deployment.

    You may see a copy of soa.mar in the deployed SOA Infrastructure in the Oracle WebLogic Server domain, which is a JAR/ZIP file containing RuntimeFault.wsdl.

  2. Declare a variable with messageType bpelx:RuntimeFaultMessage.

  3. Catch it using the following syntax:

    <catch faultName="bpelx:remoteFault"  | "bpelx:bindingFault" faultName="varName">
    

12.6 Getting Fault Details with the getFaultAsString XPath Extension Function

The catchAll activity is provided to catch possible faults. However, BPEL does not provide a method for obtaining additional information about the captured fault. Use the getFaultAsString() XPath extension function to obtain additional information.

12.6.1 How to Get Fault Details with the getFaultAsString XPath Extension Function

Example 12-19 shows how to use this function.

Example 12-19 getFaultAsString() XPath Extension Function

<catchAll>
   <sequence>
      <assign>
         <from expression="bpelx:getFaultAsString()"/>
         <to variable="faultVar" part="message"/>
      </assign>
      <reply faultName="ns1:myFault" variable="faultVar" .../>
   </sequence>
</catchAll>

12.7 Throwing Internal Faults

A BPEL application can generate and receive fault messages. The throw activity has three elements: its name, the name of the fault, and the fault variable. The fault thrown by a throw activity is internal to BPEL. You cannot use a throw activity on an asynchronous process to communicate with a client. Throw activity syntax includes the throw name, fault name, and fault variable:

<throw name="delay" faultName="nsPrefix:fault-1" faultVariable="fVar"/>

12.7.1 How to Create a Throw Activity

To create a throw activity:

  1. In the Component Palette, expand BPEL Constructs.

  2. Drag a Throw activity into the designer.

  3. Double-click and define the Throw activity.

  4. Optionally enter a name or accept the default value.

  5. To the right of the Namespace URI field, click the Search icon to select the fault to monitor.

  6. Select the fault in the Fault Chooser dialog, and click OK.

    The namespace URI for the selected fault displays in the Namespace URI field. Your fault selection also automatically displays in the Local Part field.

    Figure 12-3 provides an example of a completed Throw dialog. This example shows the Throw_Fault_CC_Denied throw activity of the Scope_AuthorizeCreditCard scope activity in the Fusion Order Demo application. This activity throws a fault for orders that are not approved.

  7. Click Apply, then OK.

12.7.2 What Happens When You Create a Throw Activity

Example 12-20 shows the throw activity in the .bpel file after design completion. The OrderProcessor process terminates after executing this throw activity.

Example 12-20 Throw Activity

<throw name="Throw_Fault_CC_Denied"
    faultName="client:OrderProcessorFault"/>

12.8 Rethrowing Faults with the Rethrow Activity

The rethrow activity rethrows faults originally captured by the immediately enclosing fault handler. Only use the rethrow activity within a fault handler (for example, within catch and catchAll activities). The rethrow activity is used in fault handlers to rethrow the captured fault (that is, the fault name and the fault data (if present) of the original fault). The rethrow activity must ignore modifications to fault data. For example:

Note:

This activity is supported in BPEL version 2.0 projects.

12.8.1 How to Create a Rethrow Activity

To create a rethrow activity:

  1. In the Component Palette, expand BPEL Constructs.

  2. Drag a Rethrow activity into the designer.

  3. Double-click and define the Rethrow activity.

  4. Optionally enter a name or accept the default value, as shown in Figure 12-4.

    Figure 12-4 Rethrow Dialog

    Description of Figure 12-4 follows
    Description of "Figure 12-4 Rethrow Dialog"

  5. Click Apply, then OK.

    When complete, design can look similar to that shown in Figure 12-5.

    Figure 12-5 Throw Activity in BPEL Process

    Description of Figure 12-5 follows
    Description of "Figure 12-5 Throw Activity in BPEL Process"

12.8.2 What Happens When You Rethrow Faults

Example 12-21 shows the .bpel file after design is complete for a rethrow activity. The rethrow activity is inside a fault handler (catch activity).

Example 12-21 Rethrow Activity

<scope name="scope1">
  <faultHandlers>
    <catch faultName="tns:error" faultVariable="tmpVar"
 faultElement="tns:fault">
      <sequence>
        <assign>
          <copy>
            <from>concat('caught fault: ', $tmpVar)</from>
            <to>$output.payload</to>
          </copy>
        </assign>
        <rethrow name="Rethrow_1"/>
      </sequence>
    </catch>
  </faultHandlers>
  <throw faultName="tns:error" faultVariable="fault"/>
</scope>

12.9 Returning External Faults

A BPEL process service component can send a fault to another application to indicate a problem, as opposed to throwing an internal fault. In a synchronous operation, the reply activity can return the fault. In an asynchronous operation, the invoke activity performs this function.

12.9.1 How to Return a Fault in a Synchronous Interaction

The syntax of a reply activity that returns a fault in a synchronous interaction is shown in Example 12-22:

Example 12-22 Reply Activity

<reply partnerlinke="partner-link-name"
       portType="port-type-name"
       operation="operation-name"
       variable="variable-name" (optional)
       faultName="fault-name">
</reply>

Always returning a fault in response to a synchronous request is not very useful. It is better to make the activity part of a conditional branch, in which the first branch is executed if the data requested is available. If the requested data is not available, then the BPEL process service component returns a fault with this information.

For more information, see the following chapters:

12.9.2 How to Return a Fault in an Asynchronous Interaction

In an asynchronous interaction, the client does not wait for a reply. The reply activity is not used to return a fault. Instead, the BPEL process service component returns a fault using a callback operation on the same port type that normally receives the requested information, with an invoke activity.

For more information about asynchronous interactions, see Chapter 8, "Invoking an Asynchronous Web Service from a BPEL Process."

12.10 Using a Scope Activity to Manage a Group of Activities

A scope activity provides a container and a context for other activities. A scope provides handlers for faults, events, compensation, data variables, and correlation sets. Using a scope activity simplifies a BPEL flow by grouping functional structures. This grouping enables you to collapse them into what appears to be a single element in Oracle BPEL Designer.

Example 12-23 shows a scope named Scope_FulfillOrder from the WebLogic Fusion Order Demo application. This scope invokes the FulfillOrder Oracle Mediator component, which determines the shipping method for the order.

Example 12-23 Scope Activity

<scope name="Scope_FulfillOrder">
    <variables>
        <variable name="lFulfillOrder_InputVariable"
        messageType="ns17:requestMessage"/>
    </variables>
    <sequence>
        <assign name="Assign_OrderData">
            <copy>
                <from variable="gOrderInfoVariable"
                    query="/ns4:orderInfoVOSDO"/>
                <to variable="lFulfillOrder_InputVariable"
                    part="request" query="/ns4:orderInfoVOSDO"/>
            </copy>
        </assign>
        <invoke name="Invoke_FulfillOrder"
            inputVariable="lFulfillOrder_InputVariable"
            partnerLink="FulfillOrder.FulfillOrder"
            portType="ns17:execute_ptt" operation="execute"/>
    </sequence>
</scope>

12.10.1 How to Create a Scope Activity

To create a scope activity:

  1. In the Component Palette, expand BPEL Constructs.

  2. Drag a Scope activity into the designer.

  3. Open the scope activity by double-clicking it or by single-clicking the Expand icon.

  4. From the Component Palette, drag and define activities to build the functionality within the scope. Figure 12-6 provides details.

    Figure 12-6 Expanded Scope Activity

    Description of Figure 12-6 follows
    Description of "Figure 12-6 Expanded Scope Activity"

  5. Click OK.

    When complete, scope activity design can look as shown in Figure 12-7. This example shows the Scope_AuthorizeCreditCard scope activity of the Fusion Order Demo application.

    Figure 12-7 Scope Activity After Design Completion

    Description of Figure 12-7 follows
    Description of "Figure 12-7 Scope Activity After Design Completion"

12.10.2 How to Add Descriptive Notes and Images to a Scope Activity

You can add descriptive notes to scope activities that provide simple descriptions of the functionality of the scope. You can also change the graphical image of scopes. The notes and images display in Oracle BPEL Designer. This helps to make a scope easier to understand.

To add descriptive notes and images to a scope activity:

  1. Perform one of the following steps:

    • Right-click the scope and select User Documentation.

    • Double-click the scope and select the User Documentation tab.

    The Documentation dialog appears.

  2. In the Comment field, enter a brief description of the functionality of the scope.

  3. In the Image field, click the Search icon to optionally change the graphical image for the scope.

  4. Click OK.

    Your changes display in Oracle BPEL Designer, as shown in Figure 12-8.

    Figure 12-8 Scope with Descriptive Note and Modified Image

    Description of Figure 12-8 follows
    Description of "Figure 12-8 Scope with Descriptive Note and Modified Image"

  5. To edit the note, double-click it.

12.10.3 What Happens After You Create a Scope Activity

Example 12-24 shows the scope activity in the .bpel file after design completion. The Scope_AuthorizeCreditCard scope activity consists of activities that perform the following actions:

  • A catch activity for catching faulted orders in which the credit card number is not provided or the credit type is not valid.

  • A throw activity that throws a fault for orders that are not approved.

  • An assign activity that takes the credit card type, credit card number, and purchase amount, and assigns this information to the input variable for the CreditCardAuthorizationService service.

  • An invoke activity that calls a CreditCardAuthorizationService service to retrieve customer information.

  • A switch activity that checks the results of the credit card validation.

Example 12-24 Scope Activity

<scope name="Scope_AuthorizeCreditCard">
    <variables>
        <variable name="lCreditCardInput"
            messageType="ns2:CreditAuthorizationRequestMessage"/>
        <variable name="lCreditCardOutput"
            messageType="ns2:CreditAuthorizationResponseMessage"/>
    </variables>
    <faultHandlers>
        <catch faultName="bpws:selectionFailure">
            <sequence>
                 <assign name="Assign_noCCNumber">
                     <copy>
                         <from expression="string('CreditCardCheck - NO
                             CreditCard')"/>
                         <to variable="gOrderProcessorFaultVariable"
                             part="code"/>
                     </copy>
                 </assign>
                 <throw name ="Throw_NoCreditCard"
                     faultVariable="gOrderProcessorFaultVariable"
                     faultName="ns9:OrderProcessingFault"/>
            </sequence>
        </catch>
        <catch faultName="ns2:InvalidCredit">
            <sequence>
                <assign name="Assign_InvalidCreditFault">
                    <copy>
                        <from expression="concat(bpws:getVariableData
                             ('gOrderInfoVariable','/ns4:orderInfoVOSDO/
                             ns4:CardTypeCode'), ' is not a valid 
                             creditcard type')"/>
                        <to variable="gOrderProcessorFaultVariable"
                            part="summary"/>
                    </copy>
                    <copy>
                        <from expression="string('CreditCardCheck - NOT VALID')"/>
                        <to variable="gOrderProcessorFaultVariable"
                            part="code"/>
                    </copy>
                </assign>
                <throw name="Throw_OrderProcessingFault"
                    faultName="ns9:OrderProcessingFault"
                    faultVariable="gOrderProcessorFaultVariable"/>
            </sequence>
        </catch>
    </faultHandlers>
    <sequence>
        <assign name="Assign_CreditCheckInput">
            <copy>
                <from variable="gOrderInfoVariable"
                    query="/ns4:orderInfoVOSDO/ns4:OrderTotal"/>
                <to variable="lCreditCardInput" part="Authorization"
                    query="/ns8:AuthInformation/ns8:PurchaseAmount"/>
            </copy>
            <copy>
                <from variable="gOrderInfoVariable"
                    query="/ns4:orderInfoVOSDO/ns4:CardTypeCode"/>
                        <to variable="lCreditCardInput" part="Authorization"
                             query="/ns8:AuthInformation/ns8:CCType"/>
            </copy>
            <copy>
                <from variable="gOrderInfoVariable"
                    query="/ns4:orderInfoVOSDO/ns4:AccountNumber"/>
                <to variable="lCreditCardInput" part="Authorization"
                    query="/ns8:AuthInformation/ns8:CCNumber"/>
                    </copy>
        </assign>
        <invoke name="InvokeCheckCreditCard"
            inputVariable="lCreditCardInput"
            outputVariable="lCreditCardOutput"
            partnerLink="CreditCardAuthorizationService"
            portType="ns2:CreditAuthorizationPort"
            operation="AuthorizeCredit"/>
        <switch name="Switch_EvaluateCCResult">
            <case condition="bpws:getVariableData('lCreditCardOutput','status','
                /ns8:status') != 'APPROVED'">
                <bpelx:annotation>
                    <bpelx:pattern>status &lt;&gt; approved</bpelx:pattern>
                </bpelx:annotation>
                <throw name="Throw_Fault_CC_Denied"
                    faultName="client:OrderProcessorFault"/>
            </case>
        /switch>
    </sequence>
</scope>

12.10.4 What You May Need to Know About Scopes

Scopes can use a significant amount of CPU and memory and should not be overused. Sequence activities use less CPU and memory and can make large BPEL flows more readable.

12.10.5 How to Use a Fault Handler Within a Scope

If a fault is not handled, it creates a faulted state that migrates up through the application and can throw the entire process into a faulted state. To prevent this from occurring, place the parts of the process that have the potential to receive faults within a scope. The scope activity includes the following fault handling capabilities:

  • The catch activity works within a scope to catch faults and exceptions before they can throw the entire process into a faulted state. You can use specific fault names in the catch activity to respond in a specific way to an individual fault.

  • The catchAll activity catches any faults that are not handled by name-specific catch activities.

Example 12-25 shows the syntax for catch and catchAll activities. Assume that a fault named x:foo is thrown. The first catch is selected if the fault carries no fault data. If there is fault data associated with the fault, the third catch is selected if the type of the fault's data matches the type of variable bar. Otherwise, the default catchAll handler is selected. Finally, a fault with a fault variable whose type matches the type of bar and whose name is not x:foo is processed by the second catch. All other faults are processed by the default catchAll handler.

Example 12-25 Catch and CatchAll Activities

<faulthandlers>
   <catch faultName="x:foo">
         <empty/>
      </catch>
   <catch faultVariable="bar">
         <empty/>
      </catch>
   <catch faultName="x:foo" faultVariable="bar">
         <empty/>
      </catch>
   <catchAll>
         <empty/>
      </catchAll>
</faulthandlers>

12.10.6 How to Create a Catch Activity in a Scope

To create a catch activity in a scope:

  1. In the expanded Scope activity, click Add Catch. Figure 12-9 provides details.

    This creates a catch activity in the right side of the scope activity.

  2. Double-click the Catch activity.

  3. Optionally enter a name.

  4. To the right of the Namespace URI field, click the Search icon to select the fault.

  5. Select the fault in the Fault Chooser dialog, and click OK.

    The namespace URI for the selected fault displays in the Namespace URI field. Your fault selection also automatically displays in the Local Part field.

    Figure 12-10 provides an example of a Catch dialog. This example shows the selectionFailure catch activity of the Scope_AuthorizeCreditCard scope activity in the Fusion Order Demo application. This catch activity catches orders in which the credit card number is not provided.

    Figure 12-10 Catch Dialog

    Description of Figure 12-10 follows
    Description of "Figure 12-10 Catch Dialog"

  6. Design additional fault handling functionality.

  7. Click OK.

    Figure 12-11 provides an example of two catch activities for the Scope_AuthorizeCreditCard scope activity. The second catch activity catches credit types that are not valid.

    Figure 12-11 Catch Activities in the Designer

    Description of Figure 12-11 follows
    Description of "Figure 12-11 Catch Activities in the Designer"

12.10.7 What Happens When You Create a Catch Activity in a Scope

Example 12-26 shows the catch activity in the .bpel file after design completion. The selectionFailure catch activity catches orders in which the credit card number is not provided and the InvalidCredit catch activity catches credit types that are not valid.

Example 12-26 Catch Branch

<faultHandlers>
    <catch faultName="bpws:selectionFailure">
        <sequence>
            <assign name="Assign_noCCNumber">
                <copy>
                    <from expression="string('CreditCardCheck - NO CreditCard')"/>
                    <to variable="gOrderProcessorFaultVariable"
                        part="code"/>
                </copy>
            </assign>
            <throw name ="Throw_NoCreditCard"
               faultVariable="gOrderProcessorFaultVariable"
               faultName="ns9:OrderProcessingFault"/>
    </sequence>
 </catch>
 <catch faultName="ns2:InvalidCredit">
    <sequence>
        <assign name="Assign_InvalidCreditFault">
           <copy>
              <from expression="concat(bpws:getVariableData
                 ('gOrderInfoVariable','/ns4:orderInfoVOSDO/ns4:CardTypeCode'), '
                 is not a valid creditcard type')"/>
              <to variable="gOrderProcessorFaultVariable"
                 part="summary"/>
           </copy>
           <copy>
               <from expression="string('CreditCardCheck - NOT VALID')"/>
               <to variable="gOrderProcessorFaultVariable"
                   part="code"/>
           </copy>
        </assign>
        <throw name="Throw_OrderProcessingFault"
           faultName="ns9:OrderProcessingFault"
           faultVariable="gOrderProcessorFaultVariable"/>
    </sequence>
  </catch>
</faultHandlers>

12.10.8 How to Create an Empty Activity to Insert No-Op Instructions into a Business Process

There is often a need to use an activity that does nothing. An example is when a fault must be caught and suppressed. In this case, you can use the empty activity to insert a no-op instruction into a business process.

To create an empty activity:

  1. In the Component Palette, expand BPEL Constructs.

  2. Drag an Empty activity into the designer.

  3. Double-click the Empty activity.

    The Empty dialog appears, as shown in Figure 12-12.

    Figure 12-12 Empty Activity

    Description of Figure 12-12 follows
    Description of "Figure 12-12 Empty Activity"

  4. Optionally enter a name.

  5. Click OK.

12.10.9 What Happens When You Create an Empty Activity

The syntax for an empty activity is shown in Example 12-27.

Example 12-27 Empty Activity

<empty standard-attributes>
    standard-elements
  </empty>

If no catch or catchAll is selected, the fault is not caught by the current scope and is rethrown to the immediately enclosing scope. If the fault occurs in (or is rethrown to) the global process scope, and there is no matching fault handler for the fault at the global level, the process terminates abnormally. This is as though a terminate activity (described in Section 12.13.1, "Stopping a Business Process Instance with the Terminate Activity in BPEL 1.1") had been performed.

12.11 Re-executing Activities in a Scope Activity with the Replay Activity

You can create a replay activity inside a scope activity to re-execute all of the activities inside the scope.

12.11.1 How to Create a Replay Activity

To create a replay activity:

  1. In the Component Palette, expand Oracle Extensions.

  2. Drag a Replay activity into the designer.

  3. Double-click the Replay activity.

  4. Enter an optional name.

  5. Select the scope to re-execute, as shown in Figure 12-13.

    Figure 12-13 Replay Dialog

    Description of Figure 12-13 follows
    Description of "Figure 12-13 Replay Dialog"

  6. Click Apply, then click OK.

  7. Continue with the design of your scope activity.

    When complete, design of the scope activity can look similar to that shown in Figure 12-14.

    Figure 12-14 Replay Activity in a Scope Activity

    Description of Figure 12-14 follows
    Description of "Figure 12-14 Replay Activity in a Scope Activity"

12.11.2 What Happens When You Create a Replay Activity

Example 12-28 shows the .bpel file after design is complete for a replay activity in a BPEL project that supports BPEL version 2.0. In BPEL 2.0, the replay activity is wrapped in an extensionActivity element.

Example 12-28 Replay Activity

<scope name="scope2">
     <sequence>
       <assign>
         <copy>
           <from>$counter2 + 1</from>
           <to>$counter2</to>
         </copy>
       </assign>
       <scope name="scope3">
         <sequence>
           <assign>
             <copy>
               <from>$counter + 1</from>
               <to>$counter</to>
             </copy>
           </assign>
           <if>
             <condition>$counter = 3</condition>
             <empty/>
             <else>
               <extensionActivity>
                 <bpelx:replay name="ReplayScope" scope="Scope_RetrieveOrder"/>
               </extensionActivity>
             </else>
           </if>
         </sequence>
       </scope> 
     </sequence>
   </scope>

In BPEL 1.1, the replay activity is coded as a bpelx extension.

<bpelx:replay name="ReplayScope" scope="Scope2"/>

12.12 Using Compensation After Undoing a Series of Operations

Compensation occurs when the BPEL process service component cannot complete a series of operations after some have completed, and the BPEL process service component must backtrack and undo the previously completed transactions. For example, if a BPEL process service component is designed to book a rental car, a hotel, and a flight, it may book the car and the hotel and then be unable to book a flight for the right day. In this case, the BPEL flow performs compensation by going back and unbooking the car and the hotel.

In a scope activity, the compensation handler can reverse previously completed process steps. The compensation handler can be invoked after successful completion of its associated scope with either of the following activities.

12.12.1 Using a Compensate Activity

You can invoke a compensation handler by using the compensate activity, which names the scope for which the compensation is to be performed (that is, the scope whose compensation handler is to be invoked). A compensation handler for a scope is available for invocation only when the scope completes normally. Invoking a compensation handler that has not been installed is equivalent to using the empty activity (it is a no-op). This ensures that fault handlers do not have to rely on state to determine which nested scopes have completed successfully. The semantics of a process in which an installed compensation handler is invoked multiple times are undefined.

The ability to explicitly invoke the compensate activity is the underpinning of the application-controlled error-handling framework of Business Process Execution Language for Web Services Specification. You can use this activity only in the following parts of a business process:

  • In a fault handler of the scope that immediately encloses the scope for which compensation is to be performed.

  • In the compensation handler of the scope that immediately encloses the scope for which compensation is to be performed.

For example:

<compensate scope="RecordPayment"/>

If a scope being compensated by name was nested in a loop, the BPEL process service component invokes the instances of the compensation handlers in the successive iterations in reverse order.

If the compensation handler for a scope is absent, the default compensation handler invokes the compensation handlers for the immediately enclosed scopes in the reverse order of the completion of those scopes.

The compensate form, in which the scope name is omitted in a compensate activity, explicitly invokes this default behavior. This is useful when an enclosing fault or compensation handler must perform additional work, such as updating variables or sending external notifications, in addition to performing default compensation for inner scopes. The compensate activity in a fault or compensation handler attached to the outer scope invokes the default order of compensation handlers for completed scopes directly nested within the outer scope. You can mix this activity with any other user-specified behavior except for the explicit invocation of the nested scope within the outer scope. Explicitly invoking compensation for such a scope nested within the outer scope disables the availability of default-order compensation.

12.12.2 How to Create a Compensate Activity

To create a compensate activity:

  1. In the Component Palette, expand BPEL Constructs.

  2. Drag a Compensate activity into the designer

  3. Double-click the Compensate activity.

  4. Select a scope activity in which to invoke the compensation handler, as shown in Figure 12-15.

    Figure 12-15 Compensate Activity

    Description of Figure 12-15 follows
    Description of "Figure 12-15 Compensate Activity"

  5. Click Apply, then OK.

12.12.3 What Happens When You Create a compensate Activity

If an invoke activity has a compensation handler defined inline, then the name of the activity is the name of the scope to be used in the compensate activity. The syntax is shown in Example 12-29:

Example 12-29 Compensation Handler

<compensate scope="ncname"? standard-attributes>
    standard-elements
  </compensate>

12.12.4 Using a compensateScope Activity in BPEL 2.0

The compensateScope activity is used to start compensation on a specified inner scope that has already completed successfully. This activity must only be used from within a fault handler, another compensation handler, or a termination handler.

When you create a compensateScope activity, you select a target that must refer to the immediately-enclosed scope. The scope must include a fault handler or compensation handler.

12.12.5 How to Create a compensateScope Activity

Note:

This activity is supported in BPEL 2.0 projects.

To create a compensateScope activity:

  1. In the Component Palette, expand BPEL Constructs.

  2. Drag a CompensateScope activity into the designer

  3. Double-click the CompensateScope activity.

  4. Select a specific scope activity in which to invoke the compensation handler. Figure 12-16 provides details.

    Figure 12-16 CompensateScope Activity

    Description of Figure 12-16 follows
    Description of "Figure 12-16 CompensateScope Activity"

  5. Click Apply, then OK.

12.12.6 What Happens When You Create a compensateScope Activity

Example 12-30 shows the .bpel file after design is complete for a compensateScope activity. The compensateScope activity is defined in a catchall fault handler. The scope in which to invoke the compensation handler is defined.

Example 12-30 compensateScope Activity

<scope name="ScopeAssignCreditRating">
   <faultHandlers>
      <catchAll>
         <compensateScope target="ScopeAssignScreditRating2" />
      </catchAll>
   </faultHandlers>
   <sequence>
      <scope name="ScopeAssignScreditRating2">
         <compensationHandler>
            <!-- undo work -->
         </compensationHandler>
         <!-- do some work -->
      </scope>
      <!-- do more work -->
      <!-- a fault is thrown here; results of ScopeAssignScreditRating2 must be undone -->
   </sequence>
</scope>

12.13 Stopping a Business Process Instance

You can stop a business process instance with either of the following activities:

12.13.1 Stopping a Business Process Instance with the Terminate Activity in BPEL 1.1

The terminate activity immediately terminates the behavior of a business process instance within which the terminate activity is performed. All currently running activities must be terminated as soon as possible without any fault handling or compensation behavior. The terminate activity does not send any notifications of the status of a BPEL process service component. If you are going to use the terminate activity, first program notifications to the interested parties.

12.13.1.1 How to Create a Terminate Activity

To create a terminate activity:

  1. In the Component Palette in Oracle JDeveloper, expand BPEL Constructs.

  2. Drag a Terminate activity into the designer. Figure 12-17 provides an example.

    Figure 12-17 Terminate Activity

    Description of Figure 12-17 follows
    Description of "Figure 12-17 Terminate Activity"

  3. Double-click the terminate activity.

  4. Optionally enter a name.

  5. Click OK.

12.13.1.2 What Happens When You Create a Terminate Activity

The syntax for the terminate activity is shown in Example 12-31. This stops the business process instance.

Example 12-31 Terminate Activity

<terminate standard-attributes>
    standard-elements
</terminate>

12.13.2 Immediately Ending a Business Process Instance with the Exit Activity in BPEL 2.0

You can use the exit activity to immediately end all currently running activities on all parallel branches without involving any termination handling, fault handling, or compensation handling mechanisms. This activity is useful for environments in which there may not be a reasonable way for dealing with unexpected, severe failures.

Note:

Any open conversations are also impacted by the exit activity. For example, other partners interacting with the process may wait for a response that never arrives.

12.13.2.1 How to Create an Exit Activity

To create an exit activity:

  1. In the Component Palette, expand BPEL Constructs.

  2. Drag an Exit activity into the section of your BPEL process in which you want to execute the exit activity.

  3. Double-click the Exit activity, as shown in Figure 12-18.

    Figure 12-18 Exit Activity

    Description of Figure 12-18 follows
    Description of "Figure 12-18 Exit Activity"

  4. Optionally enter a name.

  5. Click Apply, then OK.

    When complete, the exit activity in a BPEL process appears similar to that shown in Figure 12-19.

    Figure 12-19 Exit Activity in a BPEL Process

    Description of Figure 12-19 follows
    Description of "Figure 12-19 Exit Activity in a BPEL Process"

12.13.2.2 What Happens When You Create an Exit Activity

Example 12-32 shows the .bpel file after design is complete for an exit activity.

Example 12-32 Exit Activity

<sequence>
    <!-- receive input from requester -->
    <receive name="receiveInput" partnerLink="client" portType="tns:Test"
        operation="process" variable="input" createInstance="yes"/>
    <assign>
      <copy>
        <from>$input.payload</from>
        <to>$output.payload</to>
      </copy>
    </assign>
    <!-- respond output to requester -->
    <reply name="replyOutput" partnerLink="client"
       portType="tns:Test" operation="process" variable="output"/>
    <exit/>
  </sequence>

12.14 Throwing Faults with Assertion Conditions

You can specify an assertion condition in BPEL versions 1.1 and 2.0 that is executed upon receipt of a callback message in request-response invoke activities, receive activities, reply activities, and onMessage branches of pick and scope activities. The assertion specifies an XPath expression that, when evaluated to false, causes a BPEL fault to be thrown from the activity. This condition provides an alternative to creating a potentially large number of switch, assign, and throw activities after a partner callback.

You can select when to execute a condition:

The assertion condition is specified as a nested extension element. Example 12-33 shows the postassertion condition schema definition in BPEL 1.1.

Example 12-33 Postassertion Condition Schema Definition in BPEL 1.1

<invoke | receive | onMessage>
    standard-elements
    <bpelx:postAssert name="ncname" expression="boolean-expr" faultName="QName"+
 message="generic-expr"+/>
</invoke | receive | onMessage>

Example 12-34 shows the postassertion condition syntax in BPEL 1.1.

Example 12-34 Postassertion Condition Syntax in BPEL 1.1

<bpelx:postAssert name="Assert_1"
   message='Post Invoke Multiple assert value fired'
   faultName="ns2:NegativeValue"
   expression="bpws:getVariableData('invar','payload','/ns1:process/ns1:input') >
0"/>

Example 12-35 shows the postassertion condition schema definition in BPEL 2.0. Note the differences between BPEL 1.1 and BPEL 2.0.

Example 12-35 Postassertion Condition Schema Definition in BPEL 2.0

<invoke | receive | onMessage>
    standard-elements
    <bpelx:postAsserts> 
       <bpelx:postAssert faultName="QName">
         <bpelx:expression expressionLanguage="anyURI"?>expression
         </bpelx:expression>
         <bpelx:message expressionLanguage="anyURI"?>expression</bpelx:message>
       </bpelx:postAssert>
   </bpelx:postAsserts>
</invoke | receive | onMessage>

Example 12-36 shows the postassertion condition syntax in BPEL 2.0.

Example 12-36 Postassertion Condition Syntax in BPEL 2.0

<bpelx:postAsserts>
   <bpelx:postAssert faultName="ns2:InvalidInput">
     <bpelx:expression>number(concat($inputVariable.payload/client:input,'2')) <  
      500</bpelx:expression>
      <bpelx:message>"AssertXpathPostInvoke_20 assert fired"</bpelx:message>
   </bpelx:postAssert>
</bpelx:postAsserts>

Example 12-37 shows the preassertion condition schema definition in BPEL 1.1.

Example 12-37 Preassertion Condition Schema Definition in BPEL 1.1

<invoke | reply>
    standard-elements
    <bpelx:preAssert name="NCName" expression="string" message="string"
    faultName="QName"/>
</invoke | reply>

Example 12-38 shows the preassertion condition syntax in BPEL 1.1.

Example 12-38 Preassertion Condition Syntax in BPEL 1.1

<bpelx:preAssert name="Assert_1"
   expression="bpws:getVariableData('invar','payload','/ns1:process/ns1:input') > 
   0"
   message='pre invoke assert NegativeInput fired'
   faultName="ns4:NegativeInput"/>

Example 12-39 shows the preassertion condition schema definition in BPEL 2.0. Note the differences between BPEL 1.1 and BPEL 2.0.

Example 12-39 Preassertion Condition Schema Definition in BPEL 2.0

<invoke | reply>
   standard-elements
   <bpelx:preAsserts>
     <bpelx:preAssert faultName="QName">
      <bpelx:expression expressionLanguage="anyURI"?>expression</bpelx:expression>
      <bpelx:message expressionLanguage="anyURI"?>expression</bpelx:message>
     </bpelx:preAssert>
   </bpelx:preAsserts>
</invoke | reply>

Example 12-40 shows the preassertion condition syntax in BPEL 2.0.

Example 12-40 Preassertion Condition Syntax in BPEL 2.0

<bpelx:preAsserts>
    <bpelx:preAssert faultName="ns1:InvalidInput">
       <bpelx:expression>concat($inputVariable.payload/client:input,'2') >
       $inputVariable.payload/client:input</bpelx:expression>
       <bpelx:message>"AssertXpathPreInvoke_20 Assert test"</bpelx:message>
    </bpelx:preAssert>
</bpelx:preAsserts>

The bpelx:postAssert extension specifies the XPath expression to evaluate upon receipt of a callback message from a partner. If the assertion expression returns a false boolean value, the specified fault is thrown from the activity. If the assertion expression returns a true boolean value, no fault is thrown and the activities following the invoke activity, receive activity, or the onMessage branch of pick and scope activities are executed as in a normal BPEL process flow.

The bpelx:preAssert or bpelx:postAssert extension is similar to the Java assert statement. In Java, if the assert expression does not evaluate to true, an error is reported by the JVM. Similarly, the expression in the bpelx:preAssert or bpelx:postAssert extension must evaluate to true; otherwise, the specified fault is thrown.

For example, with the BPEL 1.1 invoke activity shown in Example 12-41, if the XPath expression specified in the assertion condition returns false, the NegativeCredit fault is thrown.

Example 12-41 Invoke Activity in BPEL 1.1

<scope>
    <faultHandlers>
        <catch faultName="services:NegativeCredit" faultVariable="crError">
            <empty/>
        </catch>
    </faultHandlers>
    <sequence>
        <invoke name="invokeCR" partnerLink="creditRatingService"
                portType="services:CreditRatingService" operation="process"
                inputVariable="crInput" outputVariable="crOutput">
            <bpelx:postAssert name="negativeCredit"
 expression="$crOutput.payload/tns:rating > 0"
                          faultName="services:NegativeCredit" message="'Negative
 Credit'" />
        </invoke>
    </sequence>
</scope>

The optional name attribute for bpelx:preAssert or bpelx:postAssert is used while creating the audit trail event message. The name in this instance enables you to identify the assertion element in case multiple assertions are specified. If no name attribute is specified, the line number of the assertion element in the BPEL file may be used.

12.14.1 Introducing Assertion Conditions

This section describes key assertion condition concepts.

12.14.1.1 bpelx:postAssert and bpelx:preAssert Extensions

Depending upon the activity, you can specify when to execute a condition by clicking the Add icon in the Assertions tab of invoke, receive, reply, and onMessage branches of pick and scope activities, and selecting either Pre Assert or Post Assert. Based on your selection, the following bpelx extensions are used:

  • bpelx:preAssert: If you select Pre Assert, the condition is executed before the invoke or reply activity send out the outbound message.

  • bpelx:postAssert: If you select Post Assert, the condition is executed after an invoke activity, receive activity, or onMessage branch receives the inbound message.

Example 12-42 shows multiple bpelx:postAssert extensions in a receive activity in BPEL 1.1:

Example 12-42 bpelx:postAssert Extension in a Receive Activity in BPEL 1.1

<receive name="Receive_1" createInstance="no"
            variable="Receive_1_processResponse_InputVariable"
            partnerLink="AsyncBPELService"
            portType="ns1:AsyncBPELServiceCallback"
            bpelx:for="'PT10S'"
            operation="processResponse">
         <bpelx:postAssert name="assert1" expression="true()" message="'assert
 true failed'" faultName="client:fault1"/>
         <bpelx:postAssert name="assert2" expression="false()" message="'assert
 false failed'" faultName="client:fault2"/>
       </receive> 

Example 12-43 shows multiple bpelx:preAssert extensions in an invoke activity in BPEL 1.1:

Example 12-43 bpelx:preAssert Extension in a Invoke Activity in BPEL 1.1

<invoke name="Invoke_1" inputVariable="Invoke_1_process_InputVariable"
           outputVariable="Receive_1_processResponse_InputVariable"
           partnerLink="SyncBPELService" portType="ns1:SyncBPELService"
           operation="process">
         <bpelx:preAssert name="assert1" expression="true()" message="'assert true
 failed'"/>
         <bpelx:preAssert name="assert2"
 expression="bpws:getVariableData('counter') = 3" message="concat('The value of
 counter is ', $counter)"/> 

For information on using the Assertions tab, see Section 12.14.2, "How to Create Assertion Conditions."

12.14.1.2 Use of faultName and message Attributes

You can specify the faultName and message attributes of the bpelx:postAssert element, as shown in the schema definition in Example 12-44 for BPEL 1.1

Example 12-44 faultName and message Attributes Schema Definition in BPEL 1.1

<invoke | receive | onMessage>
    standard-elements
    <bpelx:postAssert name="ncname"? expression="boolean-expr" faultName="QName"+
 message="generic-expr"+/> *
</invoke | receive | onMessage>

Example 12-45 shows the syntax for the faultname and message attributes.

Example 12-45 faultName and message Attributes Syntax in BPEL 1.1

<bpelx:postAssert name="Assert_2"
   message='multiple post assert Greater value fired'
   faultName="ns2:GreaterValue"
  expression="bpws:getVariableData('invar','payload','/ns1:process/ns1:input') <
 500"/>

If you do not specify the faultName attribute, the fault defaults to bpelx:postAssertFailure. If the message attribute is not specified, the message value defaults to the name of the activity.

<bpelx:postAssert expression="boolean-expr" />

The specified fault is thrown whenever the assertion condition evaluates to false. Analysis is performed on the faultName QName to ensure that it properly resolves to a fault that has been defined in the partner WSDL portType. The message expression is a general expression that can evaluate to any XPath value type (string, number, or boolean). If a nonstring value is returned, the string equivalent of the value is used.

12.14.1.3 Multiple Assertions

You can nest multiple assertions in receive activities, invoke activities, and the onMessage branch of pick and scope activities, with evaluation of the assertions continuing in the order in which they were declared until an expression evaluates to false. Example 12-46 provides details.

Example 12-46 Nesting Multiple Assertions in BPEL 1.1

<invoke name="invokeCR" partnerLink="creditRatingService"
        portType="services:CreditRatingService" operation="process"
        inputVariable="crInput" outputVariable="crOutput">
    <bpelx:postAssert name="negativeCredit" expression="$crOutput.payload/tns:rating >
 0"
                  faultName="services:NegativeCredit" message="'Negative Credit'"
 />
    <bpelx:postAssert name="insufficientCredit"
 expression="$crOutput.payload/tns:rating > 600"
                  faultName="services:InsufficientCredit" message="'Insufficient
 Credit'" />
</invoke>

In Example 12-46, the assertion with the expression that checks that the response credit rating is greater than zero is evaluated first. Table 12-4 describes the assertion behavior.

Table 12-4 Assertion Behavior

If The Credit Rating For The Returned Response Is... Then...

Less than zero

The services:NegativeCredit fault is thrown.

Greater than or equal to zero

The assertion is correct and the second assertion is evaluated.

Less than 600

The services:InsufficientCredit fault is thrown.

Greater than or equal to 600

The assertion is correct and no fault is thrown from the invoke activity.


Any number of assertions can be nested. For no fault to be thrown from the activity, all assertions specified must evaluate to true.

This construct enables you to apply multiple levels of validation on an incoming payload, similar to if...else if...else statements in Java.

To enable a fault to always be thrown regardless of validation logic, the assertion expression can be specified as false(). This is similar to the else construct in Java.

12.14.1.4 Use of Built-in and Custom XPath Functions and $variable References

You can also use built-in and custom XPath functions and $variable references within the assertion condition. Example 12-47 provides several examples.

Example 12-47 Built-in and Custom XPath Functions in BPEL 1.1

<bpelx:postAssert expression="bpws:getVariableData( 'crOutput', 'payload',
 '/tns:rating' ) > 0" ... />

<bpelx:postAssert expression="custom:validateRating()" ... />

<bpelx:postAssert xmlns:fn='http://www.w3.org/2005/xpath-functions'
 expression="fn:false()" ... />

If an error is thrown by the XPath expression evaluation, the error is wrapped with a BPEL fault and thrown from the activity.

Faults that are thrown from a request-response invoke activity, receive activity, or onMessage branch of a pick or scope activity because of a failed assertion evaluation can be caught and handled by BPEL's fault management framework. For information, see Section 12.4, "Using the Fault Management Framework."

Faults that are not caught and handled within a BPEL process flow are thrown from a BPEL component if the component WSDL declares the fault on the operation. If the fault is not declared on the operation, the fault is converted into a FabricInvocationException, which is a runtime fault. This fault can be caught by any caller components (including BPEL components), but the fault type is no longer the one originally thrown (however, the fault message string still retains traces of the original fault message).

For more information about runtime faults, see Section 12.3, "Introduction to Categories of BPEL Faults."

For more information about fault policies, see Section 12.4, "Using the Fault Management Framework."

12.14.1.5 Assertion Condition Evaluation Logging of Events to the Instance Audit Trail

Each assertion condition that is evaluated causes an event to be logged to the instance audit trail. The event indicates whether the assertion passed or failed (for failure, the fault name and message are printed). The event also includes the name attribute specified in the assertion element; if no name attribute is provided, the line number of the assertion element in the BPEL process flow is used. The assertion condition printed in the audit event helps identify the assertion and better enables debugging of the flow.

12.14.1.6 Expressions Not Evaluating to an XML Schema Boolean Type Throw a Fault

If the assertion condition XPath expression does not evaluate to an XML schema boolean type, a bpelx:postAssertFailure fault is thrown from the activity. An event in the instance audit trail is also logged indicating the error. Example 12-48 provides details.

Example 12-48 Throwing a bpelx:assertFailure Fault in BPEL 1.1

<bpelx:postAssert expression="bpws:getVariableData( 'crOutput', 'payload',
 '/tns:rating' ) > 0" ... />

<bpelx:postAssert expression="custom:validateRating()" ... />

<bpelx:postAssert xmlns:fn='http://www.w3.org/2005/xpath-functions'
 expression="fn:false()" ... />

Analysis of the assertion expression is performed by the BPEL compiler and errors are reported if an expression does not evaluate to an XML schema boolean type. For custom XPath functions, this type of analysis is not performed.

12.14.1.7 Assertion Conditions in a Standalone Assert Activity

You can also create assertion conditions in a standalone assert activity in a BPEL process service component. The assertion specifies an XPath expression that, when evaluated to false, causes a BPEL fault to be thrown from the activity.

The bpelx:assert extension implements assertions in the standalone assert activity:

<bpelx:assert name="Assert1" expression="string" message="string"/>

For information on using the standalone assert activity, see Section 12.14.2, "How to Create Assertion Conditions."

12.14.2 How to Create Assertion Conditions

You can create assertion conditions in the following activities:

  • In message exchange activities such as invoke activities, receive activities, reply activities, and OnMessage branches

  • In standalone assert activities for specifying XPath expressions

To create assertion conditions in invoke activities, receive activities, reply activities, and OnMessage branches:

  1. In the SOA Composite Editor, double-click the BPEL process service component.

  2. In the Component Palette, expand BPEL Constructs.

  3. Drag a Receive activity, Invoke activity, Pick activity, or Scope activity into the designer.

  4. Expand the Receive, Invoke, or onMessage branch of the Pick or Scope activity.

  5. Click the Assertions tab.

  6. If you are creating an assertion for a BPEL 1.1 project, perform the following tasks. Otherwise, go to Step 7.

    1. Click the Add icon, as shown in Figure 12-20.

      Figure 12-20 Add Icon of Assertions Tab in BPEL 1.1

      Description of Figure 12-20 follows
      Description of "Figure 12-20 Add Icon of Assertions Tab in BPEL 1.1"

    2. Select when to execute the condition. Table 12-5 provides details.

      Table 12-5 Condition Execution Options

      Element Description

      Pre Assert

      If selected, the condition is executed before the invoke or reply activity send out the outbound message.

      Post Assert

      If selected, the condition is executed after an invoke activity, receive activity, or onMessage branch receives the inbound message.


      Based on your selection, the Pre Assert or Post Assert dialog is displayed.

  7. If you are creating an assertion for a BPEL 2.0 project, perform the following tasks.

    1. Select when to execute the condition. Table 12-6 provides details.

      Table 12-6 Assertion Condition Tabs

      To Create A... Select The...

      Preassertion condition

      Pre Asserts tab

      Postassertion condition

      Post Asserts tab.


    2. Click the Add icon, as shown in Figure 12-21.

      Figure 12-21 Add Icon of Assertions Tab in BPEL 2.0

      Description of Figure 12-21 follows
      Description of "Figure 12-21 Add Icon of Assertions Tab in BPEL 2.0"

    The Assert dialog is displayed.

  8. Specify values for the assertion condition, as shown in Figure 12-22. For this example, Post Assert was selected for an assertion condition on a receive activity in a BPEL 1.1 project.

    1. Select the Fault QName to be thrown by clicking the Search icon and selecting an existing fault from the Fault Chooser dialog. You can also provide your own values for the Namespace URI and Local Part fields of the fault. If you do not specify anything for the Fault QName, then a bpelx:assertFailure fault is thrown.

    Figure 12-22 Assertion Condition Values

    Description of Figure 12-22 follows
    Description of "Figure 12-22 Assertion Condition Values"

  9. When complete, click OK to return to the Assertions tab of the activity. The completed assertion condition is displayed, as shown in Figure 12-23.

    Figure 12-23 Assertions Tab with Data

    Description of Figure 12-23 follows
    Description of "Figure 12-23 Assertions Tab with Data"

  10. Click Apply, then OK.

To create an assertion condition in standalone assert activities:

  1. In the SOA Composite Editor, double-click the BPEL process service component.

  2. In the Component Palette, expand Oracle Extensions.

  3. Drag an Assert activity into the designer, as shown in Figure 12-24.

    Figure 12-24 Assert Activity in Component Palette

    Description of Figure 12-24 follows
    Description of "Figure 12-24 Assert Activity in Component Palette"

  4. Expand the Assert activity.

  5. To the right of the Expression field, click the XPath Expression Builder icon.

  6. Create an expression.

  7. When complete, click OK.

    The Assert dialog looks as shown in Figure 12-25.

    Figure 12-25 Assert Dialog

    Description of Figure 12-25 follows
    Description of "Figure 12-25 Assert Dialog"

  8. Click Apply, then OK.

12.14.3 How to Disable Assertions

You can disable assertions in either of two ways:

  • By setting the System MBean Browser property DisableAsserts to true in Oracle Enterprise Manager Fusion Middleware Control.

  • By setting bpel.config.disableAsserts to true in the composite.xml file of the SOA composite application, as shown in Example 12-49.

    Example 12-49 Disable Assertions

    <component name="AsyncBPELClient">
        <implementation.bpel src="AsyncBPELClient.bpel"/>
        <property name="bpel.config.disableAsserts">true</property>
      </component>
    

For more information about setting System MBean Browser properties, see Oracle Fusion Middleware Administrator's Guide for Oracle SOA Suite and Oracle Business Process Management Suite.

12.14.4 What Happens When You Create Assertion Conditions

The code segment in the .bpel file defines the specific operation after design completion.

For Example 12-50, the bpelx:assert condition in the invoke activity, when evaluated to false (for example, a credit rating of 0 is submitted), returns a Negative Credit message. If the condition evaluates to true, no fault is thrown from the invoke activity and the remaining activities in the BPEL process flow are executed normally.

Example 12-50 Assertion Condition in an Invoke Activity in BPEL 1.1

<invoke name="callbackClient" partnerLink="internalwarehouseservice_client"
 portType="client:InternalWarehouseServiceCallback" operation="processResponse"
 inputVariable="outputVariable">
           <bpelx:assert name="negativeCredit"
                         expression="$crOutput.payload/tns:rating > 0"
                         message="Negative Credit"/>
</invoke>

In Example 12-51, the bpelx:assert condition in the standalone assert activity, when evaluated to false, returns a got assertion failure on true expression message. If the condition evaluates to true, no fault is thrown from the assert activity and the remaining activities in the BPEL process flow are executed normally.

Example 12-51 Assertion Condition in a Standalone Assert Activity in BPEL 1.1

<bpelx:assert expression="true()bpws:getLinkStatus()" message="'got assertion
failure on true expression'"