Basics of Business Events and step by step process to subscribe to a Business Event

Business Event

Business Event is an occurrence of a business activity which has some significance. For example, the activity of creating a purchase order (PO) is a business event, like wise approving PO, receiving goods against a PO, matching a PO receipt with invoice is a Business Event.

Subscription

Subscription is an activity to be performed on occurrence of a Business Event.
Eg:- If you would like to send an email notification to some set of users when a PO receipt is created then you can subscribe to PO Receipt related Business Event and trigger a workflow notification from the subscription to send email.

How is Business Event Raised?

Usually seeded Business Events are raise by workflows or Forms through a PL/SQL code.

Oracle not only provides an option to create custom subscriptions to seeded Business Event s but also provides a flexibility to create a complete custom Business Event.

Steps to Subscribe to a Business Event

In this article I will show you how to subscribe to PO Receipt standard business event (oracle.apps.po.rcv.rcvtxn). Our subscription would just insert the seeded business event details into a custom temporary table.

Navigate to “Workflow Administrator Web (New)” responsibility –> Administrator Workflow –> Business Events

1.Business Events Navigation

Search for a business event oracle.apps.po.rcv.rcvtxn

2.Search Business Event

Click on Subscription icon

3.Business Event Subscription

and then click on Create Subscription button

4.Business Event Create Subscription

In Create Subscription page enter the following details and save the page:
System: < choose your system name from LOV >
Phase: 101 (enter some number greater than 100)
Status: Enabled
Rule Data: Message
Action Type: Custom
On Error: Stop and Rollback
PL/SQL Rule Function: xx_be_test_pkg.xx_insert (we will create this package and procedure in next step)
Priority: Normal
Owner Name: (enter your custom application short name)
Owner Tag: (enter your custom application short name)

5.Business Event Create Subscription

6.Business Event Create Subscription

Execution Condition: PHASE

If you want to execute the business event subscription on sync with workflow activity then you need to select phase below 100 OR else enter phase more than 100 if you want to execute business event subscription after completion of workflow business activity i.e, asynchronously.

Below is the code block related to the package mentioned in the above example:

Table Definition

--
--drop table xx_be_debug_log_tmp;
--
CREATE TABLE xx_be_debug_log_tmp
  (
    id         NUMBER,
    text       VARCHAR2(4000),
    time_stamp DATE DEFAULT SYSDATE
  );
--
--DROP SEQUENCE apps.xx_be_debug_log_tmp_seq;
--
CREATE SEQUENCE apps.xx_be_debug_log_tmp_seq 
START WITH 1 
MAXVALUE 999999999999999999999999999 
MINVALUE 1 
NOCYCLE 
NOCACHE 
NOORDER;
--
--DROP TRIGGER xx_be_debug_log_tmp_t1;
--
CREATE OR REPLACE TRIGGER xx_be_debug_log_tmp_t1 BEFORE
   INSERT ON xx_be_debug_log_tmp FOR EACH ROW BEGIN IF :NEW.id IS NULL THEN
   SELECT xx_be_debug_log_tmp_seq.nextval INTO :NEW.id FROM dual;
END IF;
END;
/  
SHOW ERRORS;
EXIT;

Package Specification

--
CREATE OR REPLACE PACKAGE xx_be_test_pkg
AS
   FUNCTION xx_insert (p_subscription_guid IN RAW, p_event IN OUT wf_event_t)
      RETURN VARCHAR2;
END xx_be_test_pkg;
/
--

Package Body

CREATE OR REPLACE PACKAGE BODY xx_be_test_pkg
AS
   FUNCTION xx_insert (p_subscription_guid IN RAW, p_event IN OUT wf_event_t)
      RETURN VARCHAR2
   IS
--
      l_param_list    wf_parameter_list_t;
      l_param_name    VARCHAR2 (240);
      l_param_value   VARCHAR2 (2000);
      l_event_name    VARCHAR2 (2000);
      l_event_key     VARCHAR2 (2000);
	  l_event_data    VARCHAR2 (4000);
--
   BEGIN
--
      l_param_list := p_event.getparameterlist;
      l_event_name := p_event.geteventname ();
      l_event_key  := p_event.geteventkey ();
      l_event_data := p_event.geteventdata ();
 
--
      INSERT INTO xx_be_debug_log_tmp
                  (text
                  )
           VALUES ('EVENT NAME: ' || l_event_name
                  );
      --
      --
      INSERT INTO xx_be_debug_log_tmp
                  (text
                  )
           VALUES ('EVENT KEY: ' || l_event_key
                  );
      --
      --
      INSERT INTO xx_be_debug_log_tmp
                  (text
                  )
           VALUES ('EVENT DATA: ' || l_event_data
                  );				  
 
      IF l_param_list IS NOT NULL
      THEN
         FOR i IN l_param_list.FIRST .. l_param_list.LAST
         LOOP
            --
            l_param_name := l_param_list (i).getname;
            l_param_value := l_param_list (i).getvalue;
 
            --
            INSERT INTO xx_be_debug_log_tmp
                        (text
                        )
                 VALUES (l_param_name || ': ' || l_param_value
                        );
 
            COMMIT;
         --
         END LOOP;
      END IF;
 
      COMMIT;
      RETURN 'SUCCESS';
   --
   --
   EXCEPTION
      WHEN OTHERS
      THEN
         --
         --Provide context information that helps locate the source of an error.
         --
         wf_core.CONTEXT (pkg_name       => 'XX_BE_TEST_PKG',
                          proc_name      => 'XX_INSERT',
                          arg1           => p_event.geteventname (),
                          arg2           => p_event.geteventkey (),
                          arg3           => p_subscription_guid
                         );
         --
         --Retrieves error information from the error stack and sets it into the event message.
         --
         wf_event.seterrorinfo (p_event => p_event, p_type => 'ERROR');
         --
         RETURN 'ERROR';
   --
   END xx_insert;
END xx_be_test_pkg;

Compile the above package and Restart Workflow Agent Listener service as shown in the below screen shot

Restart - Workflow Agent Listener Service

More about the package

When the Event Manager calls the rule function, it passes two parameters to the function and expects a return code when the function completes. The parameters are defined here:

p_subscription_ guid
– The globally unique identifier for the subscription.
p_event – The event message with which we can access Event Key, Event Name, Event Data and Parameters. Every seeded business event has some parameters which we can access through p_event parameter.

The function must return one of the three status codes: SUCCESS or WARNING or ERROR.

Create PO Receipt Transaction to raise Business Event

Create a PO Receipt transaction so that the business event oracle.apps.po.rcv.rcvtxn will get raised the custom subscription we created will get executed.

After creating PO Receipt transaction wait for a minute and query for the custom table which we have mentioned in the package.

SELECT * FROM xx_be_debug_log_tmp;

7.Business Event Log

Event Key

A string that uniquely identifies an instance of an event. Together, the event name, event key, and event data fully communicate what occurred in the event.

Event Data

A set of additional details describing an event. The event data can be structured as an XML document. Together, the event name, event key, and event data fully communicate what occurred in the event.

Event Message

A standard Workflow structure for communicating business events, defined by the datatype WF_EVENT_T. The event message contains the event data as well as several header properties, including the event name, event key, addressing attributes, and error information.

Event Activity

A business event modeled as an activity so that it can be included in a workflow process.

To know if the business event is fired or not query for WF_DEFERRED queue table if the subscription is using PL/SQL procedure or else use WF_JAVA_DEFERRED queue table if the subscription is using Java procedure.

SELECT substr(wfd.corrid,1,40) corrid,
decode(wfd.state,
0, '0 = Ready',
1, '1 = Delayed',
2, '2 = Retained',
3, '3 = Exception',
to_char(substr(wfd.state,1,12))) State,
COUNT(*) COUNT
FROM applsys.wf_deferred wfd
GROUP BY wfd.corrid, wfd.state;
Status Meaning
Ready Activity is ready to be processed
Delayed Activity will be processed later
Retained Activity was already processed
Exception Activity had an error

Note: Make sure Workflow Background Process is running in the background.

In this way we can use business events in many ways to solve business requirements.