Implementing Custom Event Handlers

To implement custom event handlers:

Implement one of the SPIs mentioned in table below to write a custom pre-process, post-process, or validation handler.

Table 7-3 SPIs to Write Custom Event Handlers

Stage SPI to implement
Pre-Process oracle.iam.platform.kernel.spi.PreProcessHandler
Post-Process oracle.iam.platform.kernel.spi.PostProcessHandler
Validation oracle.iam.platform.kernel.spi.ValidationHandler
  • Include the following JAR files in the class path to compile a custom class:
    From OIM_INSTALL_HOME/server/platform
  • iam-platform-kernel.jar
  • iam-platform-util.jar
  • iam-platform-context.jar
  • iam-plaftorm-authz-service.jar

From OIM_INSTALL_HOME/designconsole/lib

  • OIMClient.jar
  • xlAPI.jar

From OIM_INSTALL_HOME/designconsole/lib and OIM_INSTALL_HOME/server:
All other JAR files

  • Create a library of JAR files containing the custom classes.

The following code samples illustrate how to invoke Oracle Identity Manager 9.1.x APIs and 11g APIs to customize user management operations. See SPI Javadocs for more information.

Example 1: Custom Password Validation

Example shows a sample custom validation handler code fragment that checks to ensure that $ is not used in a password.

Example 7-1 Sample Custom Validation Handler
throws ValidationException, ValidationFailedException {
    HashMap<String, Serializable> parameters = orchestration.getParameters();
    String password = (parameters.get("usr_password") instanceof ContextAware)
      ? (String) ((ContextAware) parameters.get("usr_password")).getObjectValue()
      : (String) parameters.get("usr_password");
    if (password.contains("$")) {
      throw new ValidationFailedException();
    }
}
Example 2: Custom Pre-process Event Handler to Set Middle Initial

Example 7-2 shows a sample custom pre process event handler code fragment that sets the middle initial to the first letter of the first name if the user does not have a middle name.

Example 7-2 Sample Custom Pre Process Event Handler
// This custom preprocess event handler sets the first letter of the first name as 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 (isNullOrEmpty(middleName)) {
     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) {
  String value = (parameters.get(key) instanceof ContextAware)
  ? (String) ((ContextAware) parameters.get(key)).getObjectValue()
  : (String) parameters.get(key);
  return value;
}
Example 3: Custom Post-process Event Handler to Provision Resource Object

shows a sample custom post process event handler code fragment that provisions a resource object OBJ005 to a user whose role is ROLE 00.5

Example 7-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("Error occurred ", 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<Identity> roles = roleManager.getUserMemberships(userKey);

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;
}

Creating Plug-ins for Custom Event Handlers

To create plug-ins containing custom event handlers, you need to develop the appropriate event handler classes.

Note:
Ensure that plug-in point used in the plug-in definition is set to oracle.iam.platform.kernel.spi.EventHandler.

Note:
The plug-ins can be packaged as required, just like the JAR files, as long as they adhere to the packaging guidelines.

Here 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>

7.2.2.3 Defining Custom Events

Take these steps to define custom events:

  1. Create the metadata XML file containing definitions of all the custom events.
    Example 7-4 shows what a metadata file looks like:
Example 7-4 Sample Metadata XML File for Custom Event Definitions
<?xml version='1.0' encoding='utf-8'?>
<eventhandlers>
  <!-- Custom preprocess event handlers -->
  <action-handler

    entity-type="User" 
    operation="CREATE" 
    name="SamplePreprocessExtension"
    Stage="preprocess"
    order="1000" 
    sync="TRUE"/>

  <!-- Custom postprocess event handlers -->
  <action-handler

    entity-type="User" 
    operation="CREATE" 
    name="SamplePostprocessExtension"
    stage="postprocess"
    order="1000" 
    sync="TRUE"/>

  <action-handler

    entity-type="User" 
    operation="MODIFY" 
    name="SamplePostprocessExtension"
    stage="postprocess"
    order="1000" 
    sync="TRUE"/>

  <!-- Custom validation event handlers -->
   <validation-handler

    entity-type="User" 
    operation="CREATE" 
    name="SampleValidationExtension"
    order="1000"/>       

   <validation-handler

    entity-type="User" 
    operation="MODIFY" 
    name="SampleValidationExtension"
    order="1000"/>       
</eventhandlers>