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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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