Description: An example of implementing execute() for bulk orchestration in an event handler is given here. The example plug-in can be download here. The example event handler performs recalculation of department number user attribute whenever user type or manager user attribute is changed for target user(s). A test driver is given to perform modifications on multiple users on a single API call.
References:
http://docs.oracle.com/cd/E27559_01/dev.1112/e27150/oper.htm#OMDEV4741
http://docs.oracle.com/cd/E40329_01/apirefs.1112/e28159/toc.htm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.blogspot.oraclestack.eventhandlers; | |
import java.io.Serializable; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import oracle.core.ojdl.logging.ODLLevel; | |
import oracle.core.ojdl.logging.ODLLogger; | |
import oracle.iam.identity.exception.NoSuchUserException; | |
import oracle.iam.identity.exception.UserLookupException; | |
import oracle.iam.identity.usermgmt.api.UserManager; | |
import oracle.iam.identity.usermgmt.api.UserManagerConstants; | |
import oracle.iam.identity.usermgmt.vo.User; | |
import oracle.iam.identity.vo.Identity; | |
import oracle.iam.platform.Platform; | |
import oracle.iam.platform.authz.exception.AccessDeniedException; | |
import oracle.iam.platform.entitymgr.EntityManager; | |
import oracle.iam.platform.entitymgr.InvalidDataFormatException; | |
import oracle.iam.platform.entitymgr.InvalidDataTypeException; | |
import oracle.iam.platform.entitymgr.NoSuchEntityException; | |
import oracle.iam.platform.entitymgr.ProviderException; | |
import oracle.iam.platform.entitymgr.StaleEntityException; | |
import oracle.iam.platform.entitymgr.UnknownAttributeException; | |
import oracle.iam.platform.entitymgr.UnsupportedOperationException; | |
import oracle.iam.platform.kernel.EventFailedException; | |
import oracle.iam.platform.kernel.spi.ConditionalEventHandler; | |
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; | |
/** | |
* Bulk Event Handler Example | |
* Operation = MODIFY | |
* Perform recalculation of Department Number = "{Manager User Login}|{Manager USR Key}|{User Type}" | |
* whenever User Type or Manager is changed for target user | |
* @author rayedchan | |
*/ | |
public class BulkModifyUserEHPostProcess implements PostProcessHandler, ConditionalEventHandler | |
{ | |
private ODLLogger logger = ODLLogger.getODLLogger("BULK_MODIFY_USER"); | |
private EntityManager entMgr = null; | |
private UserManager usrMgr = null; | |
@Override | |
public EventResult execute(long processId, long eventId, Orchestration orchestration) | |
{ | |
logger.log(ODLLevel.NOTIFICATION, "Enter execute() with parameters: Process Id = [{0}], Event Id = [{1}], Orchestration = [{2}]", new Object[]{processId, eventId, orchestration}); | |
try | |
{ | |
this.entMgr = Platform.getService(EntityManager.class); | |
this.usrMgr = Platform.getService(UserManager.class); | |
// Get the modified UDFs | |
HashMap<String, Serializable> modUDFs = orchestration.getParameters(); | |
logger.log(ODLLevel.NOTIFICATION, "Modified UDFs: [{0}]", new Object[]{modUDFs}); | |
// Get USR_KEY of current userbeing modified | |
String userKey = orchestration.getTarget().getEntityId(); | |
logger.log(ODLLevel.NOTIFICATION, "Target OIM User Key: [{0}]", new Object[]{userKey}); | |
// Get Target Type | |
String targetType = orchestration.getTarget().getType(); | |
logger.log(ODLLevel.NOTIFICATION, "Target type: [{0}]", new Object[]{targetType}); | |
// Get new user state | |
HashMap<String, Serializable> interEventData = orchestration.getInterEventData(); // Contains old and new values of user | |
logger.log(ODLLevel.TRACE, "InterEventData: {0}", new Object[]{interEventData}); | |
User newUserState = (User) interEventData.get("NEW_USER_STATE"); | |
logger.log(ODLLevel.NOTIFICATION, "User: [{0}]", new Object[]{newUserState}); | |
// Perform attribute derivation of Department Number = "{Manager User Login}|{Manager USR Key}|{User Type}" | |
executeEvent(newUserState, userKey, targetType); | |
} | |
catch (Exception e) | |
{ | |
logger.log(ODLLevel.ERROR, e.getMessage(), e); | |
throw new EventFailedException(processId,"","","","", new Exception(e.getMessage())); | |
} | |
return new EventResult(); | |
} | |
@Override | |
public BulkEventResult execute(long processId, long eventId, BulkOrchestration bulkOrchestration) | |
{ | |
logger.log(ODLLevel.NOTIFICATION, "Enter execute() with parameters: Process Id = [{0}], Event Id = [{1}], Bulk Orchestration = [{2}]", new Object[]{processId, eventId, bulkOrchestration}); | |
try | |
{ | |
this.entMgr = Platform.getService(EntityManager.class); | |
this.usrMgr = Platform.getService(UserManager.class); | |
// Get the user records from the orchestration argument | |
String[] entityIds = bulkOrchestration.getTarget().getAllEntityId(); | |
// Get every changes from all users | |
HashMap<String, Serializable>[] bulkParameters = bulkOrchestration.getBulkParameters(); | |
// Get interParameters | |
HashMap<String, Serializable> interParameters = bulkOrchestration.getInterEventData(); | |
// Get the new state of all users | |
Object newUsersObj = interParameters.get("NEW_USER_STATE"); | |
Identity[] newUsersState = (Identity[]) newUsersObj; | |
// Iterate each OIM user | |
for (int i = 0; i < entityIds.length; i++) | |
{ | |
// Get the modified UDFs | |
HashMap<String, Serializable> modUDFs = bulkParameters[i]; | |
logger.log(ODLLevel.NOTIFICATION, "Modified UDFs: [{0}]", new Object[]{modUDFs}); | |
// Get USR_KEY of current userbeing modified | |
String userKey = entityIds[i]; | |
logger.log(ODLLevel.NOTIFICATION, "Target OIM User Key: [{0}]", new Object[]{userKey}); | |
// Get Target Type | |
String targetType = bulkOrchestration.getTarget().getType(); | |
logger.log(ODLLevel.NOTIFICATION, "Target type: [{0}]", new Object[]{targetType}); | |
// Get new user state | |
User newUserState = (User) newUsersState[i]; | |
logger.log(ODLLevel.NOTIFICATION, "User: [{0}]", new Object[]{newUserState}); | |
// Perform attribute derivation of Department Number = "{Manager User Login}|{Manager USR Key}|{User Type}" | |
executeEvent(newUserState, userKey, targetType); | |
} | |
} | |
catch (Exception e) | |
{ | |
logger.log(ODLLevel.ERROR, e.getMessage(), e); | |
throw new EventFailedException(processId,"","","","", new Exception(e.getMessage())); | |
} | |
return new BulkEventResult(); | |
} | |
/** | |
* Process a single event. | |
* Populate Department Number with "{Manager User Login}|{Manager USR Key}|{User Type}" | |
* @param newUserState New User state | |
* @param userKey OIM USR_KEY | |
* @param targetType User | |
* @throws AccessDeniedException | |
* @throws NoSuchUserException | |
* @throws UserLookupException | |
* @throws InvalidDataTypeException | |
* @throws InvalidDataFormatException | |
* @throws NoSuchEntityException | |
* @throws StaleEntityException | |
* @throws UnsupportedOperationException | |
* @throws UnknownAttributeException | |
* @throws ProviderException | |
*/ | |
public void executeEvent(User newUserState, String userKey, String targetType) throws AccessDeniedException, NoSuchUserException, UserLookupException, InvalidDataTypeException, InvalidDataFormatException, NoSuchEntityException, StaleEntityException, UnsupportedOperationException, UnknownAttributeException, ProviderException | |
{ | |
// Fetch User attributes | |
String managerKey = newUserState.getManagerKey(); | |
String userType = newUserState.getEmployeeType(); | |
String managerUserLogin = ""; | |
// Check existence of manager key | |
if(managerKey != null) | |
{ | |
User managerUser = this.usrMgr.getDetails(managerKey, new HashSet<String>(), false); | |
managerUserLogin = managerUser.getLogin(); | |
} | |
else | |
{ | |
managerUserLogin = "NO_MANAGER"; | |
} | |
logger.log(ODLLevel.NOTIFICATION, "Manager Key = {0}, Manager User Login = {1}, User Type ={2}", new Object[]{managerKey,managerUserLogin,userType}); | |
// Populate Department Number with <Manager User Login>|<Manager USR Key>|<User Type> | |
String result = managerKey + "|" + managerUserLogin + "|" + userType; | |
logger.log(ODLLevel.NOTIFICATION, "Result = {0}", new Object[]{result}); | |
HashMap<String, Object> modAttrs = new HashMap<String, Object>(); | |
modAttrs.put(UserManagerConstants.AttributeName.DEPARTMENT_NUMBER.getId(), result); | |
this.entMgr.modifyEntity(targetType, userKey, modAttrs); // prevents OIM from triggering a second orchestration event after the user gets updated | |
logger.log(ODLLevel.NOTIFICATION, "Modify user successfully."); | |
} | |
@Override | |
public void compensate(long l, long l1, AbstractGenericOrchestration ago) | |
{ | |
} | |
@Override | |
public boolean cancel(long l, long l1, AbstractGenericOrchestration ago) | |
{ | |
return false; | |
} | |
@Override | |
public void initialize(HashMap<String, String> hm) | |
{ | |
logger.log(ODLLevel.NOTIFICATION, "Enter initialize with parameter: [{0}]", new Object[]{hm}); | |
} | |
/** | |
* Determines if this event handler should be triggered. | |
* Condition for Execution: Manager or User Type user attribute is changed | |
* @param abstractGenericOrchestration Orchestration is used for single event. BulkOrchestration is used for bulk events. | |
* @return true to execute event handler or false to skip event handler | |
*/ | |
@Override | |
public boolean isApplicable(AbstractGenericOrchestration abstractGenericOrchestration) | |
{ | |
logger.log(ODLLevel.NOTIFICATION, "Enter isApplicable() with parameter: AbstractGenericOrchestration = {0}", new Object[]{abstractGenericOrchestration}); | |
boolean isApplicable = false; | |
String operationType = abstractGenericOrchestration.getOperation(); | |
logger.log(ODLLevel.NOTIFICATION, "Operation: {0}", new Object[]{operationType}); | |
HashMap<String, Serializable> modParams = abstractGenericOrchestration.getParameters(); | |
logger.log(ODLLevel.NOTIFICATION, "Modified Parameters: {0}", new Object[]{modParams}); | |
HashMap<String, Serializable> interEventData = abstractGenericOrchestration.getInterEventData(); | |
logger.log(ODLLevel.NOTIFICATION, "InterEventData: {0}", new Object[]{interEventData}); // null | |
// Single Orchestration | |
if(abstractGenericOrchestration instanceof Orchestration) | |
{ | |
String entityId = abstractGenericOrchestration.getTarget().getEntityId(); | |
logger.log(ODLLevel.NOTIFICATION, "Entity Id: {0}", new Object[]{entityId}); | |
String[] entityIds = abstractGenericOrchestration.getTarget().getAllEntityId(); | |
for(String userId : entityIds) | |
{ | |
logger.log(ODLLevel.NOTIFICATION, "Entity Ids: {0}", new Object[]{userId}); | |
} | |
} | |
// Bulk Orchestration | |
else if (abstractGenericOrchestration instanceof BulkOrchestration) | |
{ | |
BulkOrchestration bulkOrchestration = (BulkOrchestration) abstractGenericOrchestration; | |
// Get the user records from the orchestration argument | |
String[] entityIds = bulkOrchestration.getTarget().getAllEntityId(); | |
// Get every changes from all users | |
HashMap<String, Serializable>[] bulkParameters = bulkOrchestration.getBulkParameters(); | |
logger.log(ODLLevel.NOTIFICATION, "All Modified Bulk Parameters: {0}", new Object[]{bulkParameters}); | |
// Get interParameters | |
HashMap<String, Serializable> interParameters = bulkOrchestration.getInterEventData(); | |
logger.log(ODLLevel.NOTIFICATION, "Bulk InterEventData: {0}", new Object[]{interParameters}); // No interdata in conditional stage | |
// Iterate each OIM user | |
for (int i = 0; i < entityIds.length; i++) | |
{ | |
// Get the modified UDFs | |
HashMap<String, Serializable> modUDFs = bulkParameters[i]; | |
// Get USR_KEY of current userbeing modified | |
String userKey = entityIds[i]; | |
logger.log(ODLLevel.NOTIFICATION, "Target OIM User Key = [{0}], Modified UDFs = [{1}]", new Object[]{userKey, modUDFs}); | |
} | |
} | |
// Check if User Type (Role) or Manager (usr_manager_key) user attribute is changed | |
isApplicable = modParams.containsKey(UserManagerConstants.AttributeName.MANAGER_KEY.getId()) || modParams.containsKey(UserManagerConstants.AttributeName.EMPTYPE.getId()) ; | |
logger.log(ODLLevel.NOTIFICATION, "Trigger event handler: {0}", new Object[]{isApplicable});; | |
return isApplicable; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.blogspot.oraclestack.testdriver; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.Hashtable; | |
import oracle.iam.identity.usermgmt.api.UserManager; | |
import oracle.iam.identity.usermgmt.api.UserManagerConstants; | |
import oracle.iam.identity.usermgmt.vo.User; | |
import oracle.iam.platform.OIMClient; | |
/** | |
* Test Driver for BulkModifyUserEHPostProcess class | |
* @author rayedchan | |
*/ | |
public class BulkModifyUserTestDriver | |
{ | |
// Adjust constant variables according to you OIM environment | |
public static final String OIM_HOSTNAME = "localhost"; | |
public static final String OIM_PORT = "14000"; // For SSL, use 14001; For non-SSL, use 14000 | |
public static final String OIM_PROVIDER_URL = "t3://"+ OIM_HOSTNAME + ":" + OIM_PORT; // For SSL, use t3s protocol; For non-SSL, use t3 protocol | |
public static final String AUTHWL_PATH = "lib/config/authwl.conf"; | |
public static final String APPSERVER_TYPE = "wls"; | |
public static final String FACTORY_INITIAL_TYPE = "weblogic.jndi.WLInitialContextFactory"; | |
public static final String OIM_ADMIN_USERNAME = "xelsysadm"; | |
public static final String OIM_ADMIN_PASSWORD = "Password1"; | |
public static void main(String[] args) throws Exception | |
{ | |
OIMClient oimClient = null; | |
try | |
{ | |
// Set system properties required for OIMClient | |
System.setProperty("java.security.auth.login.config", AUTHWL_PATH); | |
System.setProperty("APPSERVER_TYPE", APPSERVER_TYPE); | |
// Create an instance of OIMClient with OIM environment information | |
Hashtable<String, String> env = new Hashtable<String, String>(); | |
env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, FACTORY_INITIAL_TYPE); | |
env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, OIM_PROVIDER_URL); | |
// Establish an OIM Client | |
oimClient = new OIMClient(env); | |
// Login to OIM with System Administrator Credentials | |
oimClient.login(OIM_ADMIN_USERNAME, OIM_ADMIN_PASSWORD.toCharArray()); | |
// Get User Manager API Service | |
UserManager usrMgr = oimClient.getService(UserManager.class); | |
// Stage bulk modification data - Note user attribute must be have "Bulk Update" set to true. | |
HashMap<String,Object> modAttrs = new HashMap<String,Object>(); | |
//modAttrs.put(UserManagerConstants.AttributeName.EMPTYPE.getId(), "EMP"); // Set User Type to Employee | |
modAttrs.put(UserManagerConstants.AttributeName.EMPTYPE.getId(), "Full-Time"); | |
//modAttrs.put(UserManagerConstants.AttributeName.USERTYPE.getId(), "End-User Administrator"); | |
//modAttrs.put(UserManagerConstants.AttributeName.USERTYPE.getId(), "End-User"); | |
ArrayList<String> userIds = new ArrayList<String>(); | |
userIds.add("DDUMA"); | |
userIds.add("BLEVANDOWSKI"); | |
userIds.add("KCHESTER"); | |
// Perform bulk modifications across multiple users | |
boolean useUserLogin = true; | |
usrMgr.modify(userIds, modAttrs, useUserLogin); | |
// Single user modification | |
//User modUser = new User("DDUMA"); | |
//modUser.setManagerKey("71"); | |
//modUser.setEmployeeType("Consultant"); | |
//modUser.setFirstName("Dan"); | |
//usrMgr.modify("User Login", "DDUMA" , modUser); | |
} | |
finally | |
{ | |
if( oimClient != null) | |
{ | |
oimClient.logout(); | |
} | |
} | |
} | |
} |
Hello,
ReplyDeleteIs this code & methods works for OIM 11gR1 ?