Showing posts with label EDN. Show all posts
Showing posts with label EDN. Show all posts

Saturday, October 19, 2013

OnEvent functionality of Oracle BPEL 2.0 for parallel processing

                           One of my recent projects involved automation of account creation in multiple systems, using multiple workflow process. There was a main process which was controlling the rest of the flow. One of the requirements was to give option to admins or the super user to cancel the workflow or process flow at any point of time during their execution.
This feature was required so that in case if the Admin see’s foul play or someone trying to create a suspicious account, the support team or admins should be able to cancel or terminate the request and invalidate the changes performed by the request.
  This was an interesting use case where we can leverage the OnEvent functionality of BPEL 2.0 .In BPEL 1.1 there was option of OnMessage which has been replaced with OnEvent. Even though the name is OnEvent it is more of a service call with separate one way operation defined as part of the main service.
So if you have a Service, you can define multiple operations which can be used as part the OnEvent.
In case you want to know the status of the long running process, you can define a getProcessStatus operation which should ideally check the status parallel in the flow and send notification or asynchronous callback to return you the status. The OnEvents are all async in nature.
Couple of use cases would be to update the request details on the fly using an onEvent. Canceling and terminating the request, and in case if compensation needs to be done can handled in the onEventHandler.







   <wsdl:operation name="request">
            <wsdl:input message="client:EventTestRequestMessage"/>
        </wsdl:operation>
        <wsdl:operation name="getStatus">
            <wsdl:input message="client:EventTestStatusRequestMessage"/>
        </wsdl:operation>
        <wsdl:operation name="cancelRequest">
            <wsdl:input message="client:EventTestCancelRequestMessage"/>
        </wsdl:operation>
        <wsdl:operation name="updateRequest">
            <wsdl:input message="client:EventTestRequestMessage"/>
        </wsdl:operation>

When you select onEvent, you expectation will be to see a partnerlink which will accept a service operation or an event subscription. But in BPEL 2.0 Oracle implementation it’s only the service operation option that is available. I am not sure why they didn’t want to have event subscribers also in the parallel scope. It would have given us more options to play with EDN and have event created for different processes.



The only tricky part here is to correlate the instances, so you will need to add a unique identifier like a requestId, or combination of UserId and requestId to correlate the instances and can trigger the events.




You can always define onEvent on different scopes, so if you divide your process into multiple scopes and define OnEvents you will get multiple parallel entry points into your existing /running process, which gives you a lot of flexibility in terms of cleaning up or handling different complex scenarios.
If we design a solution with an onEvent flow for reprocessing, then the flow will come in handy for re-processing the scope again for the instances based on run time decisions. So plan ahead and have a handler for defining the logic which can interfere with the existing process flow and reach a different state of completion.
So our solution had terminate Request service exposed to the application which will trigger cancel Request OnEvent of all the participating processes there by terminating the particular request.
Hope this helps J
References:-

Monday, February 18, 2013

Error handling using EDN-reuse code -Soa 11g


In my project we had used EDN event delivery network in SOA 11g for error handling.
We created an Error event and with a error message structure .
Eg: HelloPlatformErrorEvent, so I will be listing down the entries that you will need to implement error handling across the processes .The code is reusable and will take care skeletal common error handling.
The good thing with using EDN in errorhandling is we can have multiple consumers consuming the event and do different processing. Since EDN is fully supported in SOA 11g , the overheads of publish and subscribe /configurations will not be bothering us. We need to create an event and consumers can receive events .So if we can have multiple consumer bpel’s each doing different functionality ,one can write a file,one process writing to DB, once sending notifications. So we have plugged out the error handling/logging mechanism out of the processes. Consumers can be enables/disabled separately based on requirement.

Steps for reusing the event driven error event codes

Here for example the
event  :  HelloPlatformErrorEvent,
edl file : HelloPlatformErrorEvent
Message structure :HelloPlatformErrorEvent.xsd
Since it’s used across composites, the file will uploaded/accessed from MDS.

Composite.xml

·         Add to imports

<import namespace="http://schemas.oracle.com/events/edl/HelloPlatformErrorEvent"
          location="oramds:/apps/HelloPlatform/Events/edl/HelloPlatformErrorEvent.edl"
          importType="edl"/>

·         Add to component (bpel)
    <business-events>
      <publishes xmlns:pub1="http://schemas.oracle.com/events/edl/HelloPlatformErrorEvent"
                 name="pub1:HelloPlatformErrorEventMessage"/>
    </business-events>

. bpel file

·         Add to namespaces
         xmlns:bperrmsg="http://xmlns.oracle.com/HelloPlatform/ErrorMessage/V1"
         xmlns:errorEvent="http://schemas.oracle.com/events/edl/HelloPlatformErrorEvent"
·         Add to imports
<import namespace="http://xmlns.oracle.com/HelloPlatform/ErrorMessage/V1"
          location="oramds:/apps/HelloPlatform/Events/schema/HelloPlatformErrorEvent.xsd"
          importType="http://www.w3.org/2001/XMLSchema"/>

·          Add to Variables
<variable name="PublishHelloPlatformErrorEvent"
              element="bperrmsg:HelloPlatformErrorEventMessage"/>
·         Add inside catchall
The assign values will vary based on your message structure
       
<sequence name="ErrorSequence">
  <assign name="assignErrorEvent">
          <copy>
            <from>ora:getFaultName()</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:ErrorDetails/bperrmsg:ErrorCode</to>
          </copy>
          <copy>
            <from>ora:getConversationId()</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:InstanceDetails/bperrmsg:ConversationId</to>
          </copy>
          <copy>
            <from>ora:getInstanceId()</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:InstanceDetails/bperrmsg:InstanceId</to>
          </copy>
          <copy>
            <from>ora:getCompositeName()</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:InstanceDetails/bperrmsg:CompositeName</to>
          </copy>
          <copy>
            <from>ora:getProcessId()</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:InstanceDetails/bperrmsg:ProcessName</to>
          </copy>
          <copy>
            <from>ora:getFaultAsString()</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:ErrorDetails/bperrmsg:ErrorText</to>
          </copy>
          <copy>
            <from>'Error occured in TaskExecutionFetchPendingTasksProcess'</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:ErrorDetails/bperrmsg:ErrorMessage</to>
          </copy>
          <copy>
            <from>true()</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:ErrorHandlerOptions/bperrmsg:PersistMsgOnDB</to>
          </copy>
          <copy>
            <from>true()</from>
            <to>$PublishHelloPlatformErrorEvent/bperrmsg:ErrorHandlerOptions/bperrmsg:SendNotification</to>
          </copy>
        </assign>       
<invoke name="invokePublishHelloPlatformErrorEvent"
                bpelx:eventName="errorEvent:HelloPlatformErrorEventMessage"
                inputVariable="PublishHelloPlatformErrorEvent"
                bpelx:invokeAsDetail="no"/>
        <exit name="ProcessExit"/>
      </sequence>
   
That’s it for today. Thanks to Ram,Ravi for the coming up this model.

Friday, May 21, 2010

Event delivery Network – publishing events using SQL API

Business Events always had been an interesting option when it comes to initial design of an interface. For all real time integrations, we will always prefer a business event in case end system supports it. In scenarios where business events are not supported, applications are developed to sense pre-defined conditions or continuously poll for new events. But these do not offer the flexibility and scalability required to handle new and more complex changes that will come in the future. In other scenarios, the business event feature may be there but the business event may not contain the entire payload which needs to be fetched using the ids provided as part of the business event data. Business Events is one of the new features in SOA Suite 11g, named as the Event Delivery Network (EDN). Event-driven architecture can always complement service-oriented architecture (SOA) because services can be activated by triggers fired on incoming events.

Refer the blog by Clemens on how to publish/subscribe to an event using Java APIs

http://blogs.oracle.com/soabpm/2009/07/event_delivery_network_chapter.html

I will throw some light on the steps involved as well as the internal APIs provided by EDN that you can use to publish events.

Publisher and Subscriber needs to be aware of the data format that they need to communicate in. So the first step will be to define the Payload of the business event. For this define an XSD schema which will become your payload.

On subscriber side we need to define Business Event through an edl file.

<definitions xmlns="http://schemas.oracle.com/events/edl" targetNamespace="'http://schemas.oracle.com/events/edl/EDNtest ">

<schema-import namespace="http://xmlns.geo.com/ns/Employee" location="xsd/Employee.xsd"/>

<event-definition name="createEmployee">

<content xmlns:ns0="http://xmlns.geo.com/ns/Employee" element="ns0:Employee"/>

</event-definition>

<event-definition name="removeEmployee">

<content xmlns:ns0="http://xmlns.geo.com/ns/Employee" element="ns0:Employee"/>

</event-definition>

</definitions>


Important thing to note is an event will be in its own namespace for example -“'http://schemas.oracle.com/events/edl/EDNtest” and the payload will have its own namespace - “http://xmlns.geo.com/ns/Employee”

There are a couple of tables and queues defined in SOAINFRA schema with the prefix EDN which are used as part of the event delivery system in SOA suite 11g. There is a queue named ‘edn_event_queue’ which is used to store all the published events. It uses underlying EDN_EVENT_QUEUE_TABLE for storing all the event payloads.

There is an internal API which is being called by the java SendEvent class to publish the data on to the queue. The API is ‘edn_internal_publish_event’. So in cases where we need to publish an event from functions and procedures we can call this publish API on the SOAINFRA schema.

code snippet on how to publish an event using SQL API

call edn_internal_publish_event('http://schemas.oracle.com/events/edl/EDNtest','createEmployee','<business-event xmlns:ns1="http://schemas.oracle.com/events/edl/EDNtest'" xmlns="http://oracle.com/fabric/businessEvent">

<name>ns1:createEmployee</name>

<id>e4196227-806c-4680-a6b4-6f8df931b3f3</id>

<content>

<Employee xmlns="http://xmlns.geo.com/ns/Employee">

< EmpID>101</EmpID>

< Name>Geo Tho</ Name >

< Department>Engineering</Department >

</ Employee>

</content>

</business-event>

', 'R', null, null, '3')

First parameter will be the namespace of the event, second will be business event-definition name from edl file, third being the payload (business event tags are required), and sixth parameter being the priority. Hope this helps.