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 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
Search for a business event oracle.apps.po.rcv.rcvtxn
Click on Subscription icon
and then click on Create Subscription button
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)
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:
-- --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;
-- 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; / --
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
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;
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.
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.
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.
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;
|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.