Oracle SOA Suite Best Practices

Oracle SOA Suite Build, Deployment, and Test Automation


by Sjoerd Michels, SOA Architect, AMIS

Published April 2007

Background

Service-oriented architecture (SOA) bridges the gap between business and information technology. In a typical SOA environment, business processes are constructed from a variety of business services. Each business service may be implemented using different information systems or technologies, turning an SOA implementation into a true integration effort. But of course, all the architectural benefits of the evolution in enterprise integration made their way into SOA. To name a few:

  • Widely adopted Web services standards allow easy assimilation of specialized components (favoring buy over build).
  • Loosely coupled services that are based on proven messaging technologies provide a highly scalable and robust platform.

In the end, all these loosely coupled pieces of technology, each having their own versions and release schedule, need to interoperate for the system to work. That makes release management and integration testing in an SOA environment an important and potentially daunting task. It is important to implement strict procedures and appropriate tools for development, testing, acceptance testing, and production release—it's all in a day's work for your average agile project team.

In this Technical Note, you will learn to set up an automated build and deployment environment for your Oracle SOA Suite project. (Release 10.1.3.1 of Oracle SOA Suite features improved automated build capabilities; instead of the Oracle-specific obant Ant tool, plain-vanilla Ant is now used for building and deploying BPEL suitcases.) The goal is to automatically build Oracle's SOA Suite Order Booking demo application and deploy it to an Oracle Application Server instance that runs Oracle SOA Suite. Oracle's demo application is ideal here because it uses all the components in Oracle SOA Suite: Oracle Enterprise Service Bus (ESB), Oracle BPEL Process Manager, and Oracle Business Rules. The demo application also includes a number of Web services that are programmed in Java.

As you will learn, it is not that hard to automate repetitive and tedious build and deployment tasks. In the end, this approach will save you valuable time and help provide your customers with consistently high-quality systems.

Creating Your Own Build and Deployment Server

For your build server, you will first install a number of software components. Obviously, to start with you need an Oracle database. With its modest impact on system resources, Oracle Database 10g Express Edition is ideal. We chose Oracle Application Server 10.1.3.1 with the accompanying Oracle SOA Suite in order to closely mimic the test and production environments—in which your software will ultimately have to run. For turning your software into packages that can be deployed to Oracle Application Server, you will use the Ant build tool that Oracle bundles with the app server.

Luntbuild. We opted for the open source build automation and management tool Luntbuild. The main reason for selecting Luntbuild is that it is able to deal with dependencies between different projects. In Luntbuild, a project is the metaphor for anything that you want to build—a "buildable unit," in Luntbuild terms. For example, it is possible to build and deploy a Web service first and, when that task is done, build and deploy the BPEL process that uses the Web service. Also, Luntbuild (optionally) stores its build data in an Oracle database, allowing you to easily track, manage, and report on your daily builds.

Subversion. For this article, the source code version control system of choice is Subversion. But Luntbuild does not discriminate; it supports a wide variety of version control systems, such as CVS, Visual Sourcesafe, and Clearcase. Subversion features a powerful command-line interface, and Oracle provides a great JDeveloper plug-in for it. To create a Subversion repository and subsequently retrieve a working copy takes only the following two lines of code:

     
svn import C:\oracle\product\soademo file:///c:/projecten/svnrepos/soademo -m "Initial import"
svn checkout svn://localhost/projecten/svnrepos/soademo soademo      

In larger, multiuser environments, Subversion is probably accessed via an Apache server. For a single-user build system, Svnserve provides a lightweight and very easy-to-use standalone alternative. Svnserve is bundled with Subversion.

Ant Build Scripts for the Web Services Components

The Quick Start Guide for Oracle's SOA Suite Order Booking application assumes that all components are installed from Oracle JDeveloper. In order to automate builds, build scripts are required. For Oracle BPEL projects, Ant build scripts are created automatically by JDeveloper. The demo application does not come with build scripts for Web services nor for the ESB components. In this paragraph, the creation of an Ant build script for the CreditService is outlined.

A good starting point is the Ant build script generator in Oracle JDeveloper, which can be executed to create an Ant build file for the project as it is defined in JDeveloper. Use it to generate a skeleton that at least contains the classpath settings for the Java libraries in the project.

The following picture shows the selection of a new Ant Buildfile from Project that will be generated by JDeveloper.

Figure 1


Then, add Ant targets for compiling the Java classes that comprise the Web service, as well as for creating Web and Enterprise archive files. The latter two are shown here:

    
...
<!-- Create war file -->
<target name="warfile" depends="rebuild">
  <echo message="Creating the Web Application module (war) file"/>
  <delete>
                <fileset dir="${dir.deploy}" includes="${warfile.name}"/>
        </delete>

  <war destfile="${dir.deploy}/${warfile.name}"        
       webxml="${dir.html.web-inf}/web.xml">
    <classes dir="${dir.output}" includes="**/*"/>
    <webinf dir="${dir.html.web-inf}" includes="**/*"/>
  </war>    

  <!-- Clean up the build information -->
  <delete dir="${dir.output}"/> 
</target>

<!-- Create ear file -->
<target name="earfile" depends="warfile">
  <echo message="Creating Enterprise Archive (ear) file"/>
  <delete>
        <fileset dir="${dir.deploy}" includes="${appl.name}.ear"/>
  </delete>

  <ear destfile="${dir.deploy}/${appl.name}.ear" appxml="${dir.deploy}/application.xml">
    <fileset dir="${dir.deploy}" includes="*.war,orion-application.xml"/>
  </ear>
</target>
...       

Finally, use the oracle:deploy Ant task for OC4J that comes with Oracle Application Server. This task utilizes the OC4J client administration tools in order to deploy a module to OC4J. Oracle provides clear instructions for use with OC4J standalone, for the OC4J container running in an Application Server setting, and for a clustered environment. Simply add a namespace declaration to your Ant build file, extend the build path so that Ant can access the Oracle Ant task-specificlibraries, and add the oracle:deploy target to the build.xml file, like this:

...
<target name="deploy" depends="earfile">
  <echo message="Deploying Enterprise Archive (ear) file"/>
    <oracle:deploy deployerUri="${deployer.uri}"
                   userId="${oc4j.admin.user}"
                   password="${oc4j.admin.password}"
                   file="${dir.deploy}/${appl.name}.ear"
                   deploymentName="${appl.name}"
                   bindAllWebApps="default-web-site"
                   logFile="${dir.deploy}/deploy-${appl.name}-ear.log"/>
</target>
...  

The important thing here is to have the deployer URI right. Whether the build was successful can be tested with Oracle Enterprise Manager 10g Application Server Control, which comes with a facility to test Web services.This is shown in the following figure:

Figure 2


Create similar build scripts or enhance this Ant script for building and deploying the CustomerService and the RapidService of Oracle's SOA demo application. Take into account that these use different libraries.

Building BPEL Suitcases Using Ant

In Oracle SOA Suite 10.1.3.1, standard Ant scripts are used for building and deploying BPEL projects (suitcases). The build.xml file for a new BPEL project is generated automatically when a new BPEL project is created in Oracle JDeveloper. It is great to see that the Ant build scripts are used by Oracle JDeveloper for BPEL deployments.

Running Ant for building the SOAOrderBooking BPEL process resulted in the message BUILD FAILED: Error while deploying decision services. Setting verbose="true" on the deployDecisionServices task reveals the problem:

It turns out that the .svn directory that is used by Subversion for administration purposes clutters things up. Apparently, Oracle's deployDecisionServices Ant task dives into any subdirectory within the decisionservices directory in an attempt to deploy that .svn "Decision Service."

This is a minor glitch that requires a workaround. At this point, the pre-deploy and post-deploy targets that are part of the BPEL process' Ant build file come in handy. A simple workaround is to temporarily remove the .svn directory, like this:

<target name="pre-deploy">
    <!-- Add tasks here to be performed prior to process deployment. -->
    <!-- Temporarily remove the Subversion administration directory from
         the decisionservices as it will break the build
    -->
    <move file="${basedir}/decisionservices/.svn"
          tofile="${tempdir}/decisionservices/.svn"/>
</target>

And when the process is done, put it back:

< p class="code"> <target name="post-deploy"> <!-- Add tasks here to be performed after process deployment. --> <move file="${tempdir}/decisionservices/.svn" tofile="${basedir}/decisionservices/.svn"/> </target>

Managing the Environment

Oracle BPEL Process Manager provides easy-to-use yet powerful versioning capabilities, allowing you to run multiple versions of a process simultaneously. This way, existing instances of version 1.0 can finish while version 2.0 is used for new instances of that process. Upon deployment of a new version, this new version of the process likely needs to be marked as the default.

The BPEL console provides screen functions for that purpose, but that obviously is not very helpful in an automated build and deployment environment. Fortunately, the Java client API (that is also used by the BPEL console) comes to the rescue. For marking a new process as the default revision, the following code will do:

public void markProcessAsDefault(String processId, 
                                 String revision) throws ServerException {
    if (locator == null)
        locator = getLocator();
    IBPELProcessHandle iBPELProcessHandle = 
        locator.lookupProcess(processId, revision);
    if (iBPELProcessHandle != null && 
        !iBPELProcessHandle.isDefaultRevision()) {
        iBPELProcessHandle.markAsDefaultRevision();
    }
}

The client API is packed with other useful functions; for example, clearing the WSDL cache, something desperately needed during BPEL deployments. But the client API is also very useful for performing tedious management tasks, such as removing finished process instances from a BPEL system in order to keep the dehydration store lean and mean.

Again, the pre-deploy and post-deploy targets in the Ant build files for a BPEL process come in handy for performing these additional tasks. The following Java class extends Ant by turning the code snippet for marking a process revision as the default into an Ant task that can be invoked from the post-deploy target:

package nl.amis.soa.ant;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;

import nl.amis.soa.bpel.BPELBuildUtils;

public class MarkBPELProcessAsDefault extends Task {

  private String processId;
  private String revision;

  public MarkBPELProcessAsDefault() {
  }

  public void setProcessId(String processId) {
    this.processId = processId;
  }

  public String getProcessId() {
    return processId;
  }

  public void setRevision(String revision) {
    this.revision = revision;
  }

  public String getRevision() {
    return revision;
  }

  public void init() {
    super.init();
  }

  public void execute() throws BuildException {
    if (processId != null && revision != null) {
        BPELBuildUtils bpelBuildUtils = new BPELBuildUtils();
        try {
            bpelBuildUtils.markProcessAsDefault(processId, revision);
        } catch (Exception e) {
            throw new BuildException("Process with id " + processId + 
                                     " and revision " + revision + 
                                     " could not be marked as default." +
                                     e.getMessage());
        }
    } else {
        throw new BuildException("Process not correcly identified; 
                                          either processId or revision not given.");
    }
  }
}

Next, I'll provide a short introduction to ESB concepts and to the Oracle ESB product before turning to the build automation tasks for ESB services.

Short Introduction to ESBs

The ESB concept combines a number of integration patterns. At the heart is the idea of a message bus that enables disparate applications to work together in a decoupled way via the exchange of messages. This concept is illustrated in the following diagram:

Figure 3


Oracle ESB implements this concept and additional enterprise integration patterns for working with messages in a secure way. It provides functions to connect, transform, and route business documents (mostly XML messages).

In the industry, an ESB is regarded as the underlying infrastructure for delivering SOA and event-driven architecture (EDA). The following figure provides an overview of Oracle products in SOA and EDA space, putting the different components into perspective:

Figure 4


Certainly, BPEL and ESB have characteristics in common. For example, both are very capable of handling message transformations, and both Oracle BPEL and Oracle ESB allow the use of adapters to connect to a myriad of sources and business services. BPEL is business process oriented, whereas ESB is more a part of the technical infrastructure. Combine BPEL and ESB, and put each to good use. From an ESB perspective, use Oracle ESB for

  • Crossing boundaries between semantically different domains in order to keep your BPEL-supported business processes free from technicalities such as transformations
  • Fast message handling without the overhead of BPEL
For an excellent hands-on introduction to Oracle ESB, read Lucas Jellema's article "Building Event-Driven Architecture with an Enterprise Service Bus".

Automating Builds and Deployments for Oracle ESB

Like almost any other component in an Oracle technology stack, ESB services are developed using Oracle JDeveloper. In a JDeveloper project, ESB Systems, Service Groups, and Services are constructed. Systems and Service Groups are provided as a means of organizing the ESB Services. Oracle JDeveloper also provides a function for deploying an ESB project and its contents to the ESB Metadata or Design Time server via the "Register with ESB" option.

But in an automated build and deployment environment, the intention is to stay away from tools that require manual intervention. Unfortunately, for ESB components Oracle does not yet provide automated build and deployment facilities.

A little investigation of the contents of the directory for the FulfillmentESB project shows that a zip file is constructed when the project is registered with the ESB. The zip contains the System and the Services definitions (a Service Group is not used) and the modules that make up the Services. While this is not hard to construct—for example, via Ant—the remaining question is, how is this archive file actually registered with the Oracle ESB server?

That question was quickly relayed to Doug Gschwind, a principal solutions architect in Oracle's Application Server Solution Architects Team. Doug provided custom Ant tasks for building and deploying ESB projects that then allows automation and repeatability and thus makes life easier.

Based on the excellent documentation provided by Doug, I constructed the following Ant build file :

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

<project name="FulfillmentESBDeploymentProject" default="usage">
    <property file="build.properties"/>

    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
      - Import, to enable the custom ESB Deployment ant tasks ...
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
    <import file="${dir.lib}/ESBMetadataMigrationTaskdefs.xml"/>

    <target name="deployProjects">
        <deployESBProjects esbMetadataServerHostname="${esbMetadataServerHostname}"
                       esbMetadataServerPort="${esbMetadataServerPort}"
                       userName="${esbServer.userName}"
                       password="${esbServer.password}">
            <esbProject directory="${dir.esbProjectToDeploy}"/>
        </deployESBProjects>
    </target>

    <target name="undeployEntities">
        <undeployESBEntities esbMetadataServerHostname="${esbMetadataServerHostname}"
                         esbMetadataServerPort="${esbMetadataServerPort}"
                         userName="${esbServer.userName}"
                         password="${esbServer.password}">
            <system guid="3C2D63E0CC1811DABFA0CDAACB57527A"/>
            <service guid="68CC671116A611DB8F22F7EF54089965"/>
            <service guid="FFF9F230D18F11DA8F7635853D6BAACC"/>
            <service guid="84A618D1D18E11DA8F7635853D6BAACC"/>
            <service guid="81944430CC1811DABFA0CDAACB57527A"/>
            <service guid="802F6421D19611DABF86ADAC868E14B0"/>
        </undeployESBEntities>
    </target>

    <target name="usage">
        <exec executable="ant" dir="${basedir}" vmlauncher="false">
            <arg value="-projecthelp"/>
        </exec>
    </target>

</project>   

Note: There are other functions available; for example, for metadata promotion to different ESB Metadata Servers. These are beyond the scope of this article and therefore not mentioned.

The Globally Unique Identifiers or GUIDs in the build file for the System and the Services are available in the descriptive files for these modules, with extensions .esbsys and .esbsvc, respectively.

Using the Ant file for ESB deployments within Oracle JDeveloper. To use the Ant extensions from within Oracle JDeveloper as well, add the Apache commons-codec library and the library that contains the extensions to the classpath of the default Ant version used in JDeveloper, as shown in the following figure:

Figure 5


The extensions to Ant for building and deploying ESB projects are provided as is and are not an official part of the Oracle SOA Suite product stack yet. However, these Ant extensions will be included in an upcoming patch release. In the meantime, contact Oracle through the usual channels to request this Ant package.

Configuring Luntbuild

Now that the entire toolkit is installed and the Ant build scripts are created, it is time to configure Luntbuild. Sticking to the SOA Order Booking demo application, we created Luntbuild projectsfor each component, as shown in the following figure:

Figure 6


Once the Ant scripts work, configuration of Luntbuild is straightforward, so we will not go into much detail here. Important for building the BPEL processes is the correct setting of the environment variables. There is a simple trick to getting these right: open a BPEL Developer Prompt window and "steal" the environment variables from there. The following screenshot shows part of environment variables in a Luntbuild configuration screen.

Figure 7


For setting up dependencies between projects, Luntbuild provides multiple strategies. We set up dependencies between the projects preserving the order that is outlined in the SOA demo application Quick Start Guide and made each project trigger the next in order. (See below.)

Figure 8


Since this Note is not a Luntbuild configuration guide, the remaining configuration details are not discussed here. A quick start guide for Luntbuild is available here.

Stop Talking, Start Building!

Starting the build for the BPEL processes and Web services of the Oracle SOA Suite Order Booking demo application requires the start of the build and deployment of the FulfillmentESB services.

Pictures speak louder than words:

Figure 9


Now that the build is successful for all components in the technology stack, it is time to test and verify the entire system. With the Order Booking demo application, Oracle provides a Web-based application that allows you to shop and book an order. The Shopping Card application then triggers the SOAOrderBooking BPEL process that handles the order. However, for an automated build and deployment system this is not satisfactory; it needs automated test capabilities. Especially in SOA space, where you design to interfaces, it is good practice to test to these interfaces. In the following paragraphs, the new BPEL unit test capabilities that were added in Oracle SOA Suite version 10.1.3.1 are explored.

Oracle SOA Suite BPEL Process Test Automation

Anyone familiar with unit testing Java code with the help of the de facto standard JUnit tool will quickly find their way around the BPEL unit testing tool. To start with, a test suite for the SOAOrderBooking BPEL process is created using Oracle JDeveloper.

Figure 10


As is clear from the above, the context menu also allows for the creation of a test case, via the menu option Create BPEL Test. An alternative for putting together a test case from scratch is to look for a template or baseline test case that can be imported using the menu option Import BPEL Test. The Oracle BPEL server is able to extract a baseline test case from a BPEL process instance. The following picture of the BPEL Console shows an instance of the SOAOrderBooking process that completed successfully. From here, the Test function is used to let the BPEL server generate the baseline test case for the process instance.

Figure 11


Back in Oracle JDeveloper, the test case can be imported into the Order test suite. Once that is done, it can be fine-tuned to fit your needs. Opening the test case in JDeveloper shows the SOAOrderBooking BPEL process in test mode. In this mode, it is not possible to edit the structure of the process—for example, to add or remove activities. It does allow specification of emulatedmessages that the BPEL process receives from its Web service partners or the creation of assertions with respect to variables in the BPEL process. ("At this point, I expect that variable x has value y.") Emulation is very suitable for testing human input into the process that would otherwise require "real" human effort—not a particularly good idea in repeated, automated test cases. The following picture shows emulated messages for a human task. Also, emulated messages allow testing of a BPEL process without actually invoking services that are defined as partner links in that process. For example, use of a service may be restricted—perhaps there is a pay-per-use fee or you may not always be able to control all Web Services in a distributed system.

Figure 12


Putting the Test to the Test

Like a BPEL process, a finished test case needs to be deployed to the BPEL server before it can be executed. Oracle JDeveloper comes with a graphical tool for deploying test suites and specific test cases, as shown in the following figure:

Figure 13


As an alternative for use in an automated test environment, Oracle also provides the deployTestSuites Ant task to take care of test suite deployment. This task is available from the Ant build script that is created for a BPEL process. That script also contains tasks for running deployed test suites of a BPEL process (the bpelTest task) and for reporting on the results of the test (the report task). The latter creates a JUnitReport for the test suites that were executed. As is the case with BPEL process deployment, this opens doors for configuring test suite deployments, execution, and reporting on the results as a Luntbuild project, to be scheduled when all components of the system are installed successfully.

Conclusion

In this Technical Note, you learned that it is easy to automate repetitive and tedious build and deployment tasks using Oracle SOA Suite 10.1.3.1. Oracle has effectively leveraged industry-standard build and deployment techniques for its product. And there is more to explore; we have not even touched on Oracle SOA Suite's possibilities for deploying to multiple environments, for example.

I have demonstrated simple yet effective use of technology to make your life easier. It applies to any software engineering effort but is especially relevant to SOA-based systems in which interoperation of loosely coupled components is important: design and test to interfaces. By putting the techniques outlined here into practice, you save valuable time and, more important, help to provide your customers with consistently high-quality systems.


Sjoerd Michels works as an Information Architect for AMIS in the Netherlands. He has more than 12 years of experience in architecting, designing, and building custom-made information systems using a mix of Oracle, Java, and open source technologies. During the last 2 years, Sjoerd worked on several SOA implementations concentrating on Oracle SOA Suite and Java technology.