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

29 comments:

Arun@Dubai said...

Hello Matt,

I am Arun working in Dubai - U.A.E

I exactly follow you step and the only deviation is my pop3 port is 112 and the smtp port is 26 (the default get struck somewhere).

I am using james apache mail server as you do.

The problem I face is, after the deployment of the process the activationagent keep printing log in domain.log as "no such user"

ERROR default.collaxa.cube.activation HeartBeatListenerJob::execute Error while invoking onHeartBeat() method, exception is "No Such User".

My local mail server information is (james apache mail server)

C:\MailServer\james-2.3.0\bin>run
Using PHOENIX_HOME: C:\MailServer\james-2.3.0
Using PHOENIX_TMPDIR: C:\MailServer\james-2.3.0\temp
Using JAVA_HOME: C:\Program Files\Java\jre1.5.0_06

Phoenix 4.2

James Mail Server 2.3.0
Remote Manager Service started plain:4555
POP3 Service started plain:112
SMTP Service started plain:26
NNTP Service started plain:119

I did created a user as dpp in james.

Please through some light on this.
Thank you
Arun

Chidambaram said...

Hello Matt,

I found a workaround for it...

The problem is even though I specify 112 as the port for POP3, the activation agent always look for default 110.

In my local pc the port 110 (POP3) has been assigned for
Macallan Mail Solution - Mail Server for Windows

The problem get resolved once i uninstall the Macallan and start the James (Apache mail server) with POP3 port to 110 (by updating the config.xml at
"james server directory"\apps\james\SAR-INF\config.xml) and at the same time I removed the "port" tag of my emailaccount.xml under
"bpel-home"\bpel\domains\default\metadata\MailService\

But please help me on this question.

why the "port" tag of mailaccount.xml is not working in such cases???

Thanks
Arun

PCE74 said...

Hi Matt,

This is a Very good Blog helping developer around the world, need your help as i followed the steps exactly and i'm getting the following error as error does not say any thing i'm unable to figure it out what is the problem.

Please help

error :
default.collaxa.cube.activation HeartBeatListenerJob::execute Error while invoking onHeartBeat() method, exception is ""

Thanks
Shivanath

PCE74 said...
This comment has been removed by the author.
Nizam said...

Doesn't look like this feature is not ready for any serious production use. Development is clunky. The incoming mailMessage is difficult to interpret in the BPEL process. Basically have to reinvent the wheel of parsing a MIME message...

butlimous said...

Thanks for the nice post!

Free PS3

Marinus said...

Hi, I am using IMAP to poll emails, it polls sometimes, but sometimes the messages just dissapear from my email but the bpel process don't get initiated. This happens about 50% of the time, any ideas?

Peter said...

My BPEL process does get initiated with this technique. My problem is e-mail has an attachment which I need to save to the local folder. Is there any this can be achieved?

Ninja das Caldas said...

Sorry How do I send an email to the configurated email

DK said...

Hi
I also need to save the email attachment to local folder. Is there anyone can do this? Could you please share how to.

As the Mail.xsd schema has an "content" element with "anyType" type. How can I get the attachment?

Thank you
DK.

Balas said...

Hi Matt,

I tried your suggestion. But I'm getting

"Error while invoking onHeartBeat() method, exception is "The requested mailbox is not available on this server.".
when I specify "POP3" or SMTP". When I specify "IMAP' with foldename "Inbox" I get
"com.sun.mail.iap.CommandFailedException: A2 NO There is no replica for that mailbox on this server."."

Any suggestion on what I'm doing wrong?

my file details
.
.

incomingServer
protocol pop3|smtp /protocol
host localhost.xyz /host
port 110 /port
email user@xyz.com /email
password CRYPT{LuEYFflljmm0hmJh1oEdUg==} /password
/incomingServer /mailAccount

Balas said...

Hi Matt,

It's a mistake on the server name we specified. Now the process is working but instead of creating new instance for incoming mail , it creates instance for all existing emails and dangerously it deletes the email after that.

Please let us know is this due to BPEL agent or is't due the mail server setup.

Thank you

Prady said...

Hi I am pradyumna. I want to invoke a BPEL process when a mail comes to my Gmail Account. I tried all the step that Matt have mentioned in his blog. But whenever mail comes to my gmail account my process will not get Invoked. Following is the incoming server details.
Protocol-Pop3
host-pop.gmail.com
email-pkodgi@gmail.com
password-myPassword

Can somebody help me to solve my issue

Marinus Snyman said...

What version of the BPEL server are you using? I had similar problems before I upgraded to the latest version.

marinussnyman.blogspot.com

Prady said...

Hi Marinus,
I am using Oracle SOA Suite 10.1.3.1.0. What version of BPEL i should use to make it working

Marinus Snyman said...

When I upgraded to 10.1.3.3.1 my problem was solved.

Mohd Khalid said...

Hi Matt,

I followed the same step as mentioned in your blog but mt BPEL process instance is not created after getting the email. On domain.log i found this error:
default.collaxa.cube.activation- HeartBeatListenerJob::execute-Error while invoking onHeartBeat() method, exception is "Command received in Invalid state.".

Please help me.

Thanx,
Khalid

Marinus Snyman said...

Hi Mohd Khalid,
what version are you using?

Marinus

Mohd Khalid said...

Hi Marinus,

I am using the version 10.1.3.3

thanx,

anil said...
This comment has been removed by the author.
anil said...

Hi Matt,

I have the following questions wrt Human Workflow

1. How would you send a BPEL Notification to a mailing list?
2. How would you send BPEL Notifications to various users decided at runtime?
3. How is the concept of ADHOC Roles in workflow implemented in BPEL?

Regards
Anil K A

Eduardo Cordeiro said...

Hi, Matt!
Thank you by this very useful article!
I'm using Mail Activation to read an specific account into my project.
The objective is to receive some attachment files (type text) and save the content into specific database.
But I have some problems when the attach file has a different extension (like .lst or .ost). All of them are text/plain. But the adapter interpreted like binary file, corrupting the file's.
Have you some ideal how to resolve this?

Thank',

Eduardo

vivek said...

Hi Matt,
Nice Blog.
It's for 10g .I am looking for a Similar solution in 11g.

Do you have some idea on Activation Agent class in 11g.

Any help would be much appreciated.

Thanks
Viv

subramanyam said...

Hi Matt,
I am subbu,in my current project we are using Email activity which is in 11.1.1.5 version can you please clarify on this

Dave Bridges said...

Several years ago, Mohd Khalid posted an error identical to the one I'm getting: "Error while invoking onHeartBeat() method, exception is "Command received in Invalid state."." but I don't see any answers.
We're using 10.1.3.5 and our process was working fine until our mail admins started requiring SSL connections. Does anybody have a suggestion on how to get this to work with SSL?
Thanks!

Raju said...

Hi,

Firstly, thanks to Matt for the brilliant post.

I configured a BPEL process using this post and am able to read email from a local IMAP mailbox.

However, it doesn't work with IMAPS (imap over ssl, i.e. port 993). I did this by simply pointing the mail account settings xml file to an IMAP mailbox on another server which only works over SSL.

I started a discussion in the Oracle forums but no luck there yet:
https://forums.oracle.com/forums/thread.jspa?threadID=2403689&tstart=0

@Dave Bridges: I see you hit the same issue. Did you manage to solve it? Please can you let us know how you solved it?

Many thanks in advance for any help.

Cheers,
Raju.

cumibulat said...

is this tutorial also can be applied to oracle bpel 11g ?

Wasia Kulsum said...

What will be version of opessl for jdev11.1.1.5.0 and from which site do I need to download

Wasia Kulsum said...

What will be the version of openssl and from where do I need to download this software??
Pls reply asap