Sunday, January 22, 2012

SOA11G: Scheduling SOA BPEL Process using DBMS_scheduler

Scheduling a BPEL Process is always a requirement which many projects have. SOA11G still doesn't provide Out-of-Box, ready to use functionality for that. So we are left we a choice to use an external scheduler and from that call the SOA Process. One approach is using Quartz API, which has included lot many new features now. Another approach is to use Database based scheduler.

I personally carry this thought that - One product which Oracle has released to IT world, which is efficient, easily manageable and yet reliable is - Oracle DB. So i'll prefer Database based JOBs to try scheduling a SOA BPEL.

Here in 3 simple steps, we will create a DB JOB to schedule a BPEL which takes a STRING as input. 
The input is qualified with namespace - 'http://xmlns.oracle.com/Application1/Project1/BPELProcess1', in this example.

1) Create a PLSQL procedure which will inturn call a BPEL process using SOAP request.
CREATE OR REPLACE PROCEDURE ScheduleBPELProcess
(p_Payload       IN VARCHAR2)

IS
soap_request VARCHAR2(30000);
soap_respond VARCHAR2(30000);
http_req     UTL_HTTP.REQ;
http_resp    UTL_HTTP.RESP;
resp         XMLTYPE;
response     VARCHAR2(30000) := '';
endpoint  VARCHAR2(128) :=   'http://usmtnz-dinfap19.dev.emrsn.org:8120/soa-infra/services/ETH_Temp/Project1/bpelprocess1_client_ep';
-- Service Endpoint URL of the BPEL process

BEGIN
   
--Create a SOAP request to invoke the BPEL process
   
   soap_request:= ' <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
      ||'<soap:Body xmlns:ns1="http://xmlns.oracle.com/Application1/Project1/BPELProcess1">'
            ||'   <ns1:process><ns1:input>inderpal singh</ns1:input></ns1:process>'
    ||'</soap:Body>'
     ||'</soap:Envelope>';   
    http_req:= utl_http.begin_request
    (
     endpoint,
      'POST',
      'HTTP/1.1'
    );
    utl_http.set_header
    (
      http_req  ,
     'Content-Type'  ,
     'text/xml'
    ); -- dealing with plain text in XML documents
   
    utl_http.set_header(http_req  , 'Content-Length'  , lengthb(soap_request));
    utl_http.set_header(http_req  , 'SOAPAction'  , 'process'); -- required to specify a SOAP communication
    utl_http.write_text(http_req, soap_request);--
    http_resp := utl_http.get_response(http_req);
    utl_http.read_text(http_resp, soap_respond);
    utl_http.end_response(http_resp);--
    resp := XMLType.createXML(soap_respond);
   
    IF (instr(resp.getStringVal(), 'ERROR:') > 0)
    THEN 
    raise_application_error (     -20999,     'ScheduleBPELProcess: Failed! '||p_Payload);
    END IF;
   
    resp := resp.extract(    '/soap:Envelope/soap:Body/child::node()'   , 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"'   );

   END;

2) Next Step is to create a job in Oracle DB using DBMS_SCHEDULER package.
BEGIN
  -- Job defined entirely by the CREATE JOB procedure.
  DBMS_SCHEDULER.create_job (
    job_name        => 'schedule_bpel_process',--Name the job
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN ScheduleBPELProcess(''ABC''); END;',--Enclose ---the procedure name here which will be calling the webservice
    start_date      => SYSTIMESTAMP,
    repeat_interval => 'freq=minutely; interval=5',--The repeat interval
 --attribute value can be set according to the scheduled time.These are some --predefined values which can be set.
    end_date        => NULL,
    enabled         => TRUE,
    comments        => 'Job defined entirely by the CREATE JOB procedure.');
 END;

3)We can use DBMS_SCHEDULER.setAttribute procedure to set the values of the attributes of the job created in step 2.
For ex: Here we can change the interval time from 5 mins to 2 mins.
BEGIN
DBMS_SCHEDULER.set_attribute (
    name      => 'schedule_bpel_process',
    attribute => 'repeat_interval',
    value     => 'freq=minutely; interval=2');
 END;



TO disable the job


BEGIN
DBMS_SCHEDULER.set_attribute (
    name      => 'schedule_bpel_process',
    attribute => ’enabled’,
    value     =>FALSE’);
 END;



To drop the Job

BEGIN

DBMS_SCHEDULER.drop_job (job_name => 'schedule_bpel_process');
END;

SOA11G: Automatic Recovery of BPEL Instances


Recently we faced a situation in our STAGE when a lot of instances were generated over –night, without any test being performed. When we dig into it, we found that it’s because of the Automatic Recovery initiation of BPEL Instances by the system itself.

11G gives us options to configure Automatic recovery of BPEL Instances. By default the automatic recovery window set is from 00:00 hrs to 4:00 hrs and the subsequent reties are done at 5mins frequency. You can set it up by setting the BPEL property under soa-infra -> SOA Administartion -> BPEL Properties -> More Advanced BPEL Properties -> recoveryConfig







To cancel Recoverable instances which have failed permanently and are just hogging system resources due to automatic recovery being happened. Go to BPEL Console - soa-infra -> Service Engines -> BPEL. Go to Recovery Tab.


Click to select the instance to recover or cancel. Press “Recover” to Recover OR Press “Mark Cancelled” to stop resubmission of these instances.

Sunday, December 4, 2011

SOA11G: BPEL OneWayInvocation Issue - BUG

What is OneWay Invocation?
An Adapter (say File) reading inbound message from EIS and posting to BPEL for processing is pure OneWay invocation.

How does OneWay Invocation Works in BPEL?
Adapter reads the inbound message and then posts this message to BPEL Engine using OneWayDelivery Policy.

The oneWayDeliveryPolicy is from the Oracle 10g configuration property deliveryPersistencePolicy. The new configuration property name is bpel.config.oneWayDeliveryPolicy in composite.xml.



The oneWayDeliveryPolicy property controls database persistence of messages entering Oracle BPEL Server. By default (async.persist), incoming requests are saved in the delivery service database table dlv_message. These requests are later acquired by Oracle BPEL Server worker threads and delivered to the targeted BPEL process. This property persists delivery messages and is applicable to durable processes.



Something on OneWayDeliveryPolicy values:
Value Description
async.persist
(Default)
Delivery messages are persisted in the database in table dlv_message. With this setting, reliability is obtained with some performance impact on the database. When the client initiates a process instance, an invocation request is placed in an internal queue. Inside Oracle BPEL Server, a message-driven bean (MDB), WorkerBean, monitors the queue for invocation requests. When a message is dequeued, Oracle BPEL Server allocates a thread to process the message.
async.cache Incoming delivery messages are kept only in the in-memory cache. If performance is preferred over reliability, this setting should be considered. Message are not dehydrated into dlv_message table. Rest all is same as async.persist.
sync Directs Oracle BPEL Server to bypass the scheduling of messages in the invoke queue, and invokes the BPEL instance synchronously. In some cases this setting can improve database performance. So there is no role of invoke queue and worker bean here.


Issue:
We have many BPELs being invoked through Inbound Adapters. What we observed is that the Adapter instances are being generated, BUT the further BPEL instance never comes up. And this is happening only with OneWayInvocation BPELs and not with Request-Response BPELs. We checked dlv_message table. The inbound messages were being saved in it.

So we tried changing the OneWayDeliveryPolicy value to “sync” and BPEL instance started generating.

This leads us to the issue – Either invocation requests are not being enqueue into invoke queue OR the WorkerBeans are not able to de-queue them.

SOA11G: SOAP Header in Mediator 11G - BUG

Passing SOAP Header in Mediator is supported in 11G with very GUI support.

To receive the SOAP elements in mediator expression builder it is necessary that a SOAP Header is explicitly declared in the WSDL of the mediator. Likewise to send SOAP elements from Mediator to a target SOAP service, for expression builder a SOAP Header is to be defined explicitly in the WSDL of target SOAP Service.

For better understanding on defining SOAP Header in WSDL -
http://www.ibm.com/developerworks/xml/library/ws-tip-headers/index.html

Defining SOAP Header in the WSDLs:


In Mediator Expression Builder for Assign Values, we can select SOAP Header:


In Mediator Expression Builder for Assign Values, we can assign SOAP Header:


This way SOAP Header could be passed.

BUG Description: Observe how the root element of the SOAP Header has ns2_ETHHEADER (namespacePrefix_ElementName). Now what if the Element name itself has an Underscore in it, i.e. ETH_HEADER. Its an identified BUG with Oracle and has been solved in 11.1.1.6.

SOLUTION:
• Oracle has given a back-port FIX for 11.1.1.4
• Don’t have underscore in the SOAP root element.
• Go for SOA 11.1.1.6

SOA11G: Sending SOAP Header from BPEL 11G – JDEV BUG

This Article is regarding a JDEV bug which I hit while setting SOAP Header in BPEL.

JDEV Version: 11.1.1.4
Bug 12541901 - JDEV SETS INCORRECT BPELX:HEADERVARIABLE INSTEAD OF BPELX:INPUTHEADERVARIABLE
Solution: JDEV PATCH 12541901 (Download through Metalink).

Receiving and Sending of SOAP Header from a BPEL Component is done as below:

Create a BPEL variable of type string, to be received and passed through SOAP Header.
If we want to pass a Complex data through SOAP then we have to have the corresponding schema for that.
SOAP Header Variable to be used in BPEL could be SimpleType, MessageType or ElementType.

For BPEL we need not to have SOAP Header explicitly defined in WSDL.
For Mediator we need to define the SOAP Header Explicitly in WSDL.

For better understanding on defining SOAP Header in WSDL -
http://www.ibm.com/developerworks/xml/library/ws-tip-headers/index.html.


Receiving SOAP Header in BPEL:

In our SOAP BPEL – Receive Activity



This activity code looks like:


This BPEL is ready to read in the SOAP Header into variable gvarSOAPETHHeader.

Sending SOAP Header from a BPEL:

In Invoke Activity of BPEL under Header tab:


This activity code comes out as:


Above is wrong, it’s a JDEV BUG. It should be setting bpelx:inputHeaderVariable=”gvar...” instead of what we have above. Now we need to go to source and manually change it to:


Oracle identified it as a BUG(12541901) and has released a PATCH for JDEV: patch 12541901