Showing posts with label OIM11g. Show all posts
Showing posts with label OIM11g. Show all posts

Friday, January 10, 2014

OIM Audit Table: Sample Queries to Find Who did What and When

Here are few sample queries provided by Oracle to find who did what and when:

List the last change set for user with usr_key where the changes are represented  in a relational format:


SELECT usr_key,   usr_login as changed_by_user,  upa_usr.upa_usr_eff_from_date AS changed_time,   field_name,   field_old_value,   field_new_value
 FROM upa_usr, upa_fields,   (SELECT field_new_value AS changed_by_user    FROM upa_fields
   WHERE upa_fields_key =  (SELECT MAX(upa_fields_key)      FROM upa_fields, upa_usr
     WHERE upa_usr.upa_usr_key = upa_fields.upa_usr_key
     AND upa_usr.usr_key = <>
     AND upa_fields.field_name ='Users.Updated By Login'
     )
   )
 WHERE upa_usr.upa_usr_key = upa_fields.upa_usr_key
 AND upa_usr.usr_key = <>;



References:

Java Code to Add Entry in Lookup & Display Lookup Values

Here is the same java code to add entry in existing OIM Lookup and display all the Values from an existing OIM Lookup

import java.util.HashMap;
import java.util.Hashtable;
import oracle.iam.platform.OIMClient;
import Thor.API.tcResultSet;
import Thor.API.Operations.tcLookupOperationsIntf;

public class UpdateLookup {

 private static final String OIM_URL = "t3s://<>:14001";
 private static final String AUTH_CONF = "<< Path of authwl.conf >>";
 private static final String OIM_USERNAME = "<< UserID >>";
 private static final String OIM_PASSWORD = "<< Password >>";
 private static OIMClient oimClient = null;
 Hashtable env = new Hashtable();

 public UpdateLookup() {
  try {
   env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL,
     "weblogic.jndi.WLInitialContextFactory");
   env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, OIM_URL);
   System.setProperty("java.security.auth.login.config", AUTH_CONF);
   System.setProperty("OIM.AppServerType", "wls");
   System.setProperty("APPSERVER_TYPE", "wls");
   oimClient = new OIMClient(env);
   oimClient.login(OIM_USERNAME, OIM_PASSWORD.toCharArray());
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public void addLookupEntry(String LookupCode,String Lookup) {
  try {
   tcLookupOperationsIntf lookupOps = oimClient
     .getService(tcLookupOperationsIntf.class);
   lookupOps.addLookupValue("<>", LookupKey,
     LookupValue, "", "");

  } catch (Exception e) {
   e.printStackTrace();
  }
 }


 public void displayLookup(String lookupname) {
  try {
   tcLookupOperationsIntf lookupOps = oimClient
     .getService(tcLookupOperationsIntf.class);
   tcResultSet values = lookupOps.getLookupValues(lookupname);
   for (int i = 0; i < values.getRowCount(); i++) {
    values.goToRow(i);
    System.out
      .print(values
        .getStringValue("Lookup Definition.Lookup Code Information.Decode"));
    System.out
      .println(","
        + values.getStringValue("Lookup Definition.Lookup Code Information.Code Key"));
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public static void main(String args[]) {
   UpdateLookup obj = new UpdateLookup();
   obj.addLookupEntry("LookupKey","LookupValue");

   obj.displayLookup("LookupName");
 }
}


Reference:

http://docs.oracle.com/cd/E17904_01/apirefs.1111/e17334/toc.htm

Wednesday, November 13, 2013

OIM11g: How to Automate the deployment of User Modifiable Metadata Files

                 Here is how you can you or administrators can get away from providing user name and password or even server url in plain text when using WLST to modify the OIM metadata:
 
 
Step1: Connect to Admin Server using wlst.sh using the user using which you run the wlst.sh command. For example, in my case, I have created a user deployer with administrator and oimuser roles in the weblogic security realm to deploy the OIM metadata.
 
Step2: Run the below command:
 
storeUserConfig('configfile.secure','keyfile.secure')
Creating the key file can reduce the security of your system if it is not kept in a secured location after it is created. Do you want to cre
ate the key file? y or n y
The username and password that were used for this WebLogic Server connection are stored in configfile.secure and keyfile.secure.
 
Note: if you choose to create them in different directory, then prefix the directory path with the file name. For example, storeUserConfig('C:\configfile.secure','C:\keyfile.secure'). You can also choose a different name for the files.
 
This will create a user configuration file that contains your credentials in an encrypted form and a key file that WebLogic Server uses to unencrypt the credentials.

Step3: wls:/OIMDomain/serverConfig> exit()
 
Step4: Take the backup of weblogicExportMetadata.py.
 
Step5: Modify the weblogicExportMetadata.py as below:
 
Replace: connect() with
 
connect(userConfigFile='configfile.secure',userKeyFile='keyfile.secure',url='t3://host:14000')
 
Note: Please provide the absolute path if the configuration files are not in ORACLE_HOME/server/bin directory.
 
Step6: Save the python script.
 
Step7: Now, you can run the weblogicExportMetadata.bat and you will see that it won't prompt you to enter the username & password. See below:
 
Initializing WebLogic Scripting Tool (WLST) ...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands
Starting export metadata script ....
Connecting to t3://host:14000 with userid deployer ...
Successfully connected to managed Server 'oim_server1' that belongs to domain 'OIMDomain'.
Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.
Location changed to custom tree. This is a writable tree with No root.
For more help, use help(custom)

Disconnected from weblogic server: oim_server1
End of export metadata script ...
 
Note: In case of unix, follow step 1 -4 on .sh files. You can repeat the same steps for weblogicImportMetadata.sh & weblogicDeleteMetadata.sh.

Addendum:


In your weblogicExportMetadata.py script, if you want Server URL, path of the above files to be dynamic, here is what you need to do:

Step1: Create a properties file i.e., creds.properties as below:

[Properties File for Deployment]
url: t3://host:14000
userConfigFile: C:\configfile.secure
userKeyFile: C:\keyfile.secure

Step2: Updated your weblogicExportMetadata.py script as below:

"""
Custom OIM metadata Script for Deployment
"""
print 'Starting export metadata script .... '

import ConfigParser
import string
config = ConfigParser.ConfigParser()
config.read("C:\creds.properties")
for section in config.sections():
        serverurl = config.get(section,'url')
        userFile = config.get(section,'userConfigFile')
        keyFile = config.get(section,'userKeyFile')

connect(userConfigFile=userFile,userKeyFile=keyFile,url=serverurl)
exportMetadata(application=application_name,
               server=wls_servername,
               toLocation=metadata_to_loc,
                   docs=metadata_files,
                   applicationVersion='*')
disconnect ()
print 'End of export metadata script ...'
exit()
 
 
References:
 
 
 
 

Wednesday, October 23, 2013

OIM11g: Searching & retrieve Authorization Policy Data using APIs

Here is the sample code to search and retrieve "Role Management" type Authorization Policy Data:

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import oracle.iam.authzpolicydefn.api.Action;
import oracle.iam.authzpolicydefn.api.AuthzPolicyConstants.AuthzPolicyAttributes;
import oracle.iam.authzpolicydefn.api.Feature;
import oracle.iam.authzpolicydefn.api.PolicyDefinitionService;
import oracle.iam.authzpolicydefn.vo.AuthzPolicy;
import oracle.iam.authzpolicydefn.vo.RoleDataConstraint;
import oracle.iam.identity.vo.Identity;
import oracle.iam.platform.OIMClient;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;

 public void getPolicyDetails(String policyName) {
  try {
   PolicyDefinitionService policyService = oimClient.getService(PolicyDefinitionService.class);
   SearchCriteria criteria = new SearchCriteria(AuthzPolicyAttributes.NAME.getId(),policyName,SearchCriteria.Operator.EQUAL);
   List policies = policyService.search(criteria);
   for (AuthzPolicy policy : policies) {


// Returns Display Name of Policy
    System.out.println(" Policy Name : " + policy.getDisplayName()); 


//Returns Description of the Policy
    System.out.println(" Description : " + policy.getDescription());   


//Returns the Enabled Permissions
    List
actions = policy.getActions();
    for(Action action: actions) {
     System.out.println(action.getDisplayName());
    }
  
    //Returns Type of Policy i.e., Role Management
    Feature features = policy.getFeature();
    System.out.println(" Entity Name : " + features.getDisplayName());
  
    //Returns the Assignment i.e., roles that are added to the Policy
    ArrayList
userList = policy.getRoleAssignees();
  for(Identity id: userList) {
   System.out.println(" Assign by Role : " + id.getAttribute("Role Name"));
  }

// Data Constraints i.e., Returns the Role Name attached with Policy
 RoleDataConstraint rDataConstraint = (RoleDataConstraint) policy.getDataSecurity();
 ArrayList
roles = rDataConstraint.getRoles();
 for(Identity role: roles) {
  System.out.println(role.getAttribute("Role Name"));
 }
}
}
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

}

Note: The APIs used above are not documented by Oracle.

OIM: Code to get Recon Event Data given a Recon Event Key

Here is a sample code to get the Recon Event Information & Recon Target Attibute given a Recon Event Key

 public void getReconEventData() {
  try {
   ReconOperationsService reconOpService = oimClient.getService(ReconOperationsService.class);
   EventMgmtService eventService = oimClient.getService(EventMgmtService.class);
   ReconSearchCriteria criteria = new ReconSearchCriteria() ;
   Vector order = new Vector();
   order.add(EventConstants.RECON_EVENT_KEY);
   boolean ascOrderFlag = true;
   Object reKey = 2901; // Recon Event Key
   criteria.addExpression(EventConstants.RECON_EVENT_KEY, reKey, ReconSearchCriteria.Operator.EQUAL);
   List output = eventService.search(criteria,order, ascOrderFlag, 0, 100);
  
   for(ReconEvent event: output) {
    System.out.println(" Profile Name " + event.getProfileName());
    System.out.println(" Key Fields " + event.getReKeyField());
    System.out.println(" Resource Name " + event.getResourceName());
    System.out.println(" Current Status " + event.getReStatus());
    System.out.println(" Entity " + event.getReEntityType());
    System.out.println(" Date and Time " + event.getReModify());
    System.out.println(" Job ID " + event.getRjKey());
    System.out.println(" Linked By " + event.getLinkSource()); 
    ReconEventData eventData = eventService.getReconEventData(event);
    List reconAttributes = eventData.getSingleValuedAttrs();
    System.out.println(reconAttributes.size());
    for(ReconTargetAttribute reconAttribute: reconAttributes) {
     System.out.print(reconAttribute.getOimMappedFieldDescription()+" - ");
     System.out.println(reconAttribute.getStringVal());
    }
   }


References:

http://docs.oracle.com/cd/E14571_01/apirefs.1111/e17334/oracle/iam/reconciliation/api/ReconOperationsService.html
http://docs.oracle.com/cd/E17904_01/apirefs.1111/e17334/
http://docs.oracle.com/cd/E17904_01/apirefs.1111/e17334/oracle/iam/reconciliation/vo/ReconSearchCriteria.html#addExpression_java_lang_String__java_lang_Object__oracle_iam_reconciliation_vo_ReconSearchCriteria_Operator_http://docs.oracle.com/cd/E17904_01/apirefs.1111/e17334/oracle/iam/reconciliation/vo/ReconTargetAttribute.html

Thursday, October 10, 2013

Reading OIM System Property in Custom Code

Here are the APIs to read/create/update System Property in OIM:


// You can use this API to only read the system property
tcPropertyOperationsIntf property = Platform.getService(tcPropertyOperationsIntf.class);
String pvalue = property.getPropertyValue("Property Name");
 

// You can use this API to read/create/update/delete the system property
SystemConfigurationService sc = Platform.getService(SystemConfigurationService.class);
SystemProperty sr = sc.getSystemProperty("Property Name");
String pvalue = sr.getPtyValue();


API Reference:

http://docs.oracle.com/cd/E27559_01/apirefs.1112/e28159/oracle/iam/conf/api/SystemConfigurationService.html

http://docs.oracle.com/cd/E23943_01/apirefs.1111/e17334/Thor/API/Operations/tcPropertyOperationsIntf.html
 

Thursday, September 26, 2013

OIM: Audit handler failed

Here is the Error of the day:

Just saw it after restarting OIM Server in one of the environment:

Issue: oracle.iam.platform.async.TaskExecutionException: java.lang.Exception: Audit handler failed
        at com.thortech.xl.audit.engine.jms.XLAuditMessage.execute(XLAuditMessage.java:59)
        at oracle.iam.platform.async.impl.TaskExecutor.executeManagedTask(TaskExecutor.java:122)
        at oracle.iam.platform.async.impl.TaskExecutor.execute(TaskExecutor.java:69)
        at oracle.iam.platform.async.messaging.MessageReceiver.onMessage(MessageReceiver.java:68)
        at sun.reflect.GeneratedMethodAccessor644.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke


Cause: Under Investigation

Wednesday, September 25, 2013

msExchVersion Attribute not supported by OIM Exchange Connector 11.1.1.6.0

While checking the forums, I came across this post where the author was trying to run the target reconciliation using msExchVersion attribute in search filter. The author has OIM 11g BP07 and was using OIM - Exchange Connector 11.1.1.6.0. The environment has multiple version of Exchange Servers i.e., 2007 & 2003.

Just for little background, Exchange 2007 introduced a new user attribute called msExchVersion that tracks the Exchange version a mailbox is created on. This may be useful if you want to manage mailboxes by Exchange version.
Exchange 2003 and earlier = ""
Exchange 2007  = "4535486012416"
Exchange 2010 = "44220983382016"

 
After reading the connector 11.1.1.6.0 documentation, I came to know that only specific attributes can be used in search filter for running limited reconciliation. (Refer Page 75). Here is the list:

The following attributes are supported in the filters:
  • ArchiveQuota
  • ProhibitSendQuota
  • ArchiveWarningQuota
  • Database
  • IssueWarningQuota
  • ProhibitSendQuota
  • ProhibitSendReceiveQuota
  • UseDatabaseQuotaDefaults
  • ExternalEmailAddress
  • DisplayName
  • SimpleDisplayName
  • EmailAddressPolicyEnabled
  • HiddenFromAddressListsEnabled
  • MaxSendSize
  • MaxReceiveSize
  • Name
  • Alias
  • PrimarySmtpAddress
  • RecipientLimits
  • RecipientType
  • WhenChanged
  • CustomAttribute1, CustomAttribute2, and so on up to CustomAttribute15

However, the 11.1.1.5.0 and 9.1.1.7 doesn't specifically mention any list of attributes that can be used in search filter in reconciliation task. So, I think in environment with mixed version of Exchange servers, these two version should be used. 
 
References:
 
  • https://forums.oracle.com/thread/2586016
  • Exchange Reconciliation For Environments With Mixed 2003 and 2007/2010 Servers (Doc ID 1463160.1)
  • Patch 13778888: RELEASE VEHICLE FOR EXCHANGE CONNECTOR 11.1.1.5.0
  • Patch 17198005: RELEASE VEHICLE FOR EXCHANGE CONNECTOR 11.1.1.6.0
 

Saturday, February 2, 2013

OIM11g: Bulk Load the Data in Access Policies

Hi All,

The requirement for the code that you see below comes from my client who while learning to create access policies asked me below question:

In OIM, you cannot add multiple groups in single iteration to AccessPolicy but you can remove multiple groups. What's the rationale behind this?

Well, I couldn't agree more with him and I have no answer for him and before he could throw any other question or think of asking me to modifying the OIM UI to provide capability to add multiple groups to Access Policy, I told him that I can create a Bulk Data Load Utility which can be used for loading the groups in bulk to access policies and below is the code for that:

package security.provisioning;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.thortech.xl.vo.AccessPolicyResourceData;
import com.thortech.xl.vo.PolicyChildTableRecord;
import Thor.API.tcResultSet;
import Thor.API.Operations.tcAccessPolicyOperationsIntf;
import oracle.iam.identity.rolemgmt.api.RoleManager;
import oracle.iam.identity.rolemgmt.api.RoleManagerConstants.RoleAttributeName;
import oracle.iam.identity.rolemgmt.vo.Role;
import oracle.iam.platform.Platform;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;
import oracle.iam.scheduler.vo.TaskSupport;
import com.thortech.util.logging.Logger;

public class InitialAccessPolicyLoad extends TaskSupport {
 HashMap> mapping = new HashMap>();
 tcAccessPolicyOperationsIntf moAccesspolicyutility = null;
 private static final Logger logger = Logger.getLogger("SECURITY.EVENTS");
 private static final String CLASS_NAME = "security.provisioning.InitialAccessPolicyLoad : ";
 private static final long formKey = 25;
 private static final long objectKey = 24;
 private static final String tableKey = "22";
 private static final String objName = "OID User";
 private static final String fName = "UD_OID_USR";
 private static final String groupPrefix ="41~cn=";
 private static final String groupSuffix=",cn=Groups,dc=sample,dc=com";

 public void execute(HashMap arg0) {
  final String METHOD_NAME = "execute :: ";
  try {

   logger.debug(CLASS_NAME + METHOD_NAME + "Entering Method - execute");
   // Output File Name
   String inputFileName = arg0.get("Input File Name").toString();
   logger.debug(CLASS_NAME + METHOD_NAME + " Input File Name "
     + inputFileName);

   // Delimiter for EDR Group List
   String ROLE_DELIMITER = arg0.get("List Delimiter").toString();
   logger.debug(CLASS_NAME + METHOD_NAME + " List Delimiter "
     + ROLE_DELIMITER);

   // Delimiter for the Attributes in the Input File
   String FILE_DELIMITER = arg0.get("Field Delimiter").toString();
   logger.debug(CLASS_NAME + METHOD_NAME + " Field Delimiter "
     + FILE_DELIMITER);

   // Read Input File
   BufferedReader buff = new BufferedReader(new FileReader(inputFileName));
   buff.readLine();
   String Line = null; 
   boolean isValidRecord = true;
   String PolicyName = null;
   String RoleName = null;
   String Groups = null;
   ArrayList GroupList = new ArrayList();
   while ((Line = buff.readLine()) != null) {
  
    if (Line.startsWith("#")) {
     isValidRecord = false;
    }
  
    String[] values = Line.split(FILE_DELIMITER);
  
    if (values.length == 1) {
     PolicyName = values[0];
     isValidRecord = false;

    } else if (values.length == 2) {
     PolicyName = values[0];
     RoleName = values[1];
     isValidRecord = false;

    } else if (values.length == 3) {
     isValidRecord = true;
     PolicyName = values[0];
     RoleName = values[1];
     Groups = values[2];
     String[] gList = Groups.split(ROLE_DELIMITER);
     for(int i=0;i      GroupList.add(gList[i]);
     }
    }
  
  
    if (isValidRecord) {
     uploadPolicyData(PolicyName,RoleName,GroupList);
     logger.debug(CLASS_NAME + METHOD_NAME + "ADDING RECORD: " + Line);
    } else {
     logger.debug(CLASS_NAME + METHOD_NAME + "INVALID RECORD: " + Line);
    }

   }
   

   logger.info(CLASS_NAME + METHOD_NAME
     + " Access Policies Data Loaded");

  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
  }
 }

 public void uploadPolicyData(String PolicyName, String RoleName, ArrayList GroupList) {
  final String METHOD_NAME = "uploadPolicyData :: ";

  try {

   tcAccessPolicyOperationsIntf moAccesspolicyutility = Platform
     .getService(tcAccessPolicyOperationsIntf.class);
   HashMap searchPolicy = new HashMap();
   searchPolicy.put("Access Policies.Name", PolicyName);
   tcResultSet result = moAccesspolicyutility.findAccessPolicies(searchPolicy);
 
   long policyKey = result.getLongValue("Access Policies.Key");
   logger.debug(CLASS_NAME + METHOD_NAME + "Access Policies.Key" +policyKey);
 
   Long roleKey = Long.parseLong(getRoleKey(RoleName));
   long[] roleKeys = { roleKey };
 
   //Add the Role NAME
   moAccesspolicyutility.assignGroups(policyKey, roleKeys);
   logger.info(CLASS_NAME + METHOD_NAME
     + " Role: "+ RoleName +" is attached to the Access Policy: " + PolicyName);
 
   for(int i = 0;i  
    HashMap childTableMap = new HashMap();
    String groupName = groupPrefix+GroupList.get(i)+groupSuffix;
    logger.debug(CLASS_NAME + METHOD_NAME + "OID Group Name: " +groupName);
    childTableMap.put("UD_OID_GRP_GROUP_NAME", groupName);
    AccessPolicyResourceData policyData = new AccessPolicyResourceData(objectKey,objName,formKey,fName,"P");
    PolicyChildTableRecord pChildTableData = policyData.addChildTableRecord(tableKey, "UD_OID_GRP", "Add", childTableMap);
    moAccesspolicyutility.setDataSpecifiedForObject(policyKey, objectKey, formKey, policyData);
    logger.info(CLASS_NAME + METHOD_NAME
      + " Group: "+ GroupList.get(i) +" attached to the Access Policy: " + PolicyName);
   }

  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
  }
 }



 public String getRoleKey(String roleName) {

  final String METHOD_NAME = "getRoleKey :: ";
  System.out.println(CLASS_NAME + METHOD_NAME
    + "Entering Method - getRoleKey");

  RoleManager rmgr = Platform.getService(RoleManager.class);
  Set retAttrs = new HashSet();
  String roleKey = null;
  try {
   retAttrs.add(RoleAttributeName.DISPLAY_NAME.getId());
   SearchCriteria criteria = null;
   criteria = new SearchCriteria(RoleAttributeName.NAME.getId(),
     roleName, SearchCriteria.Operator.EQUAL);
   List roles = rmgr.search(criteria, retAttrs, null);
   roleKey = roles.get(0).getEntityId();
  } catch (Exception e) {
   logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
  }
  return roleKey;
 }

 // Method to check if  Role exists in OIM or not
 public boolean isRoleExist(String[] roles) {

  String METHOD_NAME = "isRoleExist :: ";
  logger.debug(CLASS_NAME + METHOD_NAME +"Entering Method - isRoleExist");
  boolean roleExist = false;
  boolean roleListEmpty = false;
  if(Arrays.toString(roles).length() == 2) {
   roleListEmpty = true;
  }

  try {
   if (!roleListEmpty) {
   RoleManager rmgr = Platform.getService(RoleManager.class);
   Set retAttrs = new HashSet();
   retAttrs.add(RoleAttributeName.DISPLAY_NAME.getId());
   SearchCriteria criteria = null;
   for (int i = 0; i < roles.length; i++) {
    criteria = new SearchCriteria(RoleAttributeName.NAME.getId(),
      roles[i], SearchCriteria.Operator.EQUAL);
    List role = rmgr.search(criteria, retAttrs, null);
    if (role.size() != 0) {
     roleExist = true;
    } else {
     logger.debug(CLASS_NAME + METHOD_NAME + roles[i]
       + " DOESN'T EXIST IN OIM");
     roleExist = false;
    }
   }
  }
   }catch (Exception e) {
    logger.error(CLASS_NAME + METHOD_NAME + e.getMessage());
  }
  return roleExist;
 }

 public HashMap getAttributes() {
  return null;
 }

 public void setAttributes() {
 }

}
I don't know how easy/hard is to modify the UI to provide the capability but considering this as "Nice To Have" requirement, I think the above solution is good enough. There are couple of things like Checking if OID Group exist or not or update(add & delete) the Groups I might need to add later.

Note: This code is specific to OID Resource and assume that access policy is already created.

 

Saturday, January 26, 2013

OIM11g PostProcess EventHandler on RoleMembership


Below is the PostProcess Event Handler that I wrote to update a Custom UDF in OIM with the list of Roles assigned to the user (seperate by delimiter ','). This EventHandler is triggered every time a role is assigned/revoked to the user. The EventHandler for entity-type='RoleUser' actually calls the BulkEventResult execute() method, not the EventResult execute() method [ Oracle Doc ID: 1461252.1 ].


package oracle.oim.extensions.postprocess;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.io.Serializable;
import Thor.API.tcResultSet;
import Thor.API.Operations.tcLookupOperationsIntf;
import oracle.iam.identity.rolemgmt.api.RoleManager;
import oracle.iam.identity.rolemgmt.vo.Role;
import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.identity.usermgmt.vo.User;
import oracle.iam.identity.usermgmt.vo.UserManagerResult;
import oracle.iam.platform.Platform;
import oracle.iam.platform.kernel.spi.PostProcessHandler;
import oracle.iam.platform.kernel.vo.AbstractGenericOrchestration;
import oracle.iam.platform.kernel.vo.BulkEventResult;
import oracle.iam.platform.kernel.vo.BulkOrchestration;
import oracle.iam.platform.kernel.vo.EventResult;
import oracle.iam.platform.kernel.vo.Orchestration;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;

public class RoleProcessor implements PostProcessHandler {

 private static final String LOOKUP_COLUMN_DECODE = "Lookup Definition.Lookup Code Information.Decode";

 public BulkEventResult execute(long processId, long eventId,
   BulkOrchestration orchestration) {
  // TODO Auto-generated method stub
  try {
   String userKey = null;
   String operation = orchestration.getOperation().trim().toString();
   System.out.println("<---------- br="" bulkeventresult="">     + getClass().getName() + ": Operation[" + operation + "] Execute ---------->");
   HashMap[] bulkParameters = orchestration
     .getBulkParameters();
   for (int j = 0; j < bulkParameters.length; j++) {
    Set set = bulkParameters[j].keySet();
    Iterator itr = set.iterator();
    while (itr.hasNext()) {
     String key = itr.next().toString();
     if ("userKeys".equalsIgnoreCase(key)) {

     //Value of UserKey comes as [6088]. So below is the regex to replace special character from the Userkey.
      // Regular Expression to replace Special Character '[' & ']' from the UserKey
       userKey = bulkParameters[j].get(key).toString().replaceAll("[\\[\\]]", "");
       System.out.println("userKey ->" + userKey);
     }
    }
   }
  
   // Get List of  Roles to be Filtered
   HashSet removeRoles = readLookup();

   // Find List of Roles assigned to the user in OIM
   StringBuffer stringBuffer = new StringBuffer();
   RoleManager rolemanager = Platform.getService(RoleManager.class);
   List groupList = rolemanager
     .getUserMemberships(userKey, true);
   HashSet roleList = new HashSet();
   for (Role role : groupList) {
    String roleName = role.getAttribute("Role Name").toString();
    System.out.println("RoleName :" + roleName);
    roleList.add(roleName);
   }


  
   // Remove Roles like "ALL Users" and other default roles that are assigned to users. Requirement was to store only business/functional/applciation specific roles in Custom UDF.
   roleList.removeAll(removeRoles);
  
   Iterator iterator = roleList.iterator();
   String role = null;
   System.out.println("Role To Be Assigned Count is: " + roleList.size());
   int counter = 1;

   while (iterator.hasNext()) {
    role = iterator.next().toString();
    stringBuffer.append(role);
    if (counter != roleList.size()) {
     stringBuffer.append(",");
    }
    counter++;
   }
   String RoleList = stringBuffer.toString();
   System.out.println("Role List: " + RoleList );

   // Updating UDF
   HashMap mapAttrs = new HashMap();
   mapAttrs.put("Role List", RoleList);
   executeEvent(bulkParameters, orchestration.getTarget().getType(),
     userKey, RoleList);

  } catch (Exception e) {
   e.printStackTrace();
  }
  return new BulkEventResult();
 }


 public HashSet readLookup() {
 
  System.out.println("Reading Lookup");
  String lookupDecode = "Lookup.RoleProcessor.IgnoreRole";
  HashSet filterRoles = new HashSet();
  try {
  //Read Lookup to Find FilteredRoles
  tcLookupOperationsIntf lookupOps = Platform.getService(tcLookupOperationsIntf.class);
  tcResultSet lookupResultSet = lookupOps.getLookupValues(lookupDecode);
  for (int i = 0; i < lookupResultSet.getRowCount(); i++) {
   lookupResultSet.goToRow(i);
   String decode = lookupResultSet.getStringValue(
     LOOKUP_COLUMN_DECODE).trim();
   filterRoles.add(decode);
  }
  }catch(Exception e) {
   e.printStackTrace();
  }
  return filterRoles;
 }

 private void executeEvent(HashMap[] parameterHashMap, String targetType,
   String userKey, String RoleList) {
  try {
   System.out.println("Inside executeEvent () ");
   System.out.println("userKey " + userKey);
   System.out.println("Role List for UDF: " + RoleList);
   HashMap mapAttrs = new HashMap();
   mapAttrs.put("Role List", RoleList);


  // Finding User Login using usr_key as UserManager modify() expect User Login Name as one of the input parameters
   String username = null;
   UserManager userService = Platform.getService(UserManager.class);
   SearchCriteria criteria = new SearchCriteria("usr_key", userKey,
     SearchCriteria.Operator.EQUAL);
   Set attrNames = null;
   HashMap parameters = null;
   HashMap attributes = null;
   attrNames = new HashSet();
   attrNames.add("User Login");
   List users = null;
   //Set keys = null;
   users = userService.search(criteria, attrNames, parameters);
            System.out.println("Searching User_Login  based on USR_KEY");
  
   if (users != null && !users.isEmpty()) {
    System.out.println("search results, quantity=" + users.size());
    for (User user : users) {
     attributes = user.getAttributes();
     //keys = attributes.keySet();
     username = attributes.get("User Login").toString();
     System.out.println("User Login " + username);
    }

   }
  
   System.out.println("Updating UDF using UserManager");
   User user = null;
   user = new User(username,mapAttrs);
   UserManagerResult result = userService.modify("User Login",username,user);
            System.out.println( "Modification Status " + result.getStatus());
  
  } catch (Exception e) {
   System.out.println(e.getMessage());
   e.printStackTrace();
  }
 }
 @Override
 public void initialize(HashMap arg0) {
  // TODO Auto-generated method stub
  System.out
    .println("Initialize  RoleProcessor OIM PostProcess EventHandler");

 }
 @Override
 public boolean cancel(long arg0, long arg1,
   AbstractGenericOrchestration arg2) {
  System.out.println("Inside  cancel() method");
  // TODO Auto-generated method stub
  return false;
 }
 @Override
 public void compensate(long arg0, long arg1,
   AbstractGenericOrchestration arg2) {
  System.out.println("Inside  compensate() method");
  // TODO Auto-generated method stub
 }
 @Override
 public EventResult execute(long arg0, long arg1, Orchestration arg2) {
  // TODO Auto-generated method stub
  System.out.println("Inside EventResult execute ");
  return null;
 }
}

Note: This blog is just for my record keeping and contains my views/experience but if it helps someone, then I will be very glad.