BPEL and Java Cookbook

By Jurij Laznik
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Calling BPEL from Java

About this book

The Business Process Execution Language (BPEL) has become the de-facto standard for orchestrating web services. BPEL and web services are both clamped into Service-oriented Architecture (SOA). Development of efficient SOA composites too often requires usage of other technologies or languages, like Java. This Cookbook explains through the use of examples how to efficiently integrate BPEL with custom Java functionality.
If you need to use BPEL programming to develop web services in SOA development, this book is for you.

BPEL and Java Cookbook will show you how to efficiently integrate custom Java functionality into BPEL processes. Based on practical examples, this book shows you the solutions to a number of issues developers come across when designing SOA composite applications. The integration between the two technologies is shown two-fold; the book focuses on the ways that Java utilizes the BPEL and vice-versa.

With this book, you will take a journey through a number of recipes that solve particular problems with developing SOA composite applications. Each chapter works on a different set of recipes in a specific area. The recipes cover the whole lifecycle of developing SOA composites: from specification, through design, testing and deployment.


BPEL and Java Cookbook starts off with recipes that cover initiation of BPEL from Java and vice-versa. It then moves on to logging and tracing facilities, validation and transformation of BPEL servers, embedding of third-party Java libraries into BPEL. It also covers manipulation with variables in BPEL different techniques of Java code wrapping for web service usage and utilization of XML façades.


After reading BPEL and Java Cookbook you will be able to circumvent many of the issues that developers experience during SOA composite application development.

 

Publication date:
September 2013
Publisher
Packt
Pages
382
ISBN
9781849689205

 

Chapter 1. Calling BPEL from Java

In this chapter we will cover:

  • Deploying a BPEL process

  • Gathering a BPEL process's in and out parameters

  • Calling a synchronous BPEL process from Java

  • Calling an asynchronous BPEL process from Java

  • Handling business faults from a synchronous BPEL process

  • Handling business faults from an asynchronous BPEL process

  • Mapping the results of a BPEL process

 

Introduction


Business processes are an integral part of every company. As new requirements arise in the business processes, companies pursue its alignment with IT as well. Pursuing the need for IT to efficiently support business processes in companies, the SOA (Service Oriented Architecture) was identified as the most important IT technology for business process implementation. Depending on the business environment, BPEL can also be considered as a suitable technology in EDA (Event Driven Architecture), since it provides constructs to handle events through event handlers (onMessage and onAlarm). Within SOA, the most common practice to implement business processes is by using a WSBPEL (Web Services Business Process Execution Language), or BPEL for short. Of course, SOA itself does not make it compulsory to use BPEL for business process implementation, and you can also use other workflow languages, such as BPMN, YAWL, and jBPM(JPDL) just to name some. BPEL is an XML-based language for the definition and execution of business processes, and has become the de-facto standard for orchestrating web service compositions. The first official version of BPEL specification was named BPEL4WS 1.1, or BPEL 1.1 for short, in 2003. Later on, a new version, WS-BPEL 2.0, with significant enhancements, was released in 2007.

A BPEL process definition has three main parts:

  • A BPEL file in XML form: This contains the definition of a process (main activities, variables, events, partner links, fault handlers, compensation handlers, and so on).

  • The WSDL files: These files present web service interfaces, utilized by the BPEL process for orchestration purposes. Similar to BPEL, WSDL also released several versions of specification, which are widely used today. In 2001, WSDL 1.1 (Web Service Definition Language) was released, followed by WSDL 2.0 (Web Service Description Language) in 2007.

  • The XSD schema files: These files present XML definitions of the BPEL request, response, and fault messages, as well as the BPEL variable definitions.

The three mentioned parts present the source code of the business process definition. The source code is deployed on a BPEL engine, which is responsible for managing, running, and monitoring the execution of business processes.

We can find many BPEL execution engines on the market. They are either open source or proprietary. We will name just a few of them here which are most commonly used by companies and communities:

Vendor

Product

License Type

BPEL specification supported

Oracle

Oracle SOA Suite

Proprietary

1.1 and 2.0

jBoss

jBPM

Open source

1.1 and partly 2.0

Apache

Apache ODE

Open source

1.1 and 2.0

Active Endpoint

ActiveVOS

Proprietary

1.1 and 2.0

IBM

WebSphere Process Server

Proprietary

1.1

All these BPEL engines have the support of a BPEL specification, either Version 1.1 or 2.0. However, vendors do extend the functionality of the BPEL specification with their own extensions, making migration of business processes between various BPEL platforms more difficult. For example, IBM WebSphere Process Servers provides the possibility to declare inline human tasks, while Oracle SOA Suite provides Java Embedding activity and extension functions to monitor process and perform various XPATH operations.

It is evident that BPM applications are emerging, as business environments are becoming ever more dynamic and the need for agile IT is increasing. BPEL, as an orchestration technology, is able to compose business processes from various services. We can monitor business processes in real time with BAM (business activity monitoring) solutions, and extend their flexibility with the use of BRMS (business rules management system).

To successfully integrate a BPEL process with other types of applications, we need to know the description of the provided BPEL process operations, the type of the BPEL process (synchronous or asynchronous), and how to handle various faults thrown from the BPEL process.

In this chapter, we will deal with the deployment of a BPEL process. We will then investigate how applications written in Java efficiently utilize the BPEL processes.

 

Deploying a BPEL process


This recipe describes how a BPEL process can be deployed in Oracle SOA Suite. We will show the deployment of the BPEL process from a GUI tool as well as from the command line.

Getting ready

We have to set up a BPEL engine and a proper development environment. For the BPEL engine, we use the BPEL Process Manager from Oracle SOA Suite 11g. We also use JDeveloper as the development environment.

Tip

The installation notes and packages can easily be accessed from the Oracle web page at http://www.oracle.com/technetwork/middleware/soasuite/downloads/index.html. An Oracle web account is required in order to access downloads.

We will start with the HelloWorld example from the Oracle SOA Suite examples and will add additional functionality in the later recipes. For this recipe, we will unzip the HelloWorld example to our hard drive.

Note

For this recipe, we use the example from the https://java.net/projects/oraclesoasuite11g/pages/BPEL address.

How to do it…

In the following steps, we will cover the actions we need to perform in order to deploy a BPEL process to the Oracle SOA Suite server:

  1. To deploy the BPEL process, we first open JDeveloper and select Default Role. Depending on the role we choose, JDeveloper enables technologies available inside IDE. We choose the default role, which has the BPEL support enabled. We click on Open Application…, select the folder with the HelloWorld sample, and point to the bpel-101-HelloWorld.jws file. The project structure in JDeveloper is as shown in the following screenshot:

  2. We see the HelloWorldProcess.xsd file, which contains the XML data type and the XML element structures for the input and output messages that are utilized by the BPEL process. At the top level of the project, we see the HelloWorldProcess.bpel file, which contains the BPEL process definition, and HelloWorldProcess.wsdl that contains the definition of the BPEL process partner links.

  3. To deploy the BPEL process, we right-click on the top-level project in the Application Navigator, click on Deploy, and select the BPEL process. We select Deploy to Application Server and click on Next.

  4. For the deployment configuration, we don't change anything; just click on Next. At this point, we have to select the application server on which we want to deploy the BPEL process. We click on the plus (+) sign and enter the name of the connection in the Connection Name field. Then, we click on Next and enter the username and password for the application server.

    Note

    When we follow the default installation notes from Oracle, the default username is weblogic and password is welcome1.

  5. Next, we need to configure the connection parameters to the Oracle Weblogic Domain. The name of the Oracle Weblogic Domain can be obtained from the Oracle Weblogic management console.

    Note

    By default, we can access the Oracle Weblogic management console at the following address: http://<weblogic_server>:7001/console/.

  6. We leave the other parameters unchanged. We then test the connection to the Oracle Weblogic Domain by clicking on the Test Connection button.

  7. Next, we click on Finish. Now, we select the newly defined BPEL server and click on Next. We can see various information such as the name of the SOA server, the partition to which we want to deploy the BPEL process, the status of the SOA server, and the URL of the server.

  8. We then click on Next and Finish. The deployment process starts. When the deployment process finishes, we check if the process was successfully registered with the SOA server. We check this via the Oracle Enterprise Manager Console.

    Also, we check to see if there was no error reported in JDeveloper. If deployment was successful, we will see a message in the JDeveloper deployment log as follows:

    [10:05:55 PM] Successfully deployed archive sca_bpel-101-HelloWorld_rev1.0.jar to partition "default" on server AdminServer [http://medion:7001]

    Note

    By default, we access the Oracle Enterprise Manager Console at the following address:

    http://<weblogic_server>:7001/em/

  9. If our HelloWorld process appears in the Oracle Enterprise Manager Console, we succeeded in deploying the BPEL process; otherwise, we need to examine the error and respond accordingly. In case of an error, we need to first check the JDeveloper messages log, and then the Oracle SOA Suite console log. Theobe a useful source of information about the file.

There's more…

After preparing the package for deployment with JDeveloper, we can deploy the BPEL process with the ant scripts. The scripts comes handy for continuous integration tasks in staging and production environments, where various testing and deployment tasks are performed automatically. A set of ant scripts comes with Oracle SOA Suite in order to compile, build, deploy/undeploy, and test the BPEL processes.

We first open the command prompt and change the directory to the example project home. For the deployment, we execute the ant script as shown in the following screenshot:

The command with which we started the deployment is as follows:

ant -f %Middleware_Home%\%SOA_Suite_Home%\bin\ant-sca-deploy.xml
  -DserverURL=http://localhost:7001
  -DsarLocation=.\deploy\sca_bpel-101-HelloWorld_rev1.0.jar
  -Doverwrite=true
  -DforceDefault=true

Tip

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

The ant script parameters have the following meanings:

  • -f: It is the location of the deployment script

  • -DserverURL: It is the base URL of the Oracle SOA Suite server

  • -DsarLocation: It is the location of the deployment package

  • -Doverwrite: If the BPEL process with the same version is already deployed, we can overwrite it

  • -DforceDefault: The force to deploy the package to the default domain

Before the deployment starts, we have to enter the username and password of the BPEL server. Again, we open the Oracle Enterprise Manager Console in order to check whether the BPEL process was successfully deployed.

 

Gathering a BPEL process's in and out parameters


This recipe will explain the ways of getting input and output parameters about a BPEL process. The information gathered is very important if we want to call the BPEL process from Java applications.

How to do it…

We are deploying the BPEL process on the BPEL server. The business process is now ready to be executed; however, we don't have any information about the business process besides the WSDL location of the business process.

  1. In the Oracle Enterprise Manager Console, we select the BPEL process from the tree, and click on the following icon:

  2. We receive information about the business process endpoint URI and a location of the business process WSDL as shown in the following screenshot:

  3. By entering the WSDL address into the web browser, we receive a description of the BPEL process interface. In this definition, we check for the input and output messages as follows:

    <wsdl: message name = "HelloWorldProcessRequestMessage">
      <wsdl: part name = "payload" element = "client:process"/>
    </wsdl: message>
    <wsdl: message name = "HelloWorldProcessResponseMessage">
      <wsdl: part name = "payload" element = "client: processResponse"/>
    </wsdl: message>
    <wsdl: portType name = "HelloWorldProcess">
      <wsdl: operation name = "process">
      <wsdl: input message = "client: HelloWorldProcessRequestMessage"/>
      <wsdl: output message = "client:HelloWorldProcessResponseMessage"/>
      </wsdl:operation>
    </wsdl:portType>
  4. The most interesting part of WSDL is the <wsdl:operation> element, which indicates the entry point, the functionality, and the input and output messages of the BPEL process. We see that the input and output parameters both have a defined message in the client namespace, which is defined as the XSD schema. We can find its location in WSDL under the <import> tag. We search for the client: process input parameter in the XSD schema:

    <element name="process">
      <complexType>
        <sequence>
          <element name="input" type="string"/>
        </sequence>
      </complexType>
    </element>
  5. As we can see, the input parameter takes the string variable with the name input. Similarly, we explore the output parameter client: processResponse in the XSD schema as follows:

    <element name="processResponse">
      <complexType>
        <sequence>
          <element name="result" type="string"/>
        </sequence>
      </complexType>
    </element>
  6. The BPEL process will return the string variable named result.

How it works…

In general, there are two approaches to designing the BPEL processes. The first one is the top-down approach, where we first develop the XSD schema and WSDL files, which is also called the contract-first approach . The next one is called the bottom-up approach, where we start from the already-written Java code and generate the XSD schema and WSDL files with tools.

The recommended approach when designing the BPEL processes is to first define the XSD schema, which contains the definition of the input and output parameters. This is also the proper place to put the various complex variables used in the business process.

The schema is later used by WSDL to define the BPEL process interface via the <wsdl: portType> element. Both WSDL and the XSD schema are packed into the deployment package and deployed to the BPEL server.

Note

The definition of the input and output parameters in the XSD schema is not mandatory. We can easily define them in WSDL of the BPEL process. However, we lose some of the readability of the WSDL document. Note that such an approach is bad practice and is not recommended, since it hinders the reusability of the XML data types and elements.

See also

  • To learn about the deployment of a BPEL process, refer to the previous recipe, Deploying a BPEL process

 

Calling a synchronous BPEL process from Java


This recipe explains how to call a synchronous BPEL process from Java. When a client calls a synchronous BPEL, it gets blocked until the BPEL process finishes the processing and returns the response. Usually, synchronous BPEL processes are designed for cases where the operation will be completed in a relatively short time. For long-running operations, we instead design asynchronous BPEL processes. This recipe will also cover how to prepare a Java package for integration with Java applications. From the client perspective, a synchronous BPEL process can be invoked in the same way a synchronous web service could. The client is most commonly called proxy , and it is used to ease the connection between the two technologies. In our case, we would like to call the BPEL process, which is mainly the XML content, from Java and proxy is helping us to get across the gap between those two technologies.

How to do it…

In order to call a synchronous BPEL process, we will develop a Java client using the JDeveloper wizard. After completing this recipe, we will be able to call a synchronous BPEL process from the Java client application.

  1. First, we create another project in JDevelper. On the previously created BPEL sample project, we right-click, and select New…. From the Business Tier category, we select Web Services and then we select Web Service Proxy under Items as shown in the following screenshot:

  2. Then, we click on OK, which shows the welcome screen, and then we click on Next. We have to enter the WSDL location of the BPEL process in the next window. We also have the ability to choose whether we want to copy the WSDL file into the project.

    Note

    We can either choose the file location from the hard drive or enter the URL for the WSDL location of the BPEL process.

  3. In the next window, we have to enter the name of the Java packages. We have to enter the package name of the proxy files (that is, Root Package for Generated Types) and Package Name, which is where the files for the XML serialization will be placed, as shown in the following screenshot:

  4. We have inserted all the mandatory fields necessary to create the BPEL process proxy, so we conclude the wizard by clicking on Finish.

  5. In JDeveloper, we see that a number of files were generated in a separate project. The package org.packt.bpel.sync.gen contains the files that are used for transformation between XML and Java.

  6. Let us check the Process.java file. We see that the class contains only one member as follows:

        @XmlElement(required = true)
        protected String input;

    The code is annotated with the @XmlElement annotation, which indicates the usage of JAXB (Java Architecture for XML Binding). The JAXB implementation enables conversion from Java to XML and vice-versa. We need this conversion because data in Java is stored in objects, while BPEL holds data in XML format.

    Note

    This variable presents the input parameter of the BPEL process. The class also contains two helper methods for setting the value and getting the value of the variable. Similarly, we can check the ProcessResponse.java class file which contains the output parameter of the BPEL process.

    The most interesting generated file is HelloWorldProcess_ptClient.java. This file contains skeleton prepared to call the BPEL process.

  7. The code starts with the reference to the BPEL process. Since the BPEL process is exposed as a web service, the code is as follows:

      @WebServiceRef
      private static Helloworldprocess_client_ep helloworldprocess_client_ep;

    We can also note the @WebServiceRef annotation, which is used by JAX-WS (Java API for XML Web Services). The annotation indicates a reference to the web service port, or in our case, the BPEL process port.

  8. We need to instantiate the proxy to the BPEL process and get the reference to the endpoint as follows:

      helloworldprocess_client_ep = new Helloworldprocess_client_ep();
      HelloWorldProcess helloWorldProcess = helloworldprocess_client_ep.getHelloWorldProcess_pt();
  9. We define the input and output variables as the String type as follows:

      String input = "Jurij";
      String output;
  10. Remember that the BPEL process is taking string as an input. As a result, the BPEL process returns a concatenated string starting with Hello, followed by the input string, and concluded with three exclamation marks. Finally, we call the BPEL process and write results to the output as follows:

      output = helloWorldProcess.process(input);
      System.out.println("Business process returned:" + output);
  11. As a result of the BPEL process call, we receive the following output to JDeveloper:

  12. We can see that the BPEL process was executed in the Oracle Enterprise Manager Console as shown in the following screenshot:

  13. We can now see that the BPEL process completed successfully.

How it works…

With the wizard in JDeveloper, we prepare the Java proxy for calling the BPEL process using the wizards in JDeveloper. When the client is executed, it converts the parameters from Java types to XML types via JAX-WS. Then, the call to the BPEL process is performed, and after the BPEL process finishes, the client receives the result in XML. The XML types are then converted back to Java types.

There's more…

We can define different options when creating the BPEL process proxy as follows:

  • By creating asynchronous methods

  • By defining the security policies for the BPEL process

  • By defining the handlers which deal with the web service messages

 

Calling an asynchronous BPEL process from Java


This recipe explains how to call an asynchronous BPEL process from Java-based applications. Asynchronous communication is broadly used for long-running business processes. When a client invokes a long-running business process, it usually cannot wait long periods (days, weeks, and so on) for the response. Instead, the communication is closed, and a response from the business process is captured by listening for the callback. This recipe also uses the Apache AXIS package.

Getting ready

In this recipe, we call an asynchronous BPEL process. We enriched the sample scenario with the use of the Apache AXIS package. This allows us to receive an asynchronous callback from the BPEL process. We integrate the AXIS package into the JDeveloper environment simply by unpacking the AXIS package, and adding its jars into the JDeveloper project classpath.

How to do it…

We implement two classes. In the first class, we program the client that is calling the asynchronous BPEL process. In the second class, we prepare a callback class that is used to handle the response from the asynchronous BPEL process. Note that the asynchronous BPEL process is not sending a response to the client via a reply activity. Instead, the BPEL process is using the callback method, which contacts the client, of course, if one is listening.

  1. Let us examine the ClientProxy.java class first. We start by creating the ServiceClient client and preparing the Options class to configure the ServiceClient client as follows:

      ServiceClient client = new ServiceClient();
      Options opts = new Options();
  2. To configure the ServiceClient client, we set the parameters as follows:

    opts.setTo(new EndpointReference("http://medion:7001/soa-infra/services/default/HelloWordlAsync/helloworldasyncprocess_client_ep"));
    opts.setAction("process");
    opts.setUseSeparateListener(true);

    We instruct AXIS where the BPEL endpoint is, which actions we want to call, and the type of the listener (callback) we want to use. With the setUseSeparateListener call, we instruct AXIS to send a SOAP message over two separate channels, thus enabling the asynchronous communication.

  3. We engage the addressing module of the AXIS package as follows:

    client.engageModule("addressing");

    With this line of code, we actually enable the WS-Addressing module inside the AXIS package. The WS-Addressing module provides transport-neutral mechanisms to address web services and messages. In AXIS, this package is a prerequisite for the asynchronous communication.

  4. Finally, we set the options to the service client and fire a non-blocking request to the asynchronous BPEL process as follows:

    client.setOptions(opts);
    client.sendReceiveNonBlocking(createPayLoad(), new BPELCallback());

    The non-blocking request enables the client to continue its processing without actually waiting for the BPEL process to finish. The createPayLoad() method is a helper method used to create a request message for the BPEL process. The helper method is generating XML content out of the Java class through JAXB. We build the request with the help of the XML document builder.

  5. The code which simulates further processing of the client is as follows:

    System.out.println("send the message");
    while (!isFeedback) {
      Thread.sleep(5000);
      System.out.println("waiting ....");
      }
    System.exit(0);

    The main thread is sleeping for five seconds, and after that period is over, it checks if the response was already received from the BPEL process. In the meantime, the client can process other requests. When the client receives the response from the BPEL process, it exits.

  6. We created a code for handling the BPEL process response in the BPELCallback.java class. We implemented the onMessage and onComplete methods. When the reply arrives from the BPEL process, we print out the complete SOAP message as follows:

    public void onMessage(MessageContext messageContext) {
      SOAPBody msg = messageContext.getEnvelope().getBody();
      System.out.println(msg);
      }
  7. When the transmission is complete, the method onComplete is invoked, and we signal the program from which we received the reply from the asynchronous BPEL process as follows:

    public void onComplete() {
      System.out.println("Transmission finished.");
      ClientProxy.isFeedback = true;
      }
  8. After running the example, we check the client console output. As we can see, the message is sent to the BPEL process and the client program continues its work. When the response is retrieved from the BPEL process, we see that the message is retrieved within the callback handler, and that means the program exits.

    send the message
    waiting ....
    waiting ....
    waiting ....
    waiting ....
    <env:Body xmlns:env = "http://schemas.xmlsoap.org/soap/envelope/"><processResponse xmlns = "http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess">
       <result>Hello </result>
    </processResponse></env:Body>
    Transmission finished.
    waiting ....
    [SimpleHTTPServer] Stop called
    Process exited with exit code 0
  9. We also check the Audit Trail of the BPEL process. We see that the BPEL process received the message, executed the flow of activities, and at the end, contacted the client and sent a response to it as shown in the following screenshot:

How it works…

Asynchronous communication between the BPEL server and client is different than in synchronous communication. In synchronous communication, the BPEL process is invoked, the process flow is executed, and the result is returned to the client. The whole time the BPEL process is executed, the client is blocked. In asynchronous communication, the BPEL process is invoked and the communication is closed. We describe such a call as one-way invocation . When the BPEL process execution is finished, the BPEL engine initiates communication with the client and sends back the response via callback. An asynchronous BPEL process does not block the client. This means that as soon as the client initiates the asynchronous BPEL process, it can continue with other tasks. We can see that the asynchronous BPEL processes are used for long-running transactions where we cannot predict when they will finish. Such transactions can be found using human interaction through human tasks.

In order to enable asynchronous communication between the BPEL process and client, we use the WS-Addressing mechanisms. WS-Addressing provides transport-neutral mechanisms to address web services and messages. In the BPEL engine, the correlation mechanism is used in order to track multiple, long-running executions of the BPEL processes. Correlations help with tracking the route to the corresponding BPEL process instance. The correlation sets present a compound version of correlation, as they are composed of more individual correlations. In our example, the correlation information is hidden behind the scenes as WS-Addressing is automatically set to appropriate properties in communication between the BPEL process and client.

Note

Latest specifications of the WS-Addressing specification can be found at the following URL: http://www.w3.org/TR/ws-addr-core/.

Usually, both the BPEL servers as well as the client implementations already provide the libraries that support the WS-Addressing specification. The information about addresses resides in the SOAP Header class. When we initiate the BPEL process, the following attributes are set by the client:

  • wsa:To: This identifies the asynchronous BPEL process which we want to start.

  • wsa:ReplyTo: This identifies the address of the client to which the asynchronous BPEL process should return the response.

  • wsa:MessageID: This identifies the uniquely defined number of a sent message. With this message ID, we match the sent request with the received response.

  • wsa:Action: This identifies the action which should be executed on the asynchronous BPEL process.

Similarly, when the asynchronous BPEL process has finished its execution, the response is sent to the client. In the response SOAP Header class, the following attributes are set:

  • wsa:To: This identifies the address of the client.

  • wsa:Action: This identifies the response action name.

  • wsa:MessageID: This identifies the uniquely defined number of a sent message. With this message ID, we establish a correlation between the request with the received response.

  • wsa:RelatesTo: This identifies the message ID of the request. MessageID of the request and RelatesTo of the response are used by the applications to match the requests against their respective responses.

  • wsa:ReplyTo: This contains information about where the response should be sent. For the response message from the asynchronous BPEL process, the element is empty.

  • wsa:FaultTo: This contains information about the faults, if they exist.

 

Handling business faults from a synchronous BPEL process


This recipe explains how to handle the faults thrown from a synchronous BPEL process. A BPEL process uses the <throw> activity in case of exceptional situations. It gives the client feedback on what went wrong with the BPEL process processing. In a scenario where the client is expecting the response message and does not capture the faults thrown from the BPEL process, we can define the inline fault in the BPEL process reply activity.

Getting ready

We modified the synchronous BPEL process to throw an exception when the input parameter says FAULT. With the check_fault condition, we check if the input parameter contains the word FAULT. The modified BPEL process is shown in the following screenshot:

We also need to define the fault structure in the XSD schema (HelloWorldProcess.xsd) as shown in the following code:

<element name = "fault">
<complexType>
<sequence>
<element name = "msg" type = "string"/>
</sequence>
</complexType>
</element>

We define the element fault, which contains the element msg of the type string. We then define the fault message in the WSDL document as follows:

<wsdl:message name = "ProcessFaultMessage">
  <wsdl:part name = "message" element = "client:fault"/>
</wsdl:message>

We also specify the fault in the <portType> and <binding> elements of the WSDL document (HelloWorldProcess.wsdl). In the following code, we omit the <binding> element definition:

<wsdl:portType name = "HelloWorldProcess">
  <wsdl:operation name = "process">
  <wsdl:input message = "client:HelloWorldProcessRequestMessage"/>
  <wsdl:output message = "client:HelloWorldProcessResponseMessage"/>
  <wsdl:fault name = "fault" message = "client:ProcessFaultMessage"/>
  </wsdl:operation>
</wsdl:portType>

How to do it…

We create the client proxy the same way we created it in the Calling a synchronous BPEL process from Java recipe. We now see the additional class ProcessFaultMessage.java. We use this class when the fault occurs in the BPEL process. The class is annotated with the @WebFault annotation, which indicates the service specific exception class as follows:

@WebFault(faultBean = "org.packt.bpel.sync.gen.Fault", targetNamespace = "http://xmlns.oracle.com/bpel_101_HelloWorld_jws/bpel_101_HelloWorld/HelloWorldProcess", name = "fault")
public class ProcessFaultMessage
extends Exception

The faultBean attribute defines the Java class that will transform the fault from XML to Java. Additionally, the namespace of the BPEL process is also defined.

We also need to modify the client proxy main class HelloWorldProcess_ptClient.java. Since it is possible that the BPEL process throws a fault, we must prepare our client code in advance for such a situation.

  1. First, we create the input and output variables as follows:

    String input = "FAULT";
    String output = "";

    Tip

    We changed the code for calling the BPEL process because it requests to be in the try/catch block.

    try {
      output = helloWorldProcess.process(input);
      }
    catch (ProcessFaultMessage e) {
      System.out.println( e.getFaultInfo().getMsg());
      }
    System.out.println("Business process returned:" + output);
  2. We run the client and observer BPEL process execution in the Oracle Enterprise Manager Console as shown in the following screenshot:

  3. The output of the console in JDeveloper contains the following messages:

    Error while processing input parameter
    Business process returned:
    Process exited with exit code 0

How it works…

The business faults, as opposed to the runtime faults, are thrown by the applications when a problem with processing information occurs. Various situations can cause the BPEL process to throw a fault. The BPEL process might interact with web services and web service itself may throw a fault. Consequently, the BPEL process must react on the fault thrown by web service. When an exceptional situation occurs in the BPEL process, the fault is propagated to the client. As we can see, the newly created class ProcessFaultMessage.java extends the Exception class. We see that the BPEL faults correspond to the Exception class in Java with extensions. The BPEL process also provides the ability to define the compensation handlers. With the compensation handlers, it is possible to undo the actions that were executed during the BPEL process execution. We can consider the compensation handler as a block of code containing the activities performing the compensation tasks.

There's more…

The BPEL specification defines two types of faults. In this, we meet the BPEL process fault; however, there also exists a set of standard faults.

Note

A list of standard faults can be accessed at the following URL: http://docs.oasis-open.org/wsbpel/2.0/wsbpel-v2.0.pdf (see Appendix A, Standard Faults).

The BPEL standard faults are thrown if the BPEL server encounters some conditions in the runtime environment that do not correspond to the specifications. This category also includes situations where the variables might not be initialized if transformation does not find the XSLT file or if some problems occur on the network.

Tip

When we want to add additional information to the already existing fault in the BPEL process, we define new fault message with additional information in the WSDL document of the BPEL process. We then model the fault handling within the fault handler (the catch or catchall activity). We specify the fault condition that will be caught by the fault handler. Inside the fault handler, we use the rethrow activity that throws the fault, which will give the client a better insight into the problem that occurred in the BPEL process.

 

Handling business faults from an asynchronous BPEL process


The faults that occur either in a synchronous or asynchronous BPEL process are treated the same way inside the BPEL process. The difference, however, exists in the way the client is notified about the fault in the BPEL process. We said earlier that the client is not blocked when calling an asynchronous BPEL process. Since the communication is closed between the BPEL process and client after initiation of BPEL, we need to find a way to notify the client that something went wrong in the BPEL process. This recipe will show you how to handle the faults from the asynchronous BPEL processes.

Getting ready


We modified the asynchronous BPEL process from the Calling an asynchronous BPEL process recipe. We added the If activity, which checks the content of the input parameter of the BPEL process. If the input parameter contains FAULT text, then the BPEL process finishes immediately; otherwise, the BPEL process waits for some time and sends success to the client. The modified asynchronous BPEL process is shown in the following screenshot:

We notify the two reply activities. The callbackClient invoke activity is used in case the asynchronous BPEL process finishes successfully. We add the new invoke activity named returnFault for cases when we need to report the fault back to the client. We model the asynchronous BPEL process with the additional callback operation because the communication between the BPEL process and client is closed immediately after the client initiates the BPEL process, and there is no way the BPEL process can notify the client about the faults. We start by defining the fault message structure in the HelloWorldAsyncProcess.xsd schema as follows:

<element name="fault">
  <complexType>
    <sequence>
      <element name="msg" type="string"/>
    </sequence>
  </complexType>
</element>

We define the fault message structure the same way as we did with the synchronous BPEL process. We also modify the WSDL description of the asynchronous BPEL process (HelloWorldAsyncProcess.wsdl). Initially, we define the message for the fault as follows:

<wsdl:message name = "ProcessFaultMessage">
  <wsdl:part name = "message" element = "client:fault"/>
</wsdl:message>

We define a SOAP message containing the fault message later inside the <wsdl:operation> element of <wsdl:binding element> as follows:

<wsdl:binding name = "HelloWorldAsyncProcessCallbackBinding" type = "client:HelloWorldAsyncProcessCallback">
  <soap:binding transport = "http://schemas.xmlsoap.org/soap/http"/>
  <wsdl:operation name = "processFault">
    <soap:operation style = "document" soapAction = "processFault"/>
    <wsdl:input>
      <soap:body use = "literal" namespace = "http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess"/>
    </wsdl:input>
  </wsdl:operation>
</wsdl:binding>

In the synchronous BPEL process scenario, we added the <wsdl:fault> information in the reply operation. For the asynchronous BPEL process scenario, we model the fault callback as a new operation in the callback portType as follows:

<wsdl:portType name = "HelloWorldAsyncProcessCallback">
  <wsdl:operation name = "processFault">
    <wsdl:input message = "client:ProcessFaultMessage"/>
  </wsdl:operation>
</wsdl:portType>

Information about the fault is then sent via the new callback operation to the client.

How to do it…

The asynchronous BPEL process does not return a fault in the same way as the synchronous BPEL process. For that purpose, we need to check the response SOAP message to see whether it contains the fault as follows:

Iterator<?> it = msg.getChildrenWithLocalName("fault");
if (it.hasNext()) {
  System.out.println("Fault occurred: " + msg.getFirstElement().getFirstElement().getText());
  return;
  }

If the fault exists, we execute the actions for solving the problems.

How it works…

We know from the previous recipes that calling an asynchronous BPEL process does not block the client. So, in order to retrieve information about the fault, we need to take a different approach as and when we call the synchronous BPEL process. We already mentioned that we defined another operation in reply to portType.

We now have a problem, when we send the response information back to the client. Namely, the client does not care, if the message is a success or failure. In any case, the onMessage method in the AxisCallback class is executed. Here is the reason why we needed to implement the additional code inside the onMessage method to check whether we received the fault from the asynchronous BPEL process.

There's more…

Another way of testing whether we received the fault as the response from the asynchronous BPEL process is to take advantage of the WS-Addressing fields in the SOAP Header class of the SOAP message. If we know the operation with which the asynchronous BPEL process is returning the faults to the client, we can check the <wsa:Action> element in SOAP Header as follows:

<wsa:Action xmlns:wsa = "http://www.w3.org/2005/08/addressing">
  processFault
</wsa:Action>

This element identifies the operation that was executed when the asynchronous BPEL process returned the response to the client.

See also

  • For more information about asynchronous communication, check out the Calling an asynchronous BPEL process recipe

 

Mapping the results of a BPEL process


The applications that integrate with BPEL processes are most interested in the results. As we saw in the asynchronous scenario recipes, as a result, we receive SOAP Header and SOAP body within SOAP message. The XML presentation is not very useful for Java applications. The better solution would be to instead have Java applications consume the Java Bean classes. For that purpose, different tools exist that enable efficient XML to Java mapping.

In this recipe, we will examine how to map the results of a BPEL process to Java-based clients.

Getting ready

We will need to extend the client proxy from the Calling an asynchronous BPEL process recipe, so we need to have the asynchronous BPEL process deployed and the client proxy ready.

First, we will update the response of the asynchronous BPEL process to include more XSD schema elements as follows:

<element name = "processResponse">
  <complexType>
    <sequence>
      <element name = "result" type = "string"/>
      <element name = "postalcode" type = "int"/>
      <element name = "temperature" type = "double"/>
      <element name = "person">
        <complexType>
          <sequence>
            <element name = "name" type = "string"/>
            <element name = "lastname" type = "string"/>
          </sequence>
        </complexType>
      </element>
    </sequence>
  </complexType>
</element>

If we now call an asynchronous BPEL process, we will receive more information. Also, the information is nested in the response.

How to do it…

  1. We will start this recipe by generating the Java Bean class that corresponds to the body of the SOAP response message. We use the wsimport command as follows:

       C:\>wsimport -keep -p org.packt.async.generated -Xnocompile -d
       C:\Temp\gen\ http://medion:7001/soa-infra/services/default/HelloWordlAsync/helloworldasyncprocess
       _client_ep?WSDL
       parsing WSDL...
       generating code...
       C:\>

    In the directory C:\temp\gen, the skeleton classes of the corresponding WSDL document are now generated. If we check the content of the directory, we see that there are many more files in it. There are also request classes as well as a client proxy to initiate the BPEL process. For our recipe, we only need the ProcessResponse.java file, so we move only this file into our JDeveloper project. In JDeveloper, we create another Java package as shown in the following screenshot:

  2. We then copy the ProcessResponse.java file into the project. Now, our project layout consists of the following classes:

  3. We now have to adapt the ClientProxy class in order to support the mapping of the result to our Java client. In the AXIS package, there is a utility class, BeanUtil, which is used for the deserialization of the XML content into Java classes. We start by preparing the variable of the result as follows:

    ProcessResponse responseBean;
  4. We then deserialize the XML content of SOAP message body element through the BeanUtil utility class as follows:

    try {
      responseBean = (ProcessResponse)BeanUtil.deserialize(ProcessResponse.class, msg.getFirstElement(), new DefaultObjectSupplier(), null);
      }
    catch (AxisFault e) {
      onError(e);
      }
  5. The XML content of the response from the asynchronous BPEL process is now accessible through the Java Bean as follows:

    <processResponse Process">
      <result>Hello Jurij</result>
      <postalcode>1430</postalcode>
      <temperature>37.5</temperature>
      <person>
        <name>Jurij</name>
        <lastname>Laznik</lastname>
      </person>
    </processResponse>

How it works…

The response from the BPEL process presents an XML document wrapped with the SOAP message. The XML format is not very friendly for programming in Java. That is why few implementations arise with the intent to simplify the transformation of XML to Java.

Implementation

Description

JAXB

Java Architecture for XML Binding. The essential tools of JAXB are as follows:

  • xjc: This is used to convert XSD schema types to their corresponding class representation

  • schemagen: This is used to convert the class representations to their respective XSD schema types

JAX-WS

Java API for XML Web Services. The important tools of JAX-WS are as follows:

  • wsimport: This supports the top-down approach of developing JAX-WS web services

  • wsgen: This supports the bottom-up approach of developing JAX-WS web services

JAX-RPC

Obsolete: replaced by JAX-WS

All the implementations mentioned here work with the same basic concept of serialization, deserialization, marshalling, and unmarshalling. In general, serialization and deserialization presents a way of transforming the data structures in a way that we can store them or transfer them between applications or over a network. The synonym for serialization, when we transform Java objects, is marshalling. Consequently, the synonym for the opposite operation, that is deserialization, is called unmarshalling.

The following mapping is used when we convert from XSD schema types to corresponding Java data types:

XML Schema Type

Java Data Type

xsd:string

java.lang.String

xsd:integer

java.math.BigInteger

xsd:int

int

xsd.long

long

xsd:short

short

xsd:decimal

java.math.BigDecimal

xsd:float

float

xsd:double

double

xsd:boolean

boolean

xsd:byte

byte

xsd:QName

javax.xml.namespace.QName

xsd:dateTime

javax.xml.datatype.XMLGregorianCalendar

xsd:base64Binary

byte[]

xsd:hexBinary

byte[]

xsd:unsignedInt

long

xsd:unsignedShort

int

xsd:unsignedByte

short

xsd:time

javax.xml.datatype.XMLGregorianCalendar

xsd:date

javax.xml.datatype.XMLGregorianCalendar

xsd:anySimpleType

java.lang.Object

xsd:duration

javax.xml.datatype.Duration

xsd:NOTATION

javax.xml.namespace.QName

While the preceding table shows the default mapping between XML data types and Java data types, it is also possible to customize the mapping, usually through the configuration mapping file.

There's more…

Applications written in Java usually do not operate with XML documents. If we want to call a BPEL process, we must also create a request. Until now, we used to build the request with the help of the XML document builder as follows:

OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess", "");
OMElement method = fac.createOMElement("process", omNs);
OMElement value = fac.createOMElement("input", omNs);
method.addChild(value);
//value.setText("Jurij");
value.setText("FAULT");

In the request, we have to know all the information, such as namespace, names of the XML tags, and, of course, the data itself.

To simplify the creation of a request, we can utilize the JAXB tools. First, we will take the Process.java class that we created with the wsimport tool. We include the class into the JDeveloper project. We need to add namespace info to the annotations in the class file as follows:

@XmlRootElement(name = "process", namespace = "http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess")
@XmlElement(required = true, namespace = "http://xmlns.oracle.com/HelloWorldAsync/HelloWordlAsync/HelloWorldAsyncProcess")

We can now also change the createPayLoad() method in the ClientProxy.java class. We create an XML document from the DocumentBuilderFactory class as follows:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().newDocument();

Then, we create a JAXB context with the following:

JAXBContext jc = JAXBContext.newInstance(Process.class);

Finally, we create marshaller and serialize the request class as follows:

Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
marshaller.marshal(req, doc);

The difference between the previous version of createPayLoad() and the newer version is that the previous version lacks transparency and clarity in the code. We can now fill the request data in the following way:

Process req = new Process();
req.setInput("JURIJ");

And call it as follows:

createPayLoad(req)

See also

About the Author

  • Jurij Laznik

    Jurij Laznik is an architect and software engineer with over 14 years of experience in BPEL and Java technologies. In the past decade, he has participated in several large SOA projects in the Energetics and Telecommunication sector. He is an accredited Oracle SOA Implementation Champion by the Oracle Partner Network. In the last five years, he has worked in the banking industry on IT projects as both project manager and system design engineer. He is currently employed as an Oracle programmer at Banka Celje d.d. He is also an assigned lecturer for the Educational Center of Energetics Systems (ICES). He received his Master's degree at the University of Maribor. Currently, he is a PhD student at the Faculty of Computer Science and Information Technology at the University of Maribor, Slovenia.

    Browse publications by this author