Tuesday, 15 January 2008

How to create a BPEL Job Scheduler

Often you have to have a bpel process started or activated on a certain time. For example during the day you append records to a file and at the end of the day you have to transfer the file to another location.

There are several jobschedule solutions. But it can also be done within BPEL PM. The advantage of this is that you can activate BPEL or ESB services or other Webservices without doing any programming. It is all started from the BPEL Console, where the certain instances can also be aborted. And you can make it as generic as you want and schedule as many instances as you want. So you can have a dayly, weekly and/or a monthly scheduled instance the same time.

What you have to do is to first create an asynchronous bpel process. Then change the accompanying xsd of the request/response documents so that the request document contains a Start DateTime element and a Duration element. You could also expand it with a “any” datagram to give it dynamic xml-fragments as input.


Illustration 1: Request Document Structure
Then add a Wait activity to the bpel process. Base it on the expression:
string(bpws:getVariableData('inputVariable','payload','/client:TimerKickoffProcessRequest/client:startDate'))
That is the startdate, with the String function around it to get valid content of the variable.

After the wait activity you can call the service you have to call, or add the activities that have to be performed. If you decide to code the activities in this process then you have to consider the expected duration ot these activities. If you expect a long duration, you might consider to move it to the end of this process, after the rescheduling of the process.

The step next is to calculate the next schedule date-time. This is done by adding duration to the start-time and copy the result to a variable:

Illustration 2: Add duration to DateTime
For your convenience, here is the expression:
xp20:add-dayTimeDuration-to-dateTime(string(bpws:getVariableData('inputVariable','payload','/client:TimerKickoffProcessRequest/client:startDate')),string(bpws:getVariableData('inputVariable','payload','/client:TimerKickoffProcessRequest/client:interval')))
Then you'll have to invoke the process itself. Create a partnerlink, choose the process' own wsdl.
Create an invoke for it with an input variable. Add to the assign above two copy rules, one with the newDate and one with the duration from the process' input-variable.

One thing that have to be taken care off is the situation that the server get's down before the wait expires and then comes up several times the duration later. For example you have a “next DateTime” of 9:00 AM and a duration of 15 minutes. When the server gets down at 8:55 PM and gets up again at 11:00, then the process gets submitted several times, for 9:15, 9:30, 9:45 and so on.
So before the invoke is done, we have to “move” the next scheduled date time to after the current date time. this by adding the interval as often as needed to get the next dateTime later then the current-dateTime. The while-expression is:
string(bpws:getVariableData('InvokeMyself_initiate_InputVariable','payload','/client:TimerKickoffProcessRequest/client:startDate')) <= xp20:current-dateTime()
In the while loop we need an assign with a copy rule that copies the following expression to the startDate: xp20:add-dayTimeDuration-to-dateTime(string(bpws:getVariableData('InvokeMyself_initiate_InputVariable','payload','/client:TimerKickoffProcessRequest/client:startDate')),string(bpws:getVariableData('InvokeMyself_initiate_InputVariable','payload','/client:TimerKickoffProcessRequest/client:interval')))


Illustration 3: Alter startdate to catch up
The Resulting BPEL process is shown below:


Illustration 4: Resulting BPEL Process
Since the process calls itself, the deployment is not straightforward. Deploy the process and determine the location of the wsdl on your BPEL server. Then add this runtime WSDL to the bpel.xml using the following properties:
  • wsdlLocation: TimerKickoff.wsdl
  • wsdlRuntimeLocation: http://localhost:80/orabpel/default/TimerKickoff/TimerKickoff?wsdl
Then deploy it again. you can start the process in the BPEL Coonsole with giving a Start DateTime stamp with the format given. For a duration of 30 minutes give in: PT30M.

Update dd. 13-12-2012: I placed the original file on  the file store on our website www.darwin-it.nl.

9 comments:

  1. Hi,

    Thanks for the idea. As i am new to BPEL can you post the whole project file. So that it will be useful.Thanks in Advance.

    ReplyDelete
  2. Hi,

    I'll see if I can find it anywhere. It was just an example project that I might have deleted.
    But I think the instructions would lead you to a working alternative. I'm interested if there are any inaccuracies in the instructions.

    ReplyDelete
  3. hi,

    Im Joshna just beginner in soa. I need to create a scheduled job that occurs daily sending mail notification by checking a DB column is set true. So for this use case your BLOG was very useful to me. But i have struck in the step after entering the expression to a wait activity. after that you are entering the expression to the newdate variable which was not specified before. It could be very useful if you provide details for all variables(ie.newdate and invoke_myself_initiate_InputVariable)where they are created and used. If possible provide the code to users who are new to soa. please do needful.

    ReplyDelete
  4. hi,

    Im Joshna just beginner in soa. I need to create a scheduled job that occurs daily sending mail notification by checking a DB column is set true. So for this use case your BLOG was very useful to me. But i have struck in the step after entering the expression to a wait activity. after that you are entering the expression to the newdate variable which was not specified before. It could be very useful if you provide details for all variables(ie.newdate and invoke_myself_initiate_InputVariable)where they are created and used. If possible provide the code to users who are new to soa. please do needful.

    ReplyDelete
  5. Hi Joshna,
    Good to see you're picking up SOA. I had to lookup the example from my library. In the past (around 2008) I made an example project, that I expanded to a real-project-version. The latter is too complex and project specific (incorporated pl/sql and Object Types as well) to post here. But I think I found the original example project. I put it here. Good luck with it. Mark though that it is a BPEL 10g project. What version are you on? I'd recommend at least 11gPs4 (11.1.1.5) or later. Current version is 11gPS5 (11.1.1.6).

    Regards,
    Martien

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Hi,
    I am getting Error in wait activity.error is duration has to start with 'p.I am entering 2008-10-28T10:28:19 and when I enter sample data given by you invocation fails giving error date should be in yyyy-m-dd format.Input is PT30M.I have taken datetime datatype.Please help.

    Thanks in advance,
    Jai Acharya

    ReplyDelete
  8. Check in which field you put what. The duration should be in the format PT30M. What you put in would be valid for a start-date (although in the mean time that is a "some what in the past")

    ReplyDelete
  9. Thanks was giving wrong period input.

    ReplyDelete