Business Events in Action

The purpose of this blog post is to explore subscription consistency levels. Subscriber can use any of the following consistency levels while subscribing to business events raised by publisher:

immediate

guaranteed

one and only one

Following is an extract from documentation explaining the functionality of each consistency level:

immediate – Events are delivered to the subscriber in the same global transaction and same thread as the publisher. The publish call does not return until all immediate subscribers have completed processing. If any subscribers throw an exception, no additional subscribers are invoked and an exception is thrown to publisher. The transaction is rolled back in case of any error during immediate processing

guaranteed – Events are delivered to the subscriber asynchronously without a global transaction. The subscriber can choose to create its own local transaction for processing, but it is committed independently of the rest of event processing. In addition, EDN does not attempt to resend an event (regardless of the backing store being AQ or JMS). If one or more subscribers fail to consume the event (while others succeed), those subscribers lose the message.

one and only one – Events are delivered to the subscriber in its own global (that is, JTA) transaction. Any changes made by the subscriber within that transaction are committed after the event processing is complete. If the subscriber fails, the transaction is rolled back. Failed events are retried a configured number of times.

This document shows you business events in action from the perspective of above highlighted points and might help you in choosing the right consistency level depending on the scenario.

Assumptions:

Using EDN-DB, though observations noted here will not vary when used EDN-JMS.

No clustered environment.

Use case:

A mediator raises 2 business events CreateOrder and UpdateOrder. For CreateOrder , we have the following subscribers:

Mediator routing the request to ASync BPEL (within same composite)

Mediator routing the request to Sync BPEL (within same composite)

Asynchronous BPEL process (within same composite)

Mediator throws exception while routing the request to Asynchronous BPEL (in different composite)

For UpdateOrder, we have the following subscribers:

Mediator routing the request to Asynchronous BPEL (in different composite)

We will observe the behavior in different scenarios by modifying event subscription consistency levels for above subscribers. The exception during the mediator routing is simulated by adding <onReply/> tag which is not needed in actual when routing to Async BPEL process. Example is shown below:

<switch>

<case executionType="direct"

name="Order2BPELProcess1.order2bpelprocess1_client.process">

<action>

<transform>

<part name="$out.payload"

function="xslt(xsl/CreateOrder_To_process.xsl, $in.payload)"/>

</transform>

<invoke reference="Order2BPELProcess1.order2bpelprocess1_client"

operation="process">

<onReply/>

</invoke>

</action>

</case>

</switch>

Configuration:

The retry configuration for one and only one subscribed events and the other EDN configuration can be set in EM console by navigating to soa-infra -> Administration -> System MBean Browser -> Application Defined MBeans -> oracle.as.soainfra.config -> EDN Config -> edn. This will bring up the following screen showing the default parameters.

Demonstration:

To start with, have a look at the list of events being used and it’s subscriptions below:

Consistency Level – immediate:

Modify all the event subscriptions to immediate consistency level.

Now raise the CreateOrder event and observe flow trace shown below. Since consistency level is immediate and the exception is thrown by one of the subscribers not all of the subscribers have received the event at all. And also no retry happened in case of faulted subscriber.

Also we can’t find this event in event recovery console which is shown below:

To confirm the above observed behavior, now modify the consistency level of few of the events to either guaranteed or one and only one.

Now again raise the CreateOrder event and observe flow trace shown below. We don’t see any change in behavior from previous iteration. So if an exception is thrown by any one of the immediate consistency level subscribers, then remaining subscribers will not get the event at all irrespective of their subscription consistency levels. And also we would see the exception thrown back while executing from EM console.

Consistency Level – guaranteed:

Modify all the event subscriptions to guaranteed consistency level.

Now raise the CreateOrder event and observe flow trace shown below. Since consistency level is guaranteed all the subscribers have received the event though one of the subscriber is faulted. And no fault is thrown back while testing from EM console as we saw in ‘immediate’ . Also no retry happened in case of faulted subscriber and the event is lost for that subscriber.

Also we can’t find this event in event recovery console which is shown below:

Consistency Level – one and only one:

Modify all the event subscriptions to one and only one consistency level.

Now raise the CreateOrder event and observe flow trace shown below. Since consistency level is ‘one and only one’ all the subscribers have received the event though one of the subscriber is faulted. And no fault is thrown back while testing from EM console as we saw in ‘immediate’ . Also retry happened thrice in case of faulted subscriber as we configured the NumberOfRetrys property to 3 (see Configuration section).

If event delivery is failed even after the configured number of retries that event will be marked for Recovery and will be shown in Faults section of Business Events screen in EM console as shown below. Use ‘Retry’ button to recover the event delivery or use ‘Abort’ button to discard.

Other Observations:

Scenario 1:Mediator routes the request to Sync BPEL which throws fault and not caught, then event retry is happening irrespective of the value set for property bpel.config.transaction.

Scenario 2:Mediator routes the request to ASync BPEL which throws fault and not caught, then event retry is not happened as expected, as the fault in Async BPEL process will not propagated back unless we do it by explicit callback and bpel.config.transaction is irrelevant in this case and the value of property bpel.config.oneWayDeliveryPolicy is set to async.persist.

Scenario 3:Mediator routes the request to ASync BPEL which throws fault and not caught having the value of property bpel.config.oneWayDeliveryPolicy is set to sync. As expected, the event retry happened in this case.

The same behavior isobserved, when BPEL is subscribed to event (no mediator in between) and the value of property bpel.config.oneWayDeliveryPolicy is set to sync.

Scenario 4:Event is published and one of the subscribers is not active. In this case, non-active subscriber will loose event and no event delivery happens even after bringing up the subscriber. We will simulate this case using by doing shutdown of another composite. In the below screenshot, we could see that event is not delivered to 6th subscriber as the composite is down and the flow trace will not change even after bringing up the composite.

This is due to fact that list of subscriptions no longer has this entry as shown below, so one should think about this type of possibility in real time use cases and have contingency plan in place for such cases.

I too observed this behavior and i think that’s expected in 11g as we don’t have concept of durability for the subscribers..did you check corrsponding EDN OAOO table if any pending msgs are seen? otherwise it has to be built into the application something similar to error queue and this the case if it needs redeployment..