Tuesday, December 23, 2014

Update Child Process Form via API

Version: Oracle Identity Manager 11.1.2.2.0
Description: Uses the Oracle Identity Manager API to make updates (add, delete, and modify) on a resource account child form.
Reference: http://docs.oracle.com/cd/E40329_01/apirefs.1112/e28159/toc.htm
Source Code
package com.blogspot.oraclestack.utilities;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.platform.OIMClient;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;
import oracle.iam.provisioning.api.ProvisioningConstants;
import oracle.iam.provisioning.api.ProvisioningService;
import oracle.iam.provisioning.exception.AccountNotFoundException;
import oracle.iam.provisioning.exception.GenericProvisioningException;
import oracle.iam.provisioning.exception.UserNotFoundException;
import oracle.iam.provisioning.vo.Account;
import oracle.iam.provisioning.vo.AccountData;
import oracle.iam.provisioning.vo.ChildTableRecord;
import oracle.iam.provisioning.vo.ChildTableRecord.ACTION;

/**
 * Update a child process form for a speicifc resource account.
 * @author rayedchan
 * @version 1.0
 */
public class UpdateChildProcessForm
{
    // Environment specfic constants
    public static final String OIM_HOSTNAME = "localhost";
    public static final String OIM_PORT = "14000";
    public static final String OIM_PROVIDER_URL ="t3://" + OIM_HOSTNAME + ":" + OIM_PORT;
    public static final String OIM_USERNAME = "xelsysadm";
    public static final String OIM_PASSWORD = "Password1";
    public static final String OIM_CLIENT_HOME ="/home/oracle/jdeveloper/mywork/OracleIdentityManager/Resources/oimclient";
    public static final String AUTHWL_PATH =OIM_CLIENT_HOME + "/conf/authwl.conf";
    
    // Constants for testing
    public static final String USER_LOGIN = "ntaylor";
    public static final String RESOURCE_OBJECT_NAME = "DBAT USER";
    public static final String CHILD_PROCESS_FORM_NAME = "UD_DBATRO";
    public static final String CHILD_ATTRIBUTE_NAME = "UD_DBATRO_ROLE";

    public static final ODLLogger logger = ODLLogger.getODLLogger(UpdateResoureProcessForm.class.getName());
    public static ProvisioningService provOps = null;
    public static UserManager usrMgrOps = null;
    
    public static void main (String[] args) 
    {
        OIMClient oimClient = null;

        try 
        {
            // Set system properties required for OIMClient
            System.setProperty("java.security.auth.login.config", AUTHWL_PATH);
            System.setProperty("APPSERVER_TYPE", "wls");

            // Create an instance of OIMClient with OIM environment information
            Hashtable env = new Hashtable();
            env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL,"weblogic.jndi.WLInitialContextFactory");
            env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, OIM_PROVIDER_URL);
            oimClient = new OIMClient(env);

            // Login to OIM with the approriate credentials
            oimClient.login(OIM_USERNAME, OIM_PASSWORD.toCharArray());
            
            // Get OIM services
            provOps = oimClient.getService(ProvisioningService.class);
            usrMgrOps = oimClient.getService(UserManager.class);
            
            // Get usr_key
            String userKey = getUserKeyByUserLogin(USER_LOGIN);
            
            // Get user's resource account
            Account resourceAccount = getUserResourceAccount(userKey, RESOURCE_OBJECT_NAME);
            
            // Get account's child data
            Map<String, ArrayList<ChildTableRecord>> childData = resourceAccount.getAccountData().getChildData();
            logger.log(ODLLevel.NOTIFICATION, "Resource Account Child Data: {0}", new Object[]{childData});
            printResourceAccountChildData(childData);
            
            // Staging objects
            HashMap<String, Object> modParentData = new HashMap<String, Object>();
            Map<String, ArrayList<ChildTableRecord>> modChildData = new HashMap<String, ArrayList<ChildTableRecord>>();
            ArrayList<ChildTableRecord> modRecords = new ArrayList<ChildTableRecord>(); 
            
            // Stage Add Child Record
            HashMap<String,Object> addRecordData = new HashMap<String,Object>();
            addRecordData.put(CHILD_ATTRIBUTE_NAME, "Engineer");
            ChildTableRecord addRecord = new ChildTableRecord();
            addRecord.setAction(ACTION.Add);
            addRecord.setChildData(addRecordData);
            modRecords.add(addRecord);
            
            // Stage Modify Child Record
            //HashMap<String,Object> modifyRecordData = new HashMap<String,Object>();
            //modifyRecordData.put(CHILD_ATTRIBUTE_NAME, "Engineer II");
            //ChildTableRecord modifyRecord = new ChildTableRecord();
            //modifyRecord.setChildData(modifyRecordData);
            //modifyRecord.setAction(ACTION.Modify);
            //modifyRecord.setRowKey(getChildRecordKeyByValue(CHILD_PROCESS_FORM_NAME, CHILD_ATTRIBUTE_NAME,  "Engineer", resourceAccount)); // <UD_TABLE>_KEY (Child Record Key)
            //modRecords.add(modifyRecord);
            
            // Stage Remove Child Record
            //HashMap<String,Object> removeRecordData = new HashMap<String,Object>();
            //ChildTableRecord removeRecord = new ChildTableRecord();
            //removeRecord.setChildData(removeRecordData);
            //removeRecord.setAction(ACTION.Delete);
            //removeRecord.setRowKey(getChildRecordKeyByValue(CHILD_PROCESS_FORM_NAME, CHILD_ATTRIBUTE_NAME,  "Engineer", resourceAccount)); // <UD_TABLE>_KEY (Child Record Key)
            //modRecords.add(removeRecord);
            
                    
            modChildData.put(CHILD_PROCESS_FORM_NAME, modRecords); // Put Child Form Name and its modified child data
            modifyUserResourceAccountParentData(userKey, resourceAccount, modParentData, modChildData); // Modify resource account                
        }

        catch (Exception ex) {logger.log(ODLLevel.ERROR, "", ex);} 

        finally 
        {
            // Logout user from OIMClient
            if (oimClient != null) { oimClient.logout();} 
        }
    }
    
    /**
     * Get the row key of a child record
     * @param childFormName         Name of the Child Form to inspect
     * @param childAttributeName    Name of the child attrribute used as a criteria
     * @param childAttributeValue   Value of the childAttributeName to search agaimst
     * @param resourceAccount       The user's resource account
     * @return  Child Record Key
     * @throws Exception
     */
    public static String getChildRecordKeyByValue(String childFormName, String childAttributeName, String childAttributeValue, Account resourceAccount) throws Exception 
    {
        Map<String, ArrayList<ChildTableRecord>> childData = resourceAccount.getAccountData().getChildData();
        logger.log(ODLLevel.NOTIFICATION, "Resource Account Child Data: {0}", new Object[]{childData});
        
        // Child Data Iterator 
        Iterator iter = childData.entrySet().iterator();
        
        // Iterator each child form
        while(iter.hasNext()) 
        {
            Map.Entry pairs = (Map.Entry) iter.next();
            String currentChildFormName = (String) pairs.getKey();
            ArrayList<ChildTableRecord> childFormData = (ArrayList<ChildTableRecord>) pairs.getValue();
            logger.log(ODLLevel.NOTIFICATION, "[Child Form Name: {0}], [Child Form Data: {1}]", new Object[]{childFormName, childFormData});
            
            if (currentChildFormName.equals(childFormName))
            {
                // Iterate records in a child form
                for (ChildTableRecord record : childFormData) 
                {
                    ACTION action = record.getAction();
                    Map<String, Object> childRecordData = record.getChildData();
                    String rowKey = record.getRowKey();
                    String attributeValue = (String)childRecordData.get(childAttributeName);
                    
                    if (attributeValue.equals(childAttributeValue)) 
                    {
                        logger.log(ODLLevel.NOTIFICATION, "[Action: {0}], [Child Record Data: {1}], [Row Key: {2}]", new Object[]{action, childRecordData, rowKey});
                        return rowKey;
                    }
                }
            }
        }
        
        // Child Value does not exist
        throw new Exception("Child Value does not exist");
    }
    
    
    /**
     * Get a specific user's resource account 
     * @param userKey       `       OIM user's usr_key
     * @param resourceObjectName    Name of the resource object
     * @return  Resource account 
     * @throws UserNotFoundException
     * @throws GenericProvisioningException
     */
    public static Account getUserResourceAccount(String userKey, String resourceObjectName) throws UserNotFoundException, GenericProvisioningException
    {
        boolean populateAccountData = true;
        HashMap<String,Object> configParams = new HashMap<String,Object>();
        SearchCriteria criteria =  new SearchCriteria(ProvisioningConstants.AccountSearchAttribute.OBJ_NAME.getId(), resourceObjectName, SearchCriteria.Operator.EQUAL);
        List<Account> accounts = provOps.getAccountsProvisionedToUser(userKey, criteria , configParams , populateAccountData);
        
        for (Account account : accounts) 
        {
            String accountId = account.getAccountID();
            String appInstName = account.getAppInstance().getApplicationInstanceName();
            Map<String, Object> accountData = account.getAccountData().getData();
            String accountStatus = account.getAccountStatus();
            logger.log(ODLLevel.NOTIFICATION, "Account Id: [{0}], Application Instance Name: [{1}], Account Status: [{2}], Account Data:[{3}]", new Object[]{accountId, appInstName, accountStatus, accountData});
            
            // Only return enabled, provisioned, or disabled account
            if(ProvisioningConstants.ObjectStatus.PROVISIONED.getId().equals(accountStatus) || ProvisioningConstants.ObjectStatus.ENABLED.getId().equals(accountStatus) || ProvisioningConstants.ObjectStatus.DISABLED.getId().equals(accountStatus)) 
            {
                logger.log(ODLLevel.NOTIFICATION, "Return Account Id: [{0}]", new Object[]{accountId});
                return account;
            }
        }
        
        return null;
    }
    
    /**
     * Get the user's usr_key 
     * @param userLogin OIM.User Login      (USR_LOGIN)
     * @return value of usr_key
     * @throws NoSuchUserException
     * @throws UserLookupException
     */
    public static String getUserKeyByUserLogin(String userLogin) throws NoSuchUserException, UserLookupException
    {
        boolean userLoginUsed = true;
        HashSet<String> attrsToFetch = new HashSet<String>();
        attrsToFetch.add(UserManagerConstants.AttributeName.USER_KEY.getId());
        attrsToFetch.add(UserManagerConstants.AttributeName.USER_LOGIN.getId());
        User user = usrMgrOps.getDetails(userLogin, attrsToFetch, userLoginUsed);
        logger.log(ODLLevel.NOTIFICATION, "User Details: {0}", new Object[]{user});
        return user.getEntityId();
    }
    
    /**
     * Modifies a resource account on an OIM user
     * @param userKey           OIM usr_key
     * @param resourceAccount   Existing resource account to modify
     * @param modAttrs          Attributes to modify on the paraent form
     * @throws AccountNotFoundException
     * @throws GenericProvisioningException
     */
    public static void modifyUserResourceAccountParentData(String userKey, Account resourceAccount, HashMap<String, Object> modAttrs, Map<String, ArrayList<ChildTableRecord>> modChildData) throws AccountNotFoundException, GenericProvisioningException 
    {
        // Stage resource account modifcations
        String accountId  = resourceAccount.getAccountID();
        String processFormInstanceKey = resourceAccount.getProcessInstanceKey();
        Account modAccount = new Account(accountId, processFormInstanceKey, userKey);
        logger.log(ODLLevel.NOTIFICATION, "Account Id: [{0}], Process Form Instance Key: [{1}]", new Object[]{accountId, processFormInstanceKey});

        // Setup account data object
        String formKey = resourceAccount.getAccountData().getFormKey();
        String udTablePrimaryKey = resourceAccount.getAccountData().getUdTablePrimaryKey();
        AccountData accountData = new AccountData(formKey, udTablePrimaryKey , modAttrs);
        logger.log(ODLLevel.NOTIFICATION, "Form Key: [{0}], UD Table Primary Key: [{1}]", new Object[]{formKey, udTablePrimaryKey});
        accountData.setChildData(modChildData); // set child data
        
        // Set necessary information to modified account
        modAccount.setAccountData(accountData);
        modAccount.setAppInstance(resourceAccount.getAppInstance());

        // Modify resource account
        provOps.modify(modAccount);
        logger.log(ODLLevel.NOTIFICATION, "Modification successful.");
    }
    
    /**
     * Prints the child data in each child form of a resource account.
     * @param childData   Child data of user's resource account
     */
    public static void printResourceAccountChildData(Map<String, ArrayList<ChildTableRecord>> childData) 
    {
        // Child Data Iterator 
        Iterator iter = childData.entrySet().iterator();
        
        // Iterator each child form
        while(iter.hasNext()) 
        {
            Map.Entry pairs = (Map.Entry) iter.next();
            String childFormName = (String) pairs.getKey();
            ArrayList<ChildTableRecord> childFormData = (ArrayList<ChildTableRecord>) pairs.getValue();
            logger.log(ODLLevel.NOTIFICATION, "[Child Form Name: {0}], [Child Form Data: {1}]", new Object[]{childFormName, childFormData});
            
            // Iterate records in a child form
            for (ChildTableRecord record : childFormData) 
            {
                ACTION action = record.getAction();
                Map<String, Object> childRecordData = record.getChildData();
                String rowKey = record.getRowKey();
                logger.log(ODLLevel.NOTIFICATION, "[Action: {0}], [Child Record Data: {1}], [Row Key: {2}]", new Object[]{action, childRecordData, rowKey});
            }
        }
    }   
}

No comments:

Post a Comment