GenerateLoginID EventHandler in OIM 11g

In OIM 11g, the entity adapters cannot be attached to the user form. So instead you will have to re-implement the entity adapters as event handlers. I had a requirement recently to do the same. The good thing about it is you can combine multiple operations into one single event handler. In this post i am going to share the code for one pre-process and one post-process event handler. 
  1. The pre-process event handler is going to generate the user login based upon the user type.
  2. The post process is going to generate email id for the user if one is not entered initially.
The pre process event handler code is mentioned in the below snippet.
package com.oimacademy.eventhandlers;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import oracle.adf.share.logging.ADFLogger;
import oracle.iam.identity.usermgmt.api.UserManagerConstants;
import oracle.iam.platform.Platform;
import oracle.iam.platform.context.ContextAware;
import oracle.iam.platform.kernel.spi.PreProcessHandler;
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 org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class GenerateLoginID implements PreProcessHandler {
    private ADFLogger eventLogger = ADFLogger.createADFLogger(GenerateLoginID.class);
    private PlatformTransactionManager txManager = Platform.getPlatformTransactionManager();
    public GenerateLoginID() {
        super();
    }
    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;
    }
    /**
     *
     *This method is used to populate the user id
     * @param l
     * @param l1
     * @param orchestration
     * @return
     */
    public EventResult execute(long processId, long eventId, Orchestration orchestration) {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        eventLogger.entering(methodName, "params :[" + processId + "," + eventId + "]");
        HashMap map = orchestration.getParameters();
        String employeeType = getParamaterValue(map, UserManagerConstants.AttributeName.EMPTYPE.getId());
        eventLogger.info("[" + methodName + "]  Employee Type " + employeeType);
        String userId = generateEMPID(employeeType);
        System.out.println("[" + methodName + "]  got user Id " + userId);
        eventLogger.info("[" + methodName + "]   got user Id " + userId);
        map.put("User Login", userId);
        //generate home directory here we are updating another attribute
        map.put("Home Directory", "/home/" + userId);
        EventResult result = new EventResult();
        return result;
    }
    /**
     *
     * @param processId the processId
     * @param eventId the event Id
     * @param bulkOrchestration
     * @return
     */
    public BulkEventResult execute(long processId, long eventId, BulkOrchestration bulkOrchestration) {
        HashMap<String, Serializable>[] params = bulkOrchestration.getBulkParameters();
        for (int i = 0; i < params.length; i++) {
            HashMap<String, Serializable> orchParam = params[i];
            String employeeType = getParamaterValue(orchParam, UserManagerConstants.AttributeName.EMPTYPE.getId());
            String userId = generateEMPID(employeeType);
            orchParam.put(UserManagerConstants.AttributeName.USER_LOGIN.getId(), userId);
            //custom attribute
            orchParam.put("Home Directory", "/home/" + userId);
        }
        return new BulkEventResult();
    }

    public void compensate(long l, long l1, AbstractGenericOrchestration abstractGenericOrchestration) {
    }
    public boolean cancel(long l, long l1, AbstractGenericOrchestration abstractGenericOrchestration) {
        return false;
    }
    public void initialize(HashMap<String, String> hashMap) {
    }
    private String generateEMPID(String employeeType) {
        Long Id = null;
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        Connection con = null;
        Statement st = null;
        ResultSet rs = null;
        TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW));
        boolean rollback = false;
        try {
            con = Platform.getOperationalDS().getConnection();
            st = con.createStatement();
            eventLogger.info("[" + methodName + "] Before Executing query");
            if (employeeType.equalsIgnoreCase("Full-Time")) {
                rs = st.executeQuery("select USERID_FT.nextval from dual");
            } else if (employeeType.equalsIgnoreCase("Temp")) {
                rs = st.executeQuery("select USERID_TMP.nextval from dual");
            } else if (employeeType.equalsIgnoreCase("Consultant")) {
                rs = st.executeQuery("select USERID_CONS.nextval from dual");
            }
            //other conditions here
            if (rs.next()) {
                Id = rs.getLong(1);
            }
        } catch (Exception e) {
            rollback = true;
            eventLogger.severe("[" + methodName + "] Error occured in execution" + e.getMessage());
        } finally {
            try {
                if (rs != null) {
                    rs = null;
                }
                if (st != null) {
                    st = null;
                }
                if (con != null) {
                    con.close();
                }
                if (rollback)
                    txManager.rollback(txStatus);
                else
                    txManager.commit(txStatus);
            } catch (Exception e) {
                eventLogger.severe("[" + methodName + "] Error occured in execution" + e.getMessage());
            }
        }
        if (Id != null) {
            return Id.toString();
        } else
            return null;
    }
}
As this is pre process event handler all you have to do is place the new attribute value in the orchestration parameter map and it will be saved in the user profile. The generateEmpId method utilizes the transaction manager api.
The snippet for post process event is mentioned below.
package com.oimacademy.eventhandlers;
import java.io.Serializable;
import java.util.HashMap;
import oracle.adf.share.logging.ADFLogger;
import oracle.iam.identity.usermgmt.api.UserManagerConstants;
import oracle.iam.platform.Platform;
import oracle.iam.platform.context.ContextAware;
import oracle.iam.platform.entitymgr.EntityManager;
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;

public class GenerateEmailIds implements PostProcessHandler{
    private ADFLogger eventLogger=ADFLogger.createADFLogger(GenerateEmailIds.class);
    public GenerateEmailIds() {
        super();
    }
    /**
     * Gets the parameter value from parameter map
     * @param parameters
     * @param key
     * @return
     */
    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;
    }
    /**
     *
     * This method is used to populate the value for email id based on first name and last name
     * @param processId
     * @param eventId
     * @param orchestration
     * @return
     */
    public EventResult execute(long processId, long eventId, Orchestration orchestration) {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        eventLogger.entering(methodName, "params :["+processId+","+eventId+"]");
        EntityManager mgr=Platform.getService(EntityManager.class);
        HashMap map = orchestration.getParameters();
        String email=getParamaterValue(map, UserManagerConstants.AttributeName.EMAIL.getId());
        if(email==null||email.isEmpty()){
                String firstName=getParamaterValue(map, UserManagerConstants.AttributeName.FIRSTNAME.getId());
                String lastName=getParamaterValue(map, UserManagerConstants.AttributeName.LASTNAME.getId());
                String generatedEmail=generateEmail(firstName,lastName);
                HashMap modifyMap=new HashMap();
                modifyMap.put(UserManagerConstants.AttributeName.EMAIL.getId(),generatedEmail);
                try {
                    mgr.modifyEntity(orchestration.getTarget().getType(), orchestration.getTarget().getEntityId(), modifyMap);
                }catch (Exception e){
                    eventLogger.severe("[" + methodName + "] Error occured in updating user" + e.getMessage());
                    } 
            }
        // asynch events must return null
                return null;
 }
    /**
     * Generates email 
     * @param firstName
     * @param lastName
     * @return
     */
    private String generateEmail(String firstName, String lastName) {
        return null;
    }
    public BulkEventResult execute(long l, long l1, BulkOrchestration bulkOrchestration) {
        return null;
    }
    public void compensate(long l, long l1, AbstractGenericOrchestration abstractGenericOrchestration) {
    }

    public boolean cancel(long l, long l1, AbstractGenericOrchestration abstractGenericOrchestration) {
        return false;
    }
    public void initialize(HashMap<String, String> hashMap) {
    }
}
Note that post process events must return null as the event result as they are asynchronous event. The generate email is just a stub and is actually not implemented.

The event handler xml that you need to import into mds is mentioned below.
<?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">
   <action-handler class="com.oimacademy.eventhandlers.GenerateLoginID" entity-type="User" operation="CREATE" name="GenerateLoginIDs" stage="preprocess" order="1000" sync="FALSE"/>
   <action-handler class="com.oimacademy.eventhandlers.GenerateEmailId" entity-type="User" operation="CREATE" name="GenerateEmailIds" stage="postprocess" order="1001" sync="FALSE"/>
</eventhandlers>
Now for the logging part, in the snippets, i have used adflogger implementation. All you need to do to use it to add the logger with name com.blogspot to the oim server config, you could also add a log handler to place the logging output in a separate file.

No comments:

Post a Comment