Tuesday, 30 January 2007

Using Email to initiate a BPEL Process

The notification service in Oracle BPEL Process Manager allows you to send a notification by email (as well as voice message, fax, pager, or SMS) from a BPEL process.

However another requirement is to be able to use the receipt of an email to initiate a BPEL process. This is the subject of this blog, many thanks to Muruga Chinnananchi on whose original example this is based.

Essentially we want to create a simple process EMailActivation which recieves an email sent to a particular email address. To achive this there are two basic steps:
  1. Configure the BPEL Server to be able to connect to the mail account.
  2. Define the BPEL Process to be initiated on receipt of an email.

Note: Download working example.

Configure Email Account

To configure the email account which the BPEL Server should connect to, we need to place a MailAccount xml configuration file (in our example BpelMailAccount.xml) into the following directory:

    <soa_home>\bpel\domains\default\metadata\MailService

Note: You will need to create the metadata and MailService directories.

The file itself can have any name (though must end with .xml) as you can define multiple accounts. However make a note of the name as you will need it to link your BPEL Process to the actual mail account.

Here’s our sample file:



The outgoing SMTP service doesn’t need to be configured (as we use the notification service to send outgoing emails). However the incoming account is defined by the following tags:

    <incomingServer>
        <protocol>[protocol pop3 or imap]</protocol>
        <host>[imap or pop3 server]</host>
        <email>[imap or pop3 account]</email>
        <password>[imap or pop3 password]</password>
        <folderName>[imap only, inbox folder ]</folderName>
    </incomingServer>

Note: When defining the account name, be careful to use the actual account name not the email address as they are not always the same.

Creating BPEL Process

The first step is to use JDeveloper to create an Asynchronous process initiated by a request message with a payload containing an element of type mailMessage (defined in Mail.xsd installed as part of BPEL PM).

To do this use the BPEL Project Creation wizard to create a BPEL Process in the normal way. After entering the process name and specifying the process template to be asynchronous, select "Next".

This will take you to the next step in the wizard where you specify the Input and Output Schema Elements, click on the flash light for the input schema and select Mail.xsd (located in <SOA_HOME>\bpel\system\xmllib) as shown in the figure 1 below.


Figure 1 - Specify Input and Output Element


This will then open the type chooser window to select the element to use from the imported schema. Select the mailMessage element as shown in figure 2 below.


Figure 2 - Type Chooser


Once the process has been created you can remove the callBackClient activity as we won’t need this.

Import Common Schema

If you now try and compile your process, you will find it fails with an error message. Thus is because the Mail.xsd itself imports a schema (common.xsd), so you need to import this schema as well.

To import the Mail Schema into your BPEL Process, ensure the diagram view for your BPEL process is open and selected in JDeveloper. Then within the BPEL Structure window, right click on the Project Schemas node and select "Import Schemas" (as shown in figure 3 below).


Figure 3 - Import Schema


Note: Once imported, manually update the WSDL file to ensure the import statements for both the Mail.xsd and common.xsd are contained within the same <schema> element or it will still fail to compile. See previous blog - Using Nested Schemas with BPEL for details.

Define Mail Activation Agent

The process itself is now ready for deployment. However we need to complete one final activity, which is to tie the BPEL Process to a mail activation agent for the Email account that we defined earlier.

The Activation Agent will poll the defined mail box for emails and then for each email it receives invoke an instance of the process to handle it.

To do this you need to add the following definition to the bpel.xml file, after the <partnerLinkBindings> element:

  <activationAgents>
    <activationAgent
className=”com.collaxa.cube.activation.mail.MailActivationAgent”
                            heartBeatInterval=”60”>
      <property
name=”accountName">BpelMailAccount</property>
    </activationAgent>
  </activationAgents>


Where heartBeatInterval is how often we want to poll the email account for new emails, and the accountName corresponds to the name of the account configuration file we defined earlier.

Finally deploy the process and send an email to the appropriate account.

Gotcha!! - If you modify the BPEL process in JDeveloper, the bpel.xml file may lose its changes (i.e. the activationAgent definition), and as a result the process will never get initiated - so always check the bpel.xml file is correctly defined just before deploying the process.

Email Server

To make testing easier, I installed my own local mail server. For this I used James (which is an Open Source Java Mail Server from Apache).

Installation of James is very straight forward you just download it and unzip it to a convenient location. To start it, use the script run.bat or run.sh, depending on your operating system in the james-2.3.0/bin directory.

To configure James just bring up a telnet session (on port 4555) to bring up the Remote Administration Tool from which you can create the required accounts. For example, to create the accounts bpel and jsmith (where the password is welcome1) enter the following:

JAMES Remote Administration Tool 2.3.0
Please enter your login and password
Login id:
root
Password:
root
Welcome root. HELP for a list of commands
adduser bpel welcome1
User bpel added
adduser jsmith welcome1
User jsmith added
listusers
Existing accounts 2
user: bpel
user: jsmith
quit
Bye

Monday, 29 January 2007

Using nested Schemas within BPEL

When developing any BPEL based solution, you soon find that you are defining a common set of data objects that are used across multiple processes.

The most obvious place to define those data objects is in one or more XML Schemas which can then be referenced by each of your BPEL Processes.

Oracle BPEL PM 10.1.3 now provides the ability to import these Schemas as part of the BPEL Project Creation Wizard (in previous versions you had to import the Schema after the project was created – which you can of course still do in 10.1.3).

This all works very well, however there is a simple gotcha, that I’ve seen catch out a number of people, and that’s when you import schema’s which themselves import schemas.

Let’s take a simple example. A common scenario is to have a schema which defines common objects such as address, phoneNo, etc. This would be shared across multiple domain specific schemas such as customer (e.g. it imports the common schema to use the address, phoneNo type to hold the equivalent information for a customer).

Now, if were to import the customer schema into our BPEL Process, by default all we are importing are the definitions contained in Customer.xsd. This causes problems when we attempt to parse the customer schema as the parser can’t reference the definitions in the common schema.

The obvious answer here is to simply import the common schema as well. However this doesn’t work. To understand why let’s look at the import statements created in the <types> element of the WSDL file for the BPEL process:



The issue here is that each of the schemas has been imported into a “separate” schema, thus the common schema is not visible to the customer schema. However to fix this you simply edit the WSDL file to combine the imports into a single schema as illustrated below:

Saturday, 13 January 2007

Monitoring SOAP Messages between BPEL Processes

When debugging BPEL processes it can sometime be very useful to see the actual messages flowing between processes.

Now, often the audit trail in the BPEL Console provides sufficient information to see whats going on, and by clicking on the appropriate invoke, receive or reply activity you can see the content of the payload that was sent or received.

However this is only half the story as it doesn’t show details of the actual soap message exchanged and in particular details such as the SOAP headers used for WS-Security and WS-Addressing.

Now you may know that Oracle BPEL PM ships obtunnel a tool for monitoring SOAP Messages exchanged between two parties, e.g. between BPEL and an external web service.

For those who aren’t familiar with obtunnel, it’s a TCP Monitor which works by listening on one port and then forwarding the message onto another (i.e. where the actual service is located).

The simplest way to configure a process to call a web service via obtunnel is to set the property location on the Partnerlink and re-deploy the process. The value specified here will override the webservice endpoint specified in the wsdl document.

This works fine for indivdual service invocations. However if we want to monitor messages between several different BPEL processes, then having to modify multiple partner links across multiple processes can be quite tedious and also requires you to go back and amend them all to there correct value.

In addition for asynchronous processes it’s more complicated, since the invoking process will pass a call back location to the invoked process, which as a result causes replies to by-passes obtunnel, so you don’t see the responses coming back.

Ideally what we want is a simple way to configure BPEL PM to always go via obtunnel when calling a BPEL process without the need to make any changes to the process definition. This is the subject of this technical note.

Configuring the BPEL Server to use obtunnel as a Proxy

Oracle BPEL PM can easily be configured to use a proxy; typically this is for such scenrios as placing an HTTP Gateway in front of a BPEL Server. However we can use the same approach to set up obtunnel as the proxy.

To achieve this we need to set two properties; soapServerUrl and soapCallbackUrl in the server configuration file.

soapServerUrl

This URL is published as part of the SOAP address of a process in the WSDL file.

The hostname and port for this URL should be customized to match the Host and the Listen Port of your instance of obtunnel. Assuming you are running obtunnel on the same host as your BPEL Server, you just need to change the port number.

soapCallbackUrl

This URL is sent by the process (using WS-Addressing) as part of the asynchronous callback address to tell the recipient of the request where to send the response to.

Again the hostname and port for this URL should be customized to match the hostname and listen port of your instance of obtunnel; so should have the same value as soapServerUrl.

The simplest way to set these properties is on the configuration tab from BPEL Admin (to access this on the BPEL Console login screen select goto BPEL Admin). Once set you will need to restart your BPEL Server.

Note: You will need to re-deploy any processes currently deployed to your server in order for them to be re-compiled (e.g. generate WSDL) with the correct addresses.

Configuring the BPEL Domain

Once we have configured the server, any external caller of a process will now access both the WSDL and the service via the proxy URL.

However the default behaviour for a process is to by-pass this proxy, why? Well really for reasons of performance; it simply doesn’t make sense for a process to call another process via SOAP as the overhead would be to big, rather a process simply calls another process via a direct in memory Java call which is far more performant.

However for our purpose, we can turn this off by setting the property optSoapShortcut to false. The simplest way to set this is in the BPEL Console, click on Manage BPEL Domain (top right hand corner), and then update the property in the configuration tab.

Note: In version 10.1.3.0.1, this property is not actually specified in the domain configuration file, so you will need to add it manually to the domin config file, located at:

[bpel_home]/domains/[domain]/config/domain.xml

Once added you will need to re-start the engine for it to pick up the change (from then on you can modify it as normal in the domain configuration tab).

Running obtunnel

The simplest way to run obtunnel, is to launch the BPEL Developer Prompt, this simply launches a Command Prompt with all the appropriate environment varaiables set. From here simply type the command obtunnel.

Once launched simply specify the port you want to listen on, and then the host name and port of your BPEL Server.

Summary

Using this approach you can easily monitor the various SOAP messages between processes, without the need to make any actual changes to the configuration of the process. All that is required is to deploy them to a version of the BPEL PM Server configured to use the proxy.

Note: If you develop your BPEL Processes against the “Proxy BPEL PM Server”, then the WSDL locations in the PartnerLinks will contain the Host and Port No of the Proxy of the service. This is typically not a problem as you re-configure these as part of the process of deploying the processes to a test / production BPEL PM Server.