This chapter describes the concepts related to orchestration and how to write custom event handlers to extend the functionalities of Oracle Identity Manager. It contains the following topics:
In an Identity Management system, any action performed by a user or system is called an operation. Examples of operations are creating users, modifying roles, and creating password policies. The process of any Oracle Identity Manager operation that goes through a predefined set of stages and executes some business logic in each stage is called an orchestration. The type of object that is changed by the orchestration is called an orchestration target. The data that is required to carry out the orchestration operation is called orchestration parameter.
A bulk orchestration is the process of orchestrating same operation on multiple entities. For example, if you want to update the organization of multiple users, then you can submit a bulk orchestration. As a result, the operation on all the entities are performed in a single call.
Note:
If custom event handlers are required to be introduced for lock/unlock operations, then you must implement bulk orchestrations. From the UI, bulk orchestrations are triggered for a single user lock/unlock operation.Orchestration is divided into predefined steps called stages. Every operation moves through these stages until it reaches finalization. Orchestration has the following stages:
Validation: Stage to perform validation on the orchestration, such as validity of orchestration parameters. Orchestration parameter is the data that is required to carry out the orchestration operation.
Preprocess: Stage to perform orchestration parameter manipulations or get approvals or perform Segregation of Duties (SoD) checks.
Action: Stage in which the action takes place.
Audit: Stage in which the auditing of operation is performed.
Postprocess: Stage in which consequent operations related to the current operation takes place. Examples of consequent operations are auto role membership and policy evaluation on a user creation.
Finalization: Last stage in the process to perform any clean up.
Each operation performed can have consequences for users or other entities. For example, creating a user might result in provisioning of resources to that user, and creating a new password policy can make certain user passwords invalid and require changes during next login. Each consequence is represented as an orchestration. A differed consequence is executed before the finalization of the current orchestration. An immediate consequence is executed immediately after the current event handler returns, before proceeding to the next event handler on the current orchestration. You can customize the consequences of some operations, such as create, modify, delete, enable, disable, lock, and unlock users, by writing event handlers, as described in subsequent sections.
There are orchestrations for which the starting point is the postprocess stage. If you are reconciling users from a trusted source or bulk loading users and want to add this data as is in Oracle Identity Manager. When the data is in Oracle Identity Manager, you can perform postprocess operations on the users to compute autogroup membership or evaluate policies. Therefore, reconciliation engine or bulk load utility submits postprocess-only orchestrations.
An event handler is a piece of code that is registered with an orchestration on various stages. These event handlers are invoked when the relevant orchestration stage is performed. Event handlers can either be asynchronous or synchronous. A synchronous event handler returns with a response right away, whereas an asynchronous event handler completes at a later stage. An event handler can be conditional, which means that the event handler is executed when certain conditions are satisfied.
What happens at each stage of orchestration is determined by branching and by the event handler, if any, that is deployed at that stage. If a stage has a branch, responses from the event handlers decide which branch to take. If a stage has no event handlers, or event handlers respond with no recommendation, then the operation follows the default path and moves to the next stage. However, a process can move to some out-of-the-band stages if the event handlers are invalid or canceled. These stages are:
Invalid: Process is moved to this stage if orchestration validation fails.
Veto: Process is moved to this stage if any of the preprocess event handlers are vetoed. For example, if approvals are rejected by the approver, then orchestration is vetoed.
Cancel: Process is moved to this stage if the operation is stopped by calling the cancel method.
Compensation: Process is moved to this stage if the operation is rolled back by calling the compensate method.
Figure 18-1 shows the various orchestration stages:
Note:
Dynamic Monitoring Service (DMS) can be used to view performance metrics. TheOIM_Orchestration
DMS metric is present for monitoring orchestration performance. It shows the orchestration operations executed and the time taken to perform an orchestration operation.Oracle Identity Manager allows you to implement Service Provider Interfaces (SPIs) to customize the functionality of orchestration operations. Only customization of preprocess, postprocess, validation, and finalization stages of an operation in an entity orchestration is supported.
The following are examples of event handler implementation:
When a user is created, the account status (enabled or disabled) is to be set based on some rules. A preprocess event handler can be implemented to achieve this.
Users of type Contractors must have an email address at the time of creation. Other users can be created without email address. A validation event handler can be used to validate if the user is a Contractor, and then allow or disallow the user creation based on the validation result.
Users of type Agents are to be notified in the user's alternate email address after the users are created. This can be achieved by implementing a postprocess event handler.
Postprocess event handlers are most commonly implemented to meet business requirements. The following example describes how a postprocess event handler implementation can meet the given requirement:
If the enterprise user is a Contractor, then after the user is created in Oracle Identity Manager, the user must be registered in the Contractor Registration System, which is an external application. This application is a database application. The database has a structure that stores the User ID, Contractor ID, First Name, and Last Name attributes of the users. After successful registration, the Contractor ID of the users must be retrieved and updated in the user's profile in Oracle Identity Manager.
This use case can be developed as a plug-in and deployed on Oracle Identity Manager. The plug-in can be used to retrieve the Contractor ID or any configured column name from specified database table and update the user profile in Oracle Identity Manager.A postprocess event handler can be implemented and registered for the create operation of the user entity. It is a conditional event handler that executes for users only with type as Contractor. If the user type is Contractor, then the event handler connects to the external application to retrieve the Contractor ID based on the Oracle Identity Manager user ID, and update the user profile in Oracle Identity Manager with contractor ID.
The following is another common example of postprocess implementation of event handlers:
Custom attribute generation if the data that is reconciled into Oracle Identity Manager is not enough to implement all use cases and extra attributes need to be generated based on the reconciled data. This is a common use case, especially when the custom attributes are used in the role membership rules or access policies.
Table 18-1 lists the orchestration operations supported for various entities.
Table 18-1 Orchestration Operations for Entities
Entity | Orchestration operation |
---|---|
User |
CREATE MODIFY DELETE DISABLE ENABLE LOCK UNLOCK CHANGE_PASSWORD RESET_PASSWORD ADD_PROXY UPDATE_PROXY REMOVE_PROXY REMOVE_ALL_PROXIES GET_ALL_PROXIES SELFSETCHALLENGE EVALUATE_POLICIES |
Organization |
CREATE MODIFY ENABLE DISABLE DELETE |
Role |
CREATE MODIFY MODIFY_RULE DELETE |
RoleCategory |
CREATE MODIFY DELETE |
RoleUser |
CREATE MODIFY DELETE |
RoleRole |
CREATE MODIFY DELETE |
An event handler consists of the following:
Java code: Implementation of the operations
XML definition: Association with the relevant orchestration at the right stage
Plug-in definition: Registration of the event handlers and any extension code with Oracle Identity Manager plug-in framework
Developing a custom event handler comprises of implementing the operation through Java code, writing the XML definition, and creating and registering a plug-in. These are described in the following sections:
This section describes how to write the JAVA code by implementing the SPI, and thereafter, create a JAR file in the following sections:
The following points must be considered for writing custom event handlers:
The supported orchestration stages in which a custom event handler can be registered are validation, preprocess, and postprocess.
Validation, preprocess, and postprocess event handlers can be conditional. This means that the event handler will execute only if a particular condition is met.
You can make the event handler conditional by implementing the oracle.iam.platform.kernel.spi.ConditionalEventHandler interface and its isApplicable method. Context data and orchestration parameters are available in this method. For conditional event handlers, the applicability of event handlers is computed when the operation is initiated. Therefore, if a context or orchestration parameters are modified during the orchestration flow, then it might lead to execution of event handlers that must not be executed.
The event handlers can handle single as well as bulk entities.
The event handlers can have associated failure handlers that callbacks certain operations on the parent handlers.
Because retry of event handlers is supported, the event handlers can be re-entrant.
When reconciliation submits postprocess orchestrations, it submits bulk orchestrations. The bulkExecute method on the event handlers is called for these orchestrations. Therefore, make sure to implement this method.
If data is to be passed between custom event handlers, you can pass it by using inter event data. Calling the getInterEventData() method on orchestration returns a hashmap. In this map, you can put any object with key beginning with custom, and you can access this data in subsequent custom handlers. Do not modify or delete any predefined inter event data that is part of the same hashmap.
To make API calls inside event handlers for write or delete operations, get the API services by using Platform.getServiceForEventHandlers method. API calls that are made using the services obtained through this method are performed synchronously including the postprocessing.
Return type of event handlers, except validation handlers, are shown in the following table:
Event Handler Type | On Success | On Failure |
---|---|---|
Synchronous | new EventResult() in the execute method and new BulkEventResult() in bulk version of the execute method | EventFailedException |
Asynchronous | Return null | EventFailedException |
You must not define object-level variables at the event handler.
Table 18-2 lists the methods that you can implement in the various orchestration stages:
Table 18-2 Methods to Implement Event Handlers
Method | Applicable Orchestration Stage | Description |
---|---|---|
initialize |
preprocess, postprocess |
This method is used to open connections and pool state or resources. |
execute for single entity |
preprocess, postprocess |
This method is used to read the input attributes of the underlying operation and update to different values, if required. |
execute for bulk orchestration |
preprocess, postprocess |
This method is used to read the input attributes of multiple underlying operations and update to different values, if required. |
isApplicable |
conditional |
This method is used in conditional handlers to determine if the prerequisite condition for the event handler execution is met. |
validate |
validation |
This method is used for validation handlers to validate input data. |
cancel |
preprocess, postprocess |
This method is called when the orchestration operation is canceled. |
compensate |
preprocess, postprocess |
This method is called when the orchestration operation is compensated. |
For methods, such as execute, the following argument values are available:
IDs that you can include in the code for troubleshooting purpose, which includes:
Process ID: The ID of the orchestration instance
Event ID: The ID of the event handler instance
Orchestration object that consists of details of the underlying entity instance. This consists of:
Maps (key value pairs) containing ENTITY_ATTRIBUTE, VALUE from which the input attributes of the underlying entity is read.
Entity ID: To update back the values for the same or a different entity, use Entity Manager API and pass the Entity ID and data to it. For bulk orchestration, you get multiple Entity IDs and Maps.
Note:
Use Platform.getServiceForEventHandlers to get the services for calling create, update, and delete operations in event handlers.This section provides code samples that illustrate how to write various kinds of event handlers.
Example 1: Custom Email Validation
Example 18-1 shows a sample custom validation handler code fragment that checks to ensure that the ampersand character (@) is used in the email id of the user.
Example 18-1 Custom Email Validation
public void validate(long processId, long eventId, Orchestration orchestration) throws ValidationException, ValidationFailedException { HashMap<String, Serializable> parameters = orchestration.getParameters(); String email = (parameters.get("Email") instanceof ContextAware) ? (String) ((ContextAware) parameters .get("Email")).getObjectValue() : (String) parameters .get("Email"); if (!(email.contains("@"))) { throw new ValidationFailedException("Email doesn't contain @"); } }
Example 2: Custom Preprocess Event Handler to Set Middle Name
Example 18-2 shows a sample custom preprocess event handler code fragment that sets the middle name to the first letter of the first name if the a value is not provided for middle name.
Example 18-2 Custom Preprocess Event Handler to Set Middle Name
// the middle initial when the user doesn't have a middle name public EventResult execute(long processId, long eventId, Orchestration orchestration) { HashMap<String, Serializable> parameters = orchestration .getParameters(); // If the middle name is empty set the first letter of the first name // as the middle initial String middleName = getParamaterValue(parameters, "Middle Name"); if ((middleName == null) || middleName.equals("")) { String firstName = getParamaterValue(parameters, "First Name"); middleName = firstName.substring(0, 1); orchestration.addParameter("Middle Name", middleName); } return new EventResult(); } private String getParamaterValue(HashMap<String, Serializable> parameters, String key) { if(parameters.containsKey(key)){ String value = (parameters.get(key) instanceof ContextAware) ? (String) ((ContextAware) parameters .get(key)).getObjectValue() : (String) parameters.get(key); return value; } else{ return null; } }
Example 3: Custom Post-process Event Handler to Provision Resource Object
Example 18-3 shows a sample custom post process event handler code fragment that provisions a resource object OBJ005 to a user whose role is ROLE 005:
Example 18-3 Sample Custom Post Process Event Handler
// This custom post process event handler provisions resource object 'OBJ005' // to a user who has role 'ROLE 005' public EventResult execute(long processId, long eventId, Orchestration orchestration) { tcUserOperationsIntf userOperationsService = Platform.getService(tcUserOperationsIntf.class); try { String userKey = getUserKey(processId, orchestration); if (hasRole(userKey, "ROLE 005")) { long objKey = findObject("OBJ001"); userOperationsService.provisionResource(Long.getLong(userKey), objKey); } } catch (Exception e) { throw new EventFailedException(null, "Error occurred", null, null, e); } return new EventResult(); } // This method retrieves the key of the user entity on which an operation // is performed // This method shows how to retrieve the operation being performed, entity type // and the associated value objects private String getUserKey (long processID, Orchestration orchestration) { String userKey; String entityType = orchestration.getTarget().getType(); EventResult result = new EventResult(); if (!orchestration.getOperation().equals("CREATE")) { userKey = orchestration.getTarget().getEntityId(); } else { OrchestrationEngine orchEngine = Platform.getService(OrchestrationEngine.class); userKey = (String) orchEngine.getActionResult(processID); } return userKey; } // This method checks if a given user has a given role. // It demonstrates how to invoke a OIM 11g API from a custom event handler private boolean hasRole(String userKey, String roleName) throws Exception { RoleManager roleManager = Platform.getService(RoleManager.class); List<Role> roles = roleManager.getUserMemberships(userKey, true); for (Iterator iterator = roles.iterator(); iterator.hasNext();) { Role role = (Role) iterator.next(); if (roleName.equals((String)role.getAttribute("Role Name"))) { return true; } } return false; } // This method finds details about a resource object with the given name. // It demonstrates how to invoke a 9.1.x API from a custom event handler private long findObject(String objName) throws Exception { long objKey = 0; tcObjectOperationsIntf objectOperationsService = Platform.getService(tcObjectOperationsIntf.class); HashMap params = new HashMap(); params.put("Objects.Name", objName); tcResultSet objects = objectOperationsService.findObjects(params); for (int i = 0; i < objects.getRowCount(); i++) { objects.goToRow(i); if (objects.getStringValue("Objects.Name").equals(objName)) { objKey = objects.getLongValue("Objects.Key"); } } return objKey; }
Example 4: Custom User Postprocess Event Handler With bulkExecute Method
Example 18-4 shows how to loop through users that are part of a bulk user create orchestration.
Example 18-4 Custom User Postprocess Event Handler With bulkExecute Method
public BulkEventResult execute(long processId, long eventId, BulkOrchestration orchestration){ HashMap<String, Serializable>[] orchParamArray = orchestration.getBulkParameters(); // Array of user keys String [] entityIds = orchestration.getTarget().getAllEntityId(); for(int i=0; i< entityIds.length; i++){ } }
Example 5: Using Context in isApplicable method
Any operation in Oracle Identity Manager can take place in more than one context. For example, creating a user can happen in four different contexts, which are administrator creating a user as a direct operation, administrator creating a user by raising a request, creating a user through self registration, and user creation through trusted source reconciliation. In all these scenarios, Oracle Identity Manager submits the same user creation orchestrations having the same parameter names and values with same data types.
Example 18-5 shows how to find the context in which this operation is performed to figure out the applicability of the event handler.
To create a JAR with custom event handler code:
Implement one of the SPIs mentioned in Table 18-3 to write a custom preprocess, postprocess, or validation handler.
Table 18-3 SPIs to Write Custom Event Handlers
Stage | SPI to implement |
---|---|
Preprocess |
oracle.iam.platform.kernel.spi.PreProcessHandler |
Postprocess |
oracle.iam.platform.kernel.spi.PostProcessHandler |
Validation |
oracle.iam.platform.kernel.spi.ValidationHandler |
Finalization |
oracle.iam.platform.kernel.spi.FinalizationHandler |
See Also:
See Oracle Fusion Middleware Java API Reference for Oracle Identity Manager for information about the SPIs listed in Table 18-3Include the following JAR files in the class path to compile a custom class:
From the OIM_ORACLE_HOME/server/platform/ directory:
iam-platform-kernel.jar
iam-platform-utils.jar
iam-platform-context.jar
iam-plaftorm-authz-service.jar
From the OIM_ORACLE_HOME/designconsole/lib/ directory:
oimclient.jar
xlAPI.jar
If some other Oracle Identity Manager JAR files are required for compilation, then these can be found in the directories mentioned in this step.
Create a JAR file of the custom class.
For event handler exception handling, you must use conventional JAVA exception handling methods. The following guidelines can be used for dealing with failures:
In the event handler code, throw EventFailedException with the right arguments to indicate failure.
Failures can be handled by registering failure handlers. As part of failure handler, you can implement necessary logic to remediate the failure. The failure handlers must return FailedEventResult with the following options as Response:
CANCEL: Indicates that operation must get canceled. The Cancel method on all event handlers that are executed and completed so far is called by Kernel in reverse order of execution.
COMPENSATE: Indicates that operation must get rolled back. The Compensate method on all event handlers that are executed and completed so far is called by Kernel in reverse order of execution.
MANUAL_COMPLETE: Indicates that the handler that failed is manually completed and will proceed with the rest of the event handlers.
RETRY: Indicates to kernel that the event handler that failed must be retried.
NULL: Indicates that there is no response or recommendation by the failed handler.
The custom events definition XML is described in the following sections:
This section describes some of the elements and element attributes within Event Handlers XML files. It also describes a mandatory namespace for the event handler XML definitions.
The top-level (or parent) element in Event Handlers XML files is eventhandlers
. Table 18-4 lists and describes sub-elements that are typically defined within the eventhandlers
parent element.
Table 18-4 Typical Sub-elements within the eventhandlers Element
Sub-element | Description |
---|---|
|
Identifies the validations that will be performed on the orchestration. |
|
Identifies the operations that will be performed at preprocess, postprocess, and action stages. |
|
Identifies the event handlers that will be executed if an event handler in the default flow fails. |
|
Identifies the event handlers to execute at the end of the orchestration. Finalization is the last stage of any orchestration. |
|
Identifies event handlers to be executed in parent orchestration upon consequence orchestration failures. |
|
Defines the event handlers for out-of-band orchestration flows, such as veto and cancel. |
|
Identifies the event handlers that will be executed in the compensation flow of the orchestration. |
The elements within event handlers XML files contain attributes. Table 18-5 lists and describes attributes that are typically defined within elements.
Table 18-5 Typical Attributes of Sub-elements within the eventhandlers Element
Element Attribute | Description |
---|---|
Name |
The name of the event handler. |
class |
Full package name of the Java class that implements the event handler. |
entity-type |
Identifies the type of entity the event handler is executed on. A value of |
operation |
Identifies the type of operation the event handler is executed on. A value of |
order |
Identifies the order (or sequence) in which the event handler is executed. Order value is in the scope of entity, operation, and stage. Order value for each event handler in this scope must be unique. If there is a conflict, then the order in which these conflicted event handlers are executed is arbitrary. Supported values are |
orch-target |
Identifies the type of orchestration, such as entity orchestration, Toplink orchestration, and so on. The following is a list of supported values:
The default value is |
sync |
This attribute is operational in only the action-handler and change-failed elements. The sync attribute indicates whether the event handler is synchronous or asynchronous. Supported values are Note: The sync attribute must be set to |
stage |
This attribute is operational in only the out-of-band-handler, action-handler, and failed-handler elements. The stage attribute indicates the stage at which the event handler is executed. The following is a list of supported values:
|
tx |
This attribute is operational in only the out-of-band-handler, action-handler, compensate-handler, and finalization-handler elements. The tx attribute indicates whether or not the event handler should run in its own transaction. Supported values are TRUE or FALSE. By default, the value is FALSE. |
Namespace Requirement in <eventhandlers> Element
All the event handler definitions must have the following mandatory namespace definition:
<eventhandlers xmlns="http://www.oracle.com/schema/oim/platform/kernel/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oracle.com/schema/oim/platform/kernel orchestration-handlers.xsd">
Create a metadata XML file containing definitions of all the custom events, as shown in Table 18-5:
Example 18-6 Sample Metadata XML File for Custom Event Definitions
<?xml version='1.0' encoding='utf-8'?> <eventhandlers xmlns="http://www.oracle.com/schema/oim/platform/kernel/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oracle.com/schema/oim/platform/kernel orchestration-handlers.xsd"> <!-- Custom preprocess event handlers --> <action-handler class="oracle.oim.extensions.preprocess.SamplePreprocessExtension" entity-type="User" operation="CREATE" name="SetUserMiddleName" stage="preprocess" order="1000" sync="TRUE"/> <!-- Custom postprocess event handlers --> <action-handler class="oracle.oim.extensions.postprocess.SamplePostprocessExtension" entity-type="User" operation="CREATE" name="SamplePostprocessExtension" stage="postprocess" order="1000" sync="TRUE"/> <action-handler class="oracle.oim.extensions.postprocess.SamplePostprocessExtension" entity-type="User" operation="MODIFY" name="CustomResourceProv" stage="postprocess" order="1000" sync="TRUE"/> <!-- Custom validation event handlers --> <validation-handler class="oracle.oim.extensions.validation.SampleValidationExtension" entity-type="User" operation="CREATE" name="ValidateUserEmail" order="1000"/> </eventhandlers>
To create plug-ins containing custom event handlers, you need to develop the appropriate event handler classes. See "Developing Plug-ins" for detailed information about plug-ins and plug-in points.
To create a plug-in ZIP and register it:
Define the plug-in XML with the event handler plug-in point.
Note:
Ensure that plug-in point used in the plug-in definition is set to oracle.iam.platform.kernel.spi.EventHandler.The following is an example of a plug-in XML file:
<?xml version="1.0" encoding="UTF-8"?> <oimplugins> <plugins pluginpoint="oracle.iam.platform.kernel.spi.EventHandler"> <plugin pluginclass= "oracle.oim.extensions.preprocess.SamplePreprocessExtension" version="1.0" name="SamplePreprocessExtension"> </plugin> <plugin pluginclass= "oracle.oim.extensions.postprocess.SamplePostprocessExtension" version="1.0" name="SamplePostprocessExtension"> </plugin> <plugin pluginclass= "oracle.oim.extensions.validation.SampleValidationExtension" version="1.0" name="SampleValidationExtension"> </plugin> </plugins> </oimplugins>
Package the plug-in XML and the JAR file that contains the custom class or classes into a plug-in ZIP file.
Package the event handler XML that is defined using the information described in "Defining Custom Events Definition XML" into the same zip in a directory called META-INF.
Register the plug-in by using plug-in registration utilities. See "Registering Plug-ins" for additional information.
The list of custom event handlers that you deployed and registered can be viewed by using Oracle Enterprise Manager. The event handlers are displayed in the order of invocation. Using this list of event handlers, you can sequence the order of execution of the event handlers.
To specify the order for any custom event handler, you must know the list of existing event handlers and their order for a given operation. To do so, you must invoke a mbean from the Enterprise Manager by performing the following steps:
Login to the Enterprise Manager.
On the left navigation pane, expand Weblogic Domain, and select OIM DOMAIN.
Right-click the domain name, and select System Mbean Browser.
Under Application Defined Mbeans, expand oracle.iam.
Navigate to OIM_SERVER_NAME, oim, Kernel, and then click OrchestrationEngine.
Click the Operations tab.
Click the findEventHandlers method.
Provide entity name and operation name, and then click Invoke. The parameter values are case-sensitive. The possible parameter values are:
entity name: Values can be User, Role, or RoleUser
operation: Values can be CREATE, MODIFY, or DELETE
An approver can update the attribute values before approving a request. To ensure sanitization of the data entered by the approver, Oracle Identity Manager invokes validation handlers again when approver updates the request. This means that validation handlers configured for a particular entity and operations are invoked multiple times in a single request flow, when the request is submitted and when the approver modifies the request during approval workflow.
For example, when a self-registration request is submitted, the set of validation handlers configured for USER CREATE is run. Next, when the approver modifies the request to populate Organization or other user attributes, these validation handlers are re-run.
Therefore, custom validation handlers must be developed in such a way that the validation logic is re-entrant because they are invoked multiple times in single request flow.
Note:
You can add a custom password validation for cases that are not available through Oracle Identity Manager password policies. For example, you can add a password validation to ensure that the password is not a word in a dictionary.To add a custom password validation, add a custom validation event handler and set the operation to CHANGEACCOUNTPASSWORD for the event handler. Then, you can organize the order in which Oracle Identity Manager triggers the custom event handler.
Consider the following example use case:
There is a requirement of generating the HR Employee Number UDF by appending a random number to the value of the Department Number field. When the create user request or self-registration request is submitted, the HR Employee Number UDF will be auto-generated based on custom logic. If the approver edits the request during approval and modifies the Department Number value, then the HR Employee Number UDF should be re-calculated by using the new value provided for Department Number. But, if the approver does not change Department Number, then the previous values generated at the time of request submission should be used.
For this, a new validation handler must be developed for generating the HR Employee Number UDF by appending Department Number and a random number. This logic cannot be written in preprocess handler because preprocess handlers are invoked only once in the lifecycle of a request. The logic in this validation handler is as shown:
package custom.handlers; import java.io.Serializable; import java.util.HashMap; import java.util.Random; import oracle.iam.identity.usermgmt.api.UserManagerConstants; import oracle.iam.identity.utils.Utils; import oracle.iam.platform.kernel.ValidationException; import oracle.iam.platform.kernel.ValidationFailedException; import oracle.iam.platform.kernel.spi.ValidationHandler; import oracle.iam.platform.kernel.vo.BulkOrchestration; import oracle.iam.platform.kernel.vo.Orchestration; public class EmployeeNumberGenerationHandler implements ValidationHandler { @Override public void initialize(HashMap<String, String> parameters) { } @Override public void validate(long processId, long eventId, Orchestration orchestration) throws ValidationException, ValidationFailedException { HashMap<String, Serializable> contextParams = orchestration.getParameters(); //1. Generate UDF Employee number during request submission as Department Number and a random number //2. If request is in approval stage, then control has come here since approver has modified the request //2a: Check if approver has modified Department Number. If yes, then re-generate if( !Utils.isRequestInApprovalStage()) //Utility method to find if request is in approval stage or not? If it returns true, it means that approver is attempting to update the request during approval { //Step 1: String dept = contextParams.get(UserManagerConstants.AttributeName.DEPARTMENT_NUMBER.getId()).toString(); String en = dept+"_"+random(); contextParams.put("SSN", en); } else { String dept = contextParams.get(UserManagerConstants.AttributeName.DEPARTMENT_NUMBER.getId()).toString(); //compare with department number with which request was submitted, if modified by approver; the regenerate SSN if( Utils.isAttributeModifiedByApprover(orchestration , UserManagerConstants.AttributeName.DEPARTMENT_NUMBER.getId()) ) // //Utility method to find if approver has edited the particular attribute or not , during approval? { String en = dept+"_"+random(); contextParams.put("SSN", en); } } } private String random() { Random random = new Random(); String randomStr = "" + random.nextLong(); randomStr = randomStr.replaceAll("-", ""); return randomStr; } @Override public void validate(long processId, long eventId, BulkOrchestration orchestration) throws ValidationException, ValidationFailedException { } }
As a best practice, analyze the operation before developing and implementing an event handler. If plug-in is supported for the operation, then use the plug-in for customization rather than developing an event handler. For example, username generation must be implemented by using the available plug-in, and do not attempt writing that as an event handler in the create user orchestration.
For information about points to consider for developing event handlers, see "Development Considerations".
To migrate event handlers from one deployment to another, you can export the event handlers in one deployment and then import them in another deployment by using the Deployment Manager. See "Migrating Incrementally Using the Deployment Manager" in Administering Oracle Identity Manager for information exporting and importing migration artifacts by using the Deployment Manager.
The Deployment Manager supports exporting and importing of default event handlers and custom event handlers. The following table lists the entities to be selected in the Deployment Manager for default and custom event handlers.
Event Handler Type | Deployment Manager Entity Selection |
---|---|
Default event handler | Orchestration event handler |
Custom event handler | Plugin
Note: In addition to custom event handlers, custom scheduled tasks and custom notification resolvers are also migrated as part of plug-ins. Therefore, you must select the plug-in with the custom event handler while exporting and importing. |
The Deployment Manager supports migrating plug-ins, and the registered event handlers with the plug-ins, from one deployment of Oracle Identity Manager to another. See "Registering Plug-ins" for information about registering and unregistering plug-ins by using the plug-in registration utility.
Figure 18-2 shows exporting plug-ins via the Deployment Manager.
The exported plug-in is complete in itself and contains both the definition and the implementation. Therefore, you do not need to import/export the corresponding definition using other Deployment Manager entities, such as orchestration event handler in case of custom event handlers.
Table 18-6 lists common problems and causes or solutions to help troubleshoot your event handler if it is not triggered when the operation is executed.
Table 18-6 Troubleshooting Event Handlers
Problem | Cause/Solution |
---|---|
When a user is created through reconciliation, the custom preprocess event handlers are not triggered. |
Reconciliation submits postprocess only orchestration where starting stage is postprocess. |
When a user is created through reconciliation, the custom postprocess event handler is triggered but the logic inside the execute method is not triggered. |
Reconciliation submits bulk orchestrations. Therefore, make sure to implement the bulkExecute method. |
The orchestration operation taking too long to complete. |
To determine the time spent on each event handler:
|