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.