Creating Event Handlers

An event handler is the application-specific code that responds to a particular type of event. You must register event handlers to events so that when an event is raised, the Event Manager framework executes the appropriate event handlers.

Requirements for Creating Event Handlers

To be compatible with the Event Manager framework, when creating event handlers, you must implement all business logic for the event handlers to abide by the following set of standards and code requirements:

  • You must implement the entry point to the event handler in a method named ProcessEvent() within an application class.

    The Event Manager framework executes the ProcessEvent() method whenever the associated event is raised. Within the ProcessEvent() method, you are free to reference or execute code in other methods, classes, or function libraries. This application class can be an extension of any other application class if necessary.

  • You can create the event handler in any new or existing application package within your application, but you must create the event handler under the Handlers subpackage.

  • The application class and the application package that it resides in must be owned by the application, not the Event Manager framework.

  • You must import the baseEvent class definition from the Event Manager framework application package into the application class that implements the event handler.

    The ProcessEvent() method in the application class of the event handler receives as an input parameter an instance of this baseEvent class object.

  • If you want to be able to communicate detailed errors, warnings, or any other messages back to the Event Manager framework, then you must populate the HandlerStatus property with appropriate entries.

    The HandlerStatus property is a complex property that is part of the baseEvent object that the Event Manager framework makes available to the event handler. The structure of this property is defined by EOEN_EVENT_MANAGER:Base:baseEvent. The property contains both an overall status indicator and an exception array. The Event Manager framework examines the contents of this property after executing this class and takes appropriate action.

    The HandlerStatus complex type also carries a method that facilitates appending an entry to the ExceptionArray structure. This method is named AddException() and takes as an argument the structure defined by EOEN_EVENT_MANAGER:Base:Types:ExceptionType.

    Note: If event logging is enabled, the Event Manager framework automatically creates an exception entry that lists the event data that was made available to the event handler. The system displays the event data in the pages of the Event Monitor component. If event logging is not enabled in the registry an exception entry containing the data for the event is created only if the Handler ExecutionStatus is set to F (Fail). This is done to allow re-processing of the event from the Event Monitor.

    The structure within the HandlerStatus property is:

    • ExecutionStatus (string – values "S"uccess, "F"ail)

    • ExceptionArray (array):

      EXCEPTION_TYPE (string – values "E"xception, "K"eys, "T"race)

      MESSAGE_SET_NBR (number)

      MESSAGE_NBR (number)

      MSG_SEVERITY (string – values "M"essage, "W"arning, "E"rror)

      MESSAGE_TEXT (string)

      EXPLAIN_TEXT (string)

Details of the baseEvent Class

When the Event Manager framework invokes the baseEvent class, it passes the baseEvent class into the ProcessEvent() method of the application class of the event handler. This enables you to use the properties and methods of the base class to obtain more information about the event instance to direct internal processing of the event.

This table lists public properties of the event object that are of interest to application developers who are implementing the Event Manager framework:

Public Properties

Description

EventName

A string that is populated with the name (type) of the event instance. Examples are "AssignmentTerminated", "PersonAdded", and so on. If you are registering the same event handler to multiple events but these events have slightly different logic depending upon the exact event that is being processed, you can use this property to control your processing.

EventID

A numeric that is populated with the unique serial number that identifies this event instance for an originating node. Generally, event handlers do not have any need for this property. The event handler uses this property primarily inside the framework for audit and monitoring purposes.

ContextRecord

The context record associated with the event.

HasContextRecord

A Boolean set to True if the raised event has a context record.

IsLocal

A Boolean set to True if the event was raised by an activity in the local database. (The term local is relative to the domain in which the event handler code is executing).

EventNode

A string that is populated with the node name of the database in which the activity that raised the event occurred.

HandlerTraceEnabled

A Boolean that indicates whether the user wants the current event handler to create trace and debug information in the event handler log.

EventLoggingEnabled

A Boolean that indicates whether the user wants the current event to create event logging information in the event log.

Must be set to true if Event Handler logging is desired.

HandlerLoggingSwitch

A Boolean that indicates whether the user wants the current event handler to create event handler log information in the event log.

Event Handler Skeleton Code

You can use the following skeleton code as a starting point when building an event handler class:

import EOEN_EVENT_MANAGER:Base:baseEvent;
import EOEN_EVENT_MANAGER:Base:Types:ExceptionType;

class MyHandlerClass
   /** Dummy Constructor. */
   method MyHandlerClass();
   /** Process Event. */
   method ProcessEvent(&inEvent As EOEN_EVENT_MANAGER:Base:baseEvent);
end-class;

method MyHandlerClass
end-method;

method ProcessEvent
   /+ &inEvent as EOEN_EVENT_MANAGER:Base:baseEvent +/
   
   Local Record &recContext;
 
/* the following lines are required only if you want to pass detail information
    about Errors, Warnings  or other messages back to the Event Framework */
  Local EOEN_EVENT_MANAGER:Base:Types:ExceptionType &myExceptionType = 
  create EOEN_EVENT_MANAGER:Base:Types:ExceptionType();
   
   
   If Not &inEvent.HasContextRecord Then
      &myExceptionType.MESSAGE_SET_NBR = 18137;
      &myExceptionType.MESSAGE_NBR = 6509;
      &myExceptionType.MSG_SEVERITY = "E";
      &myExceptionType.MESSAGE_TEXT = MsgGetText(18137, 6509, 
      "no message found", &inEvent.EventID, &inEvent.EventNode);
      &myExceptionType.EXPLAIN_TEXT = "";
      &inEvent.HandlerStatus.AddException(&myExceptionType);
      
   Else 
/*================================================================= */
/* ----------------   Business Logic goes here ------------------*/
/*================================================================= */
   End-If;
end-method;

Addressing Errors and Warnings

During execution, an event handler might encounter errors, warnings, or other issues that a user needs to be made aware of. In most cases, you want to pass this information back to the Event Manager framework so that users can view the information through the Monitor Events component. Although you do not have to pass this information back to the Event Manager framework, the more information that you do pass back, the easier it is for the administrator to resolve the problem.

The Event Manager framework uses a simple exception-array scheme to receive status information that is passed back to it from an event handler and subsequently displays that information in the Monitor Events component. The structure of the exception array is the same as the structure of a message in the message catalog. It contains a message set number, message number, severity level, message text, and explanation text in each row of the array. The message set number and message number are significant only if the information that you want to pass back to the Event Manager framework is described in a Message Catalog entry. If not, you can leave these two properties blank and just populate the message text, explanation text, and severity properties.

As mentioned previously, the event object that is passed into your event handler contains a complex property that is used to communicate the status of your event handler. At a minimum, you should populate the overall-status simple property with either (S)uccess or (F)ail prior to quitting your ProcessEvent() method. If you do not populate the overall status property, the Event Manager framework assumes that the event handler executed successfully. PeopleSoft recommends that you pass back information through the exception array of the complex property, although this is optional. For example, if the event object is passed into your handler as &inEvent, you populate the overall status property as:

&inEvent.HandlerStatus.ExecutionStatus = "S";
     /* Handler terminated successfully */

You never have to deal directly with the exception array that is embedded in the event object that the event handler receives. Instead, whenever you want to add an item to this array, you call the AddException() method, thus passing in an object that the system has already populated with exception information. This object that you pass in is an instance of the ExceptionType TypeClass. This class has the following properties:

  • Message Set Number

  • Message Number

  • Message Severity

  • Message Text

  • Explain (Long) Text

The following example shows how to add a message to the exception array for a message that does not come from the Message catalog, assuming that the event object is passed into your event handler as &inEvent:

&myExceptionType = create EOEN_EVENT_MANAGER:Base:Types:ExceptionType();
&myExceptionEntry.MESSAGE_SET_NBR = 0;
&myExceptionEntry.MESSAGE_NBR = 0;
&myExceptionEntry.MSG_SEVERITY = "M";
&myExceptionEntry.MESSAGE_TEXT = "Hello World!";
&myExceptionEntry.EXPLAIN_TEXT = "";

&inEvent.HandlerStatus.AddException(&myExceptionType);

For a Message Catalog entry, you must include the message set number and the message number. You must also retrieve the text and explain text from the Message Catalog because substitution tokens might be involved that the Event Monitor framework cannot pass or resolve.

Note: If you use the AddException() method to create an exception array entry with the MSG_SEVERITY property set to (E)rror, then the system automatically sets the overall execution status indicator for the event handler to (F)ail. This means that you do not need to separately set the overall status property.

Note: The Event Manager framework executes all event handlers that you register to an event. If a particular event handler fails, the Event Manager framework still executes the remaining event handlers that are registered to the event. The Event Manager framework can catch exceptions that an event handler raises rather than terminating before it has finished executing all of the registered event handlers. However, the Event Manger framework does not contain any exception processing or error handling subsystems, and because of this you must ensure that event handler code does not raise an exception that the Event Manager framework cannot catch. One such exception is the PeopleCode error statement. Therefore, you must never raise an exception for an error statement in your event handler. Otherwise, the Event Manager framework stops and does not execute any remaining event handlers that are registered to the event.

Component Interface and SOA Service Exceptions

If you have PeopleSoft Human Resources two additional exception methods are available: Component Interfaces (CIs) and Service Oriented Architecture (SOA) services. The Event Manager framework therefore provides assistance to facilitate passing exceptions from these sources back to the Event Manager framework and ultimately into the Event Monitor component.

The system displays exceptions that are raised by CIs or SOA services on the Handler Exceptions page of the Event Monitor component, much like any other exceptions that are written to the log. For severity information, the system prefaces the message with “[CI] ” or “[SOA]”, respectively.

The structure of the event-handler exception log is similar to the exception structure within PeopleTools for CIs and within the SOA framework for SOA services. Essentially, you must pass these exceptions back to the Event Manager framework when they arise. Two methods are available within the Event Manager framework that enable you to do this easily. One method is:

HandlerStatus.AddCIException(&arrExceptions as array of Record, &Severity as 
string)

This method copies all exceptions from a standard CI exception array to the exception log of the event handler according to the specified severity of the exception. Severity codes are (E)rror, (W)arning, and (M)essage.

You can specify multiple severity codes by concatenation. Thus, if you want to copy both errors and warnings, then specify a severity code of EW. A blank severity code causes the copying of all exceptions regardless of severity.

The structure of the exception array that is passed into this method is identical to the exception array that the FUNCLIB_CI version of the standard HCM CI wrapper uses. This is an array of Record.CI_EXCEPTIONS. If you're using the FUNCLIB_CI wrapper, you can pass the exception array that you use with those functions into this method.

If you are calling a CI directly, then you need to first ensure that you have instructed PeopleTools to redirect CI exceptions from the screen to the %Session.PSMessages object. Then, you need to copy the items from PSMessages into an array of Record.CI_EXCEPTIONS so that these exceptions can be passed into this method.

Another method is:

HandlerStatus.AddSOAException(&inException As 
HMCR_TYPES:ExceptionTypes:ExceptionType_v1_0:ExceptionType)

This method copies all exceptions from a standard SOA exception type structure to the exception log of the event handler.

When invoking SOA services, the system always executes them in a try/catch block. Typically, the event handler executes the services and catches certain defined exceptions that arise. A catch-all exception always catches any exceptions that have not been specifically called out.

SOA exceptions differ slightly from CI exceptions in that when invoking an SOA service, you manage only one (if any) exception. The exception that you pass into this method is the exception structure that you catch in your try/catch block.

The following example shows an SOA service invocation passing exceptions back to the Event Manager:

     *     try
     *        &MyService.MyServiceManager.LocateService(&ServiceName); 
     *        &MyService.DoService();
     *          catch <NamedException1> &e1
     *                &myEvent.HandlerStatus.AddSOAException(&e1.ServiceException);
     *                --- other exception processing ---
     *          catch <NamedException2> &e2
     *                &myEvent. HandlerStatus.AddSOAException(&e2.Service
                      Exception);
     *                --- other exception processing ---
     *          . . .
     *          catch HMCR_FRAMEWORK:ServiceFramework:baseClasses:baseException
                &e0    
     *                &myEvent. HandlerStatus.AddSOAException(&e0.Service
                      Exception);
     *                --- other exception processing ---
     *      end-try 

In this code, the items appearing as <NamedExceptionX> represent the application-specific exceptions that are registered in the SOA registry. These are exceptions that are known to be thrown by the indicated SOA service. The class named HMCR_FRAMEWORK:ServiceFramework:baseClasses:baseException is for the catch-all exception, defining the shape of the generic SOA exception.

Providing Trace/Debug Information

The Registered Handlers page of the Event Registry component provides a Trace check box to indicate whether to write trace/debug information to the execution log of the event handler. This functionality is available only when you set the Logging field for the event handler to the All value.

When you select the Trace check box, the event handler produces trace/debug in the handler execution log. The amount of trace/debug information that the system writes to the log is determined by the developer of the event handler. Generally, you must provide enough information so that anyone examining the event handler log can trace the path of the execution that the event handler has taken.

The system makes the selected value of this check box available to the event handler using the HandlerTraceEnabled Boolean property of the event. When this property is True, the event handler creates trace/debug entries in the exceptions structure. PeopleSoft software provides the following method to make the creation of these entries easier:

&myEvent.HandlerStatus.AddTraceEntry(&Heading, &Detail);

In the preceding code, &Heading is the string that appears as the first line of the entry, and &Detail is a long string containing whatever detailed trace/debug information you want to create.

The system displays the trace/debug information in the Event Monitor component.

No fixed rules are associated with the trace/debug entries that the event handler generates. This is a judgement call. You should provide whatever entries you think are useful to debug or troubleshoot the event handler code.

Create trace/debug entries only when the .HandlerTraceEnabled property is True. Thus, the code looks similar to:

   If &myEvent.HandlerTraceEnabled Then
      &myEvent.HandlerStatus.AddTraceEntry("Method ABC()", 
"No data returned for: " | &Emplid);
   End-If;