Wednesday, December 17, 2014

OIM 11g R2 API: Resource Account Parent Form Modifications

Tested On: Oracle Identity Manager 11.1.2.2.0
Description: Contains sample code to make modifications to a specific resource account parent form using the ProvisioningService API.
Referencehttp://docs.oracle.com/cd/E40329_01/apirefs.1112/e28159/toc.htm




Sample Code
package com.blogspot.oraclestack.utilities;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
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;

/**
 * Update parent form of a resource account on a user.
 * @author rayedchan
 * @version 1.0
 */
public class UpdateResoureProcessForm
{
    // 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 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);
            
            // Modify resource account
            HashMap<String, Object> modParentData = new HashMap<String, Object>();
            modParentData.put("UD_DBATUSR_FIRST_NAME", "Nick"); // Key = Resource attribute column name
            modParentData.put("UD_DBATUSR_LAST_NAME", "Taylor");
            modifyUserResourceAccountParentData(userKey, resourceAccount, modParentData);
        }

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

        finally 
        {
            // Logout user from OIMClient
            if (oimClient != null) { oimClient.logout();} 
        }
    }
    
    /**
     * 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) 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});

        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});
        
        // 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.");
    }
}

2 comments:

  1. [tid: OIMQuartzScheduler_Worker-7] [userId: oiminternal] [ecid: 0000LhMf9SQBT8NpQG8Dyd1OumsU000002,1:19733] [APP: oim#11.1.2.0.0] generic Exception while provisioning User An error occurred in oracle.iam.provisioning.spi.DOBProvisioningMechanism/modify while modifying account with account id 792650 for user BROWNFIN and the cause of error is key ::$bulkTaskCounter$ value ::1.


    I am getting this error when i am running my code in OIM server. When i run same code in Local it is working as expected. What could be the reason?

    ReplyDelete
    Replies
    1. I am getting the same error. This error is coming when scheduler "Task Timed Retry" scheduler runs. I am trying to troubleshoot this but don't know where to start. Does anyone have any idea why this error is coming?

      Delete