We get a lot of questions from customers about how to schedule a BPEL process or web service to run at regular intervals. For example, how to schedule an account billing composite which is required to be run once every night.
Whilst the Oracle SOA Suite doesn’t provide a native scheduling component; Rubicon Red provides an extension to the Oracle SOA Suite (and Oracle BPM Suite) that allows you to schedule the regular invocation of a web service or the publication of an EDN Event.
The Rubicon Red Scheduler provides a Web Service API, which allows you to schedule the execution of a service from another service, such a composite. Once you can do this, it introduces a number of interesting patterns that can be implemented using the Oracle SOA Suite.
For example, we may have a customer satisfaction process, which we want to execute one month after the customer received delivery of ordered goods. Alternatively, we may want to schedule a repeating process for a specific period of time; for example to track the status of a shipped item until it is delivered.
Whilst this can be done using BPEL, this can cause issues when managing the dehydration store, often a better approach is to get the BPEL process to create a scheduled job to manage this separately. In this blog we cover how to schedule a web service from within a BPEL process. We will use this as a foundation for a series of future blogs to cover some of the patterns that this allows.
How to do it...To configure a scheduled job via the web service api, we will need the WSDL for the Scheduler, this can be found at: http://localhost:7001/RXRScheduler_2.0/util.sch.evs.Job?WSDL
For our purpose, we will be configuring the scheduler to invoke our ParcelTracker process (this will be the subject of a future blog), so to follow the example you will need to download and deploy the ParcelTracker composite contained within the example code for this blog (code sample coming soon).Once deployed you will need the WSDL for the Parcel Tracker, this should be available at: http://localhost:7001/soa-infra/services/default/ParcelTracker/ParcelTrackerService?WSDL
Create a SOA Application, with a project containing an empty composite (named ScheduleParcelTracker in the example below). The ScheduleParcelTracker is designed to receive a request containing the orderNo for a parcel to be tracked and creating a scheduled job to invoke the ParcelTracker every 15 seconds to track the status of the specified order.
Drag a Web Service from the SOA Component Pallet onto the External References swimlane within our composite. This will launch the Create Web Service wizard, specify Scheduler as the name and for the WSDL URL enter the location of the Scheduler WSDL.
Ensure the Port Type is util.sch.eve.Job and click OK. JDeveloper will add a reference to the Scheduler to our composite. Next drag a wire from the BPEL process to the Scheduler external reference.
Open the ScheduleParcelTracker BPEL process and rename the default inputVariable to orderNo.
Next drag an Invoke activity onto our BPEL Process; double click on it to open the Edit Invoke window. Give it the name putJob, for the Partner Link select Scheduler, and select the operation putJob. For the input variable, click on the auto-create variable (green plus icon) to launch the Create Variable window; give the variable a meaningful name (e.g. putJobInput). Do the same for the output variable.
Drag an Assign activity onto our BPEL Process, just before the Invoke activity; double click on it to open the Edit Assign window; give it the name setPutJob.
First we need to populate the job element with the unique identity of our job; this is a composite key defined by the elements jobId and jobGroup. Use the assign activity to set jobId to contain the orderNo of the parcel being tracked and the jobGroup to ParcelTracker (the name of our process).
We have also set jobDescription to hold details of the parcel being tracked.
Next we need to specify the schedule for when the job will be run. For the purpose of this blog we will use a basic cron schedule to run our job every 15 seconds. Use the assign activity to specify the following values for the job.
|ns9:jobDefinition/ns9:cronSchedule||'0/15 * * * * ?'|
We have specified the job will only be active from the current date up to 14 days into the future (this is optional – but will prevent the job running for ever in case we forget to cancel it), and set the job to be active (otherwise it won’t run).
Next we need to initialize the Job Definition element, which specifies the web service to be invoked and the content of the payload to be passed. Use the assign activity to initialize the attributes of the job in the element $putJob.payload/ns8:body/ns9:job/ns9:jobDefinition, as detailed within the following table:
We also need to use the assign activity to initialize the content of the element ns9:jobDefinition/ns9:webServiceJobDefinition, as detailed in the following table:
We have now configured the scheduler to send a correctly formed SOAP message to a web service endpoint; the next step is to provide the payload to put in the message.
The putJob element contains an element called soapRequestBody which is defined as xs:anyType. This is where we specify the request message to send to ParcelTracker when the scheduler invokes it.
To do this, we must create a variable of the same type as the message to be sent to ParcelTracker; this is defined in ParcelTrackerService_1.0.wsdl.
Create a new global variable, named syncParcelLocation. Select Message Type as the variable type, and click on Browse Message Types … to open the Type Chooser. From here select Import WSDL file and locate the Parcel Tracker Service WSDL file; ensure copy to project is selected and click OK.
Within the Type Chooser, expand the ParcelTrackerService_1.0.wsdl and select the Message Type syncParcelLocation.
syncParcelLocation contains the element orderNo, set this to be the orderNo contained within the variable used to invoke our BPEL Process. Next, within the Assign activity use an Append rule to copy the entire syncParcelLocation message into the soapRequestBody.
When creating the mapping, you may have noticed a couple of choice elements, for example simpleSchedule or cronsSchedule, and ednJobDefinition or webServiceDefinition. By default, at run-time BPEL will create empty elements for these alternative choices, so we need to remove them to produce a valid message. In the Assign activity, select the simpleSchedule element, right click and select remove.
Repeat this step for the element ednJobDefinition. Now our process is complete so deploy it and run it to see the created job in action. When our scheduleParcelTracker composite is executed it invokes the putJob operation against the Scheduler, the content of the soap message should look something like the following:
This will cause the Scheduler to invoke ParcelTracker every 15 seconds. If you log in Enterprise Manager you should thebe able to see a list of instances of the Parcel Tracker being started every 15 seconds.
If we click on any of the ParcelTracker instances we’ll see the audit trail for a single instance of this repeatedly executed process.