bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Programming BPM Plug-Ins

Processing Plug-In Events

This section explains how to process plug-in events. It includes the following topics:

- Overview of Plug-In Events

- EventData Class

- Defining the Plug-In Event Handler

- Defining Plug-In Message Types

- Defining an Event Watch Entry

- Sending an Event to the Plug-In Event Handler

Overview of Plug-In Events

An event is an asynchronous notification from another workflow or from an external source, such as another application. You can define an event to start a workflow, initialize variables, activate a node in the workflow, or execute an action. You define events and event properties when defining Start and Event nodes using the WebLogic Integration Studio. For more information about defining events and event properties, refer to Using the WebLogic Integration Studio.

The BPM framework supports event messages in XML format that are delivered via JMS. To support event messages in both XML and non-XML format, you must define a plug-in event.

The following figure illustrates the data flow for plug-in events.

Figure 6-1 Plug-In Event Data Flow

As shown in the previous figure, the plug-in event messages are passed to the system in one of the following two ways:

- JMS eventQueue provided by BPM.

At run time, the event listener listens for events (via the JMS eventQueue) which are received in XML format and delivered using JMS.

For more information about setting up JMS event listeners for the eventQueue, see Establishing JMS Connections in Programming BPM Client Applications.

- onEvent() method of the com.bea.wlpi.server.plugin.PluginManager EJB.

At run time, the Plug-in Manager onEvent() method accepts any data format specified by the plug-in.

The WebLogic Integration process engine stores an incoming plug-in event message as a com.bea.wlpi.server.eventprocessor.EventData object, and passes that object to the Event Processor. For more information about the EventData object, see EventData Class.

Upon receipt of an EventData object, the Event Processor first checks to see if the WLPIPlugin property is defined as part of the message.

The WLPIPlugin message property can be defined in either of the following ways:

- By defining the properties constructor parameter to the com.bea.wlpi.server.eventprocessor.EventData object to include a property named WLPIPlugin, as described in the table EventData Object Constructors.

- By defining a JMS message property named WLPIPlugin, as described in "Setting Message Property Fields" in "Developing a WebLogic JMS Application" in Programming WebLogic JMS, at the following URL:

http://e-docs.bea.com/wls/docs70/jms/implement.html

If the WLPIPlugin property is defined, the Event Processor pre-processes the plug-in event data by passing the EventData object to the plug-in event handler. The pre-processed event data is returned to the Event Processor as an array of EventData objects. For more information about defining the plug-in event handler, see Defining the Plug-In Event Handler.

Next, the Event Processor checks to see if the resulting data is in XML format, and, if so, performs the following steps:

1. Parses the event data.

   At this time, the Event Processor retrieves the content type and event descriptor supplied by the EventData object.

   The content type refers to the MIME (Multi-Purpose Internet Mail Exensions) content type, and describes the basic data type of the message. The content type defaults to text/xml, indicating that the data is in text format and obeys the rules of XML.

   The event descriptor provides a precise definition of the data format, and is interpreted in the context of the content type.

   For example, if the content type is set to text/xml, the event descriptor is the XML document type. If the DOCTYPE tag is set, the XML document type is the public ID or system ID, if defined, or the document element name. If, on the other hand, the content type is set to application/x-java-object (specifying a serialized Java object), the event descriptor is the fully-qualified Java class name.

2. Retrieves the event key value, if specified, and compares it to the pre-defined event keys in JNDI.

   An event key specifies the incoming data field that should be treated as the primary key, and is associated with a particular content type and event descriptor. An event key provides a filtering mechanism for incoming event data to improve performance. For more information about defining event keys, see Using the WebLogic Integration Studio.

   Note: If a plug-in Event or Start node uses the activateEvent() method or the postStartWatch() method, respectively, to the com.bea.wlpi.server.plugin.EventContext interface, and passes a content type other than text/xml, it is the plug-in's responsibility to ensure that a matching event key expression is registered in the event key table. This can be accomplished using the addEventKey() method to the com.bea.wlpi.server.admin.Admin interface. The plug-in should also provide a plug-in field to evaluate a key value from incoming data of this content type and format. For more information about defining a plug-in field, see Defining the Run-Time Component Class for a Message Type.

3. Searches the event watch table for possible candidates to receive the event content based on the content type, event descriptor, and event key value.

   For more information about how plug-in events are added as entries to the event watch table, see Defining an Event Watch Entry.

4. Evaluates the condition, if specified, and determines if there is a successful match.

   A condition consists of an expression that evaluates to true or false. A condition enables users to define multiple workflows for the same event data that they want to process differently, based on the content of the message. For example, the following provides a valid condition if the event data contains a field called Order Amount: "Order Amount > $500.00". For more information about defining conditions, see Using the WebLogic Integration Studio.

5. In the event of a match, triggers the event to either start a new instance of a workflow or resume processing of an existing workflow instance.

Each of these tasks are performed for each consumer subscribed to the event.

To support plug-in events, you must perform the following steps:

1. Define the plug-in event handler to handle plug-in event data.

2. Define the custom message types, or plug-in fields, to parse the event data returned by the event handler.

3. Define the event watch entry.

The following sections describe each of these steps in detail, and explain how to send a message to the plug-in event handler.

Before you can create an event handler, you need to understand how to create and access information about the EventData container class, which stores the incoming plug-in event message.

EventData Class

As shown in the figure Plug-In Event Data Flow, the com.bea.wlpi.server.eventprocessor.EventData object provides the container class for incoming data messages.

The following table defines the constructors that can be used to create an EventData object.

Table 6-1 EventData Object Constructors

Constructor | Description
--- | ---
public EventData(org.w3c.dom.Document document) | Constructs an EventData object from a pre-parsed DOM object containing XML, and sets the following values: Content type to CONTENT_TYPE_DOM. Event descriptor to the DOCTYPE public or system ID, if defined, or the document element name. The constructor parameter is defined as follows. document: org.w3c.dom.Document object that specifies the XML content.
public EventData(java.lang.String xml) throws com.bea.wlpi.common.WorkflowException | Constructs an EventData object from a String object containing XML, and sets the following values: Content type to CONTENT_TYPE_XML. Event descriptor to the DOCTYPE public or system ID, if defined, or the document element name. The constructor parameter is defined as follows. xml: java.lang.String object that specifies the XML content.
public EventData( java.lang.Object content, java.lang.String contentType, java.lang.String eventDescriptor, long expiration, java.lang.String[] templateNames, java.lang.String[] instanceIDs, java.util.Map properties) | Constructs an EventData object containing an object of any type. The constructor parameters are defined as follows: content: java.lang.Object object that specifies the content. contentType: java.lang.String object that specifies the content type. eventDescriptor: java.lang.String object that specifies the event descriptor. expiration: Long value that specifies the expiration. templateNames: Array of java.lang.String objects that specify the names to which the event data should be delivered, or null. instanceIDs: java.lang.String objects that specify the IDs of the workflow instances to which the event data should be delivered, or null. properties: java.util.Map object that specifies a map of custom message properties. For example, you may want to define any of the following custom message properties: - WLPIContentType: Content type. - WLPIEventDescriptor: Event descriptor. - WLPIPlugin: Plug-in name. Note: The EventData object also provides the CONTENT_TYPE, EVENT_DESCRIPTOR, and PLUGIN constant values that define the content type, event descriptor, and plug-in name, respectively. If templateNames or instanceIDs are non-null, the event data is considered to be addressed.
public EventData( java.lang.Object content, java.lang.String contentType, java.lang.String eventDescriptor, java.lang.String startInstanceID, java.util.Map properties) | Constructs an EventData object containing an object of any type. The constructor parameters are defined as follows: content: java.lang.Object object that specifies the content. contentType: java.lang.String object that specifies the content type. eventDescriptor: java.lang.String object that specifies the event descriptor. startInstanceID: java.lang.String object that specifies the ID of the starting workflow instance to which the event data should be delivered, or null. properties: java.util.Map object that specifies a map of custom message properties. For example, you may want to define any of the following custom message properties: - WLPIContentType: Content type. - WLPIEventDescriptor: Event descriptor. - WLPIPlugin: Plug-in name. Note: The EventData object also provides the CONTENT_TYPE, EVENT_DESCRIPTOR, and PLUGIN constant values that define the content type, event descriptor, and plug-in name, respectively.

The following table describes the EventData object information, the constructor parameters used to define the information, and the methods that can be used to access that information after the object is defined, if applicable.

Table 6-2 EventData Object Information

Object Information | Constructor Parameter | Get Method
--- | --- | ---
org.w3c.dom.Document document (DOM) containing the XML content. | document | public final boolean isDOM()
String document containing the XML content. | xml | public final boolean isXML()
java.lang.Object object containing the event data content. | content | public final java.lang.Object getContent()
Content type. | contentType | public final java.lang.String getContentType()
Event descriptor. | eventDescriptor | public final java.lang.String getEventDescriptor()
Expiration. | expiration | public final long getExpiration()
Array of template names to which the event data is addressed. | templateNames | public final String[] getTemplateNames()
Array of workflow instance IDs to which the event data is addressed. | instanceIDs | public final java.lang.String[] getInstanceIDs()
Start workflow instance ID to which the event data is addressed. | instanceIDs | public final java.lang.String getStartInstanceID()
Plug-in message properties. | properties | public java.lang.Object getProperty(java.lang.String propertyName) throws com.bea.wlpi.common.WorkflowException public java.util.Set getPropertyNames() throws com.bea.wlpi.common.WorkflowException
Unique message identifier assigned by the Event Processor. Note: This method only applies to addressed messages. If the event message data is not addressed, this method returns null. | N/A | public final java.lang.String getMessageID()
Key value of the event data. The Event Processor sets the key value if a key value expression is defined for the content type and event descriptor combination. | N/A | public final java.lang.String getKeyValue()

The following table lists the methods that can be used to parse the XML data.

Table 6-3 XML Parsing Methods

Method | Description
--- | ---
public final void parseXML(boolean validate) throws com.bea.wlpi.common.WorkflowException | Parses contents of the event data into an org.w3c.dom.Document document (DOM) if the content is XML, and sets the following values: Content type to #CONTENT_TYPE_DOM. Event descriptor to the DOCTYPE public or system ID, if defined, or the document element name. The method parameter is defined as follows. validate: True if the XML should be validated against the referenced DTD.
public final void parseXML() throws com.bea.wlpi.common.WorkflowException | Parses contents of the event data into an org.w3c.dom.Document object if the content is XML, and sets the following values: Content type to #CONTENT_TYPE_DOM. Event descriptor to the DOCTYPE public or system ID, if defined, or the document element name. The XML is not validated.

The following section explains how to define the plug-in event handler to pre-process the incoming EventData object.

Defining the Plug-In Event Handler

As shown in the figure Plug-In Event Data Flow, you must define the plug-in event handler to pre-process plug-in event data, and enable the Event Processor to parse the data.

To define the plug-in event handler, you must perform the following tasks.

1. Define the execution handler component class.

2. Define a com.bea.wlpi.server.plugin.EventHandlerInfo value object, passing the name of the event handler object defined in step 1 as an argument to the constructor.

3. Register the event handler by passing the EventHandlerInfo object defined in step 2 as a constructor parameter to the plug-in PluginCapabilitiesInfo object.

The following sections describe each of these steps in more detail.

Defining the Event Handler Component Class

To define a plug-in event handler component class, implement the com.bea.wlpi.server.plugin.EventHandler interface.

The following table defines the EventHandler interface method that you must implement to pre-process the incoming plug-in event data.

Table 6-4 EventHandler Interface Method

Method | Description
--- | ---
public com.bea.wlpi.server.eventprocessor.EventData[] onEvent(com.bea.wlpi.server.eventprocessor.EventData eventData) throws com.bea.wlpi.common.plugin.PluginException | Pre-processes incoming plug-in event data. The Event Processor calls this method upon receipt of an event message (usually via JMS) that is addressed to a specific plug-in. An event handler can translate a single incoming event into multiple outgoing events to be handled sequentially by the Event Processor. The method parameter is defined as follows. eventData: com.bea.wlpi.server.eventprocessor.EventData object that specifies the plug-in event data. This method returns one of the following values: One or more EventData objects containing the converted event data, with the appropriate content type and attributes set. Null, if the event handler fully processes the incoming plug-in event data, and no further processing is required by the Event Processor.

Creating an Event Handler Value Object

To create an event handler value object, com.bea.wlpi.common.plugin.EventHandlerInfo, use the constructor defined in EventHandlerInfo Object. You must pass the name of the event handler component class, defined in the previous section, as the classNames constructor parameter value.

For example, the following code excerpt creates a new event handler value object, passing the name of the event handler class, sample.MyEventHandler. The event handler class implements the EventHandler com.bea.wlpi.server.plugin.EventHandler interface, as described in Defining the Event Handler Component Class.

>     eh = new EventHandlerInfo(SamplePluginConstants.PLUGIN_NAME,
>             bundle.getString("startOrderName"),
>             bundle.getString("startOrderDesc")
>             sample.MyEventHandler);
>     eventHandler = new EventHandlerInfo[]{ eh };

For more information about the EventHandlerInfo object, see EventHandlerInfo Object.

Registering an Event Handler

To register the event handler, create a com.bea.wlpi.common.plugin.PluginCapabilitiesInfo value object, as defined in PluginCapabilitiesInfo Object, and pass the EventHandlerInfo object (defined in the previous section) as the eventHandler constructor parameter value.

For example, the following code excerpt creates a new PluginCapabilitiesInfo value object, passing the name of the com.bea.wlpi.common.plugin.EventHandlerInfo object as an argument.

>     PluginCapabilitiesInfo pci = new PluginCapabilitiesInfo(pi,
>             getCategoryInfo(bundle), eventInfo, fieldInfo, functionInfo,
>           startInfo, null, null, null, null, eventHandler);

For more information about the PluginCapabilitiesInfo object, see PluginCapabilitiesInfo Object.

Defining Plug-In Message Types

You must define plug-in message types, or plug-in fields, to enable the process engine to extract information from the plug-in com.bea.wlpi.server.eventprocessor.EventData objects. The extracted values can be assigned to workflow variables or used as part of an expression, such as in key value or conditional expressions.

For more information about defining plug-in message types, see Defining the Run-Time Component Class for a Message Type.

Defining an Event Watch Entry

An event watch entry enables the Event Processor to match an incoming event to the plug-in node.

The following table describes how the process engine adds plug-in event entries to the event watch table for each plug-in node type.

Table 6-5 How Event Watch Entries Are Added Based on Plug-In Node Type

Node Type | Description
--- | ---
Event node | When a workflow processor activates the node, the Plug-in Framework calls the activate() method on the com.bea.wlpi.server.plugin.PluginEvent object. The activate() method records an entry in the event watch table by calling the activateEvent() method on the com.bea.wlpi.server.plugin.EventContext. For more information about implementing the activate() method, see the table PluginEvent Interface Methods. For more information about the EventContext, see Event Context.
Start node | When a user sets a template definition to active, the Plug-in Framework calls the activate() method on the com.bea.wlpi.server.plugin.PluginStart2 object, which in turn calls the setTrigger() method. The setTrigger() method records an entry in the event watch table by calling the postStartWatch() method on the com.bea.wlpi.server.plugin.EventContext. For more information about implementing the setTrigger() method, see the table PluginStart2 Interface Method. For more information about the EventContext, see Event Context.

Sending an Event to the Plug-In Event Handler

To send an event to the plug-in event handler, the message sender must set the com.bea.wlpi.server.eventprocessor.EventData object WLPIPlugin string property to the event handler name.

For example, the following code segment demonstrates how to build a properties map, setting the WLPIPlugin property to the name of the event handler, SamplePlugin, and passing this information to the EventData constructor.

>     Map props = new HashMap();
>     props.put("WLPIPlugin","SamplePlugin");
>     EventData eventData = new EventData(data,
>       "text/x-appplication/sample",
>       "Order", 0, null, null, props);