Monday, 2 August 2021

OIM API for adding process task and retry failed task

 In this blog you can find how to add new process task and retry any failed/rejected tasks using API.


Adding new process task:

/*******************************************************************************************
 * @param orcKey
 * @param taskKey
 * @throws Exception
 * Adding new process task.
 * SQL Query to find Task: Task Key (MIL_KEY) select mil_key,mil_name from mil where mil_name='User Principal Name Updated' 
 * and tos_key in (select tos_key from tos where tos_instance_src_field like 'UD_ADUSER.%');
 */
public void addTask (long orcKey, long taskKey)throws Exception{
    tcProvisioningOperationsIntf provAPI = oimClient.getService(tcProvisioningOperationsIntf.class);
    System.out.println("Added :::"+provAPI.addProcessTaskInstance(taskKey, orcKey)+" For ORC_KEY :: "+orcKey);
}


Retry failed/rejected task


/**
 *********************************************************************************************
 * @param ro
 * @param taskName
 * @param taskStatus
 * @throws Exception
 * Retrying Rejected task
 */
public void retryTask (String ro, String taskName, String taskStatus, String uid)throws Exception{
    tcProvisioningOperationsIntf provAPI = oimClient.getService(tcProvisioningOperationsIntf.class);
    
    Map filter = new HashMap();
    filter.put("Objects.Name", ro);
    filter.put("Process Definition.Tasks.Task Name", taskName);
    
    String taskStatus1[] = new String[] {taskStatus};
    Thor.API.tcResultSet rs = provAPI.findAllOpenProvisioningTasks(filter, taskStatus1);
    
    if (rs != null && rs.getTotalRowCount() > 0){
        System.out.println("Total Count :: "+rs.getTotalRowCount());
        for (int i=0; i< rs.getTotalRowCount(); i++){
            rs.goToRow(i);
            if (rs.getStringValue("Process Instance.Task Information.Target User").equalsIgnoreCase(uid)){
                System.out.println(rs.getStringValue("Process Instance.Task Information.Target User")+ 
				" :: "+rs.getStringValue("Process Definition.Tasks.Task Name")+ " :: done");
                provAPI.retryTask(rs.getLongValue("Process Instance.Task Details.Key"));
                break;
            }
        }
    }
}

Adding or Removing child record in OIM using API.

In this blog you can find, how to add or remove child record in OIM accounts using API. In this example I used AD connectors, but it is applicable to any connectors.


Adding child record:


private String APP_INSTANCE_NAME = "ActiveDirectory";
private String CHILD_TABLE_FIELD_NAME = "UD_ADUSRC_GROUPNAME";
private String CHILD_TABLE_NAME = "UD_ADUSRC";

/**
* userLogin: USR_LOGIN value
* accountName: account login name e.g. UD_ADUSER_UID for AD account
* childRecords: String contains List of child data with comma separated.
*/
public void addChildRecord(String userLogin,String accountName, String childRecords) {

    try {
        ProvisioningService provAPI = oimClient.getService(ProvisioningService.class);
        Account acc = null;
        List accList = provAPI.getAccountsProvisionedToUser(getUserKeybyUserLogin(userLogin));
        for (Account account : accList){
            if (account.getAccountDescriptiveField().equalsIgnoreCase(accountName) && 
                account.getAppInstance().getApplicationInstanceName().equalsIgnoreCase(APP_INSTANCE_NAME) &&
                (account.getAccountStatus().equalsIgnoreCase("Provisioned") ||
                account.getAccountStatus().equalsIgnoreCase("Enabled") || 
                 account.getAccountStatus().equalsIgnoreCase("Disabled"))){
                     
                     acc = provAPI.getAccountDetails(Long.parseLong(account.getAccountID()));
                 }
        }
        
        System.out.println("App :: " + acc.getAppInstance().getApplicationInstanceName());
        AccountData accData = acc.getAccountData();
        ArrayList childArray = new ArrayList();

        String[] childRecordList = childRecords.split(",");
        for (int k = 0; k < childRecordList.length; k++) {
            ChildTableRecord newChild = new ChildTableRecord();
            Map val1 = new HashMap();
            val1.put(CHILD_TABLE_FIELD_NAME,childRecordList[k].toString());
            newChild.setChildData(val1);
            newChild.setAction(ChildTableRecord.ACTION.Add);
            childArray.add(newChild);
        }
        System.out.println("childArray size :: " + childArray.size());
        Map> childData = new HashMap>();
        childData.put(CHILD_TABLE_NAME, childArray);
        accData.setChildData(childData);
        acc.setAccountData(accData);
        provAPI.modify(acc);
        System.out.println(" ===== Account Name :: " + acc.getAccountDescriptiveField() + " updated");

    } catch (Exception e) {
        e.printStackTrace();
    }
}


Removing child records

private String APP_INSTANCE_NAME = "ActiveDirectory";
private String CHILD_TABLE_FIELD_NAME = "UD_ADUSRC_GROUPNAME";
private String CHILD_TABLE_NAME = "UD_ADUSRC";

/**
* userLogin: USR_LOGIN value
* accountName: account login name e.g. UD_ADUSER_UID for AD account
* childRecords: String contains List of child data with comma separated.
*/
public void deleteChildRecord(String userLogin,String accountName, String childRecords) {

    try {
        ProvisioningService provAPI = oimClient.getService(ProvisioningService.class);
        Account acc = null;
        List accList = provAPI.getAccountsProvisionedToUser(getUserKeybyUserLogin(userLogin));
        for (Account account : accList){
            if (account.getAccountDescriptiveField().equalsIgnoreCase(accountName) && 
                account.getAppInstance().getApplicationInstanceName().equalsIgnoreCase(APP_INSTANCE_NAME) &&
                (account.getAccountStatus().equalsIgnoreCase("Provisioned") ||
                account.getAccountStatus().equalsIgnoreCase("Enabled") || 
                 account.getAccountStatus().equalsIgnoreCase("Disabled"))){
                     
                     acc = provAPI.getAccountDetails(Long.parseLong(account.getAccountID()));
                 }
        }
        System.out.println("App instance :: " + acc.getAppInstance().getApplicationInstanceName());
        AccountData accData = acc.getAccountData();
        ArrayList childRecArray = null;
        Map> childDataMap = accData.getChildData();
        for (Map.Entry> entry : childDataMap.entrySet()){
            if (entry.getKey().equalsIgnoreCase(CHILD_TABLE_NAME)){
                childRecArray = entry.getValue();
            }
        }
        String[] childRecordList = childRecords.split(",");
        ArrayList childArray = new ArrayList();
        for (String childRecordToDelete : childRecordList) {
            String row_key = null;
            for (ChildTableRecord childRecord : childRecArray) {
                Map childValMap = childRecord.getChildData();
                if (childValMap.get(CHILD_TABLE_FIELD_NAME).toString().equalsIgnoreCase(childRecordToDelete)) {
                    row_key = childValMap.get(CHILD_TABLE_NAME+"_KEY").toString();
                    System.out.println("row_key to be deleted :: " + row_key);
                }
            }

            if (row_key != null) {
                ChildTableRecord newChild = new ChildTableRecord();
                Map val1 = new HashMap();
                val1.put(CHILD_TABLE_FIELD_NAME, childRecordToDelete);
                newChild.setChildData(val1);
                newChild.setAction(ChildTableRecord.ACTION.Delete);
                newChild.setRowKey(row_key);
                childArray.add(newChild);
            }
        }
        
        if (childArray.size() > 0){
            System.out.println("childArray size :: " + childArray.size());
            Map> childData = new HashMap>();
            childData.put(CHILD_TABLE_NAME, childArray);
            accData.setChildData(childData);
            acc.setAccountData(accData);
            provAPI.modify(acc);
            System.out.println(" ===== Account Name :: " +acc.getAccountDescriptiveField() + ": updated");
        }else{
            System.out.println(" ===== Account Name :: " +acc.getAccountDescriptiveField() + ": No data to delete");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private String getUserKeybyUserLogin(String userLogin) throws Exception {
    UserManager userAPI =
        (UserManager)oimClient.getService(UserManager.class);
    Set retAttrs = new HashSet();
    User userDetails = userAPI.getDetails(userLogin, retAttrs, true);
    return userDetails.getEntityId();
}

Saturday, 19 September 2020

OIM EL Expressions

 Here are the few available EL expression that we can use in OIM UI. We can use this EL to customize self-service UI.


Category

Usage

EL [Expression Language]

User

Get
the current user’s attribute value by passing the attribute name

#{oimcontext.currentUser['ATTRIBUTE_NAME']}

User

Similarly get
the value for a UDF

#{oimcontext.currentUser['UDF_NAME']}

User

Gets
the roles assigned to current user. Returns list of RoleEntity objects. It is
a Java Bean having name, description, key, and displayName properties

#{oimcontext.currentUser.roles}

User

Return true if
user is a system administrator

#{oimcontext.currentUser.roles['SYSTEM ADMINISTRATORS'] ne null}

 

User

Returns
true if user is assigned with admin role

'OrclOIMSystemAdministrator'

#{oimcontext.currentUser.adminRoles['OrclOIMSystemAdministrator'] ne null}

 

User

Returns user
key

#{oimcontext.currentUser.usr_key}

 

User

Returns
user key

#{oimcontext.currentUser['usr_key']}

 

User

Returns user
login

#{oimcontext.currentUser['User Login']}

 

Request

Returns
current operation. Possible values: CREATE/MODIFY

#{pageFlowScope.requestFormContext.operation}

 

Request

Returns true if
the current operation is Modify

#{pageFlowScope.requestFormContext.operation eq 'MODIFY'}

 

Request

Return
the current action type. Possible values: APPROVAL/ FULFILL/ REQUEST/ VIEW/ SUMMARY.

On all
approval pages/ approver view the value is APPROVAL

For
Manual fulfillment page the value is FULFILL

#{pageFlowScope.requestFormContext.actionType}

 

Request

Returns true if
the action type is Request i.e. the user is about to submit the request

#{pageFlowScope.requestFormContext.actionType eq 'REQUEST'}

 

Request

Returns
true if the request is bulk

#{pageFlowScope.requestFormContext.bulk}

 

Request

Returns beneficiaries
user ids[user login values]

#{pageFlowScope.requestFormContext.beneficiaryIds}

 

Request

Returns
keys for cart items

#{pageFlowScope.requestFormContext.cartItemIds}

 

Request

Returns the
type of item added to request. Possible values: ROLE/ ENTITLEMENT/
APP_INSTANCE/ USER.

#{pageFlowScope.requestFormContext.requestEntityType}

 

Request

Returns
true if added item is Application Instance

#{pageFlowScope.requestFormContext.requestEntityType eq 'APP_INSTANCE'}

 

Request

Returns application
instance key for the item added

#{pageFlowScope.requestFormContext.requestEntitySubType}

 

Request

Returns
provisioned instance key for a modify type request

#{pageFlowScope.requestFormContext.instanceKey}

 

General

Invoke a method
present on backing bean

#{backingBean.<Bean Name>.<bean method>}

General

To
show a field disabled on all FULFILL and APPROVAL pages

disabled="#{pageFlowScope.requestFormContext.actionType}


Monday, 13 April 2020

OIM UI Customization using ADF - Adding custom tile application

I have prepared a series of video tutorials on OIM UI customization using ADF, where I have demonstrated how we can add a new tile application on OIM self service page.

If you follow the step by step process, as demonstrated in this tutorials, you will be able to integrate your own web application into OIM self service page as a new dashboard tile.

#1: Environment setup
#2: Adding Custom Tile Application (Part 1)
#3: Adding Custom Tile Application (Part 2)
#4: Adding Custom Tile Application (Part 3)
#5: Adding Custom Tile Application (Part 4)

More videos are on the way. Please Like & Subscribe my channel, so that you will get notification once I upload new videos.

Wednesday, 6 March 2019

Managing Service Account in OIM 11gR2 PS3

Service Account concept was highly used during 9i version of OIM. In 11gR2 PS3 service account options are there from UI there is no option to move the Service Account to different users. here are the API sample for converting an OIM account to a Service Account and move the same to other user.

1. First Java Code: is to mark an account to Service Account
2. Second Java Code: is to get whether an account is Service Account or not.
3. Third Java Code: is to transfer a Service Account to other user.



After executing the third java code, the service account will be completely moved to a new target user.

Monday, 28 January 2019

OIM PS3 Automated Testing Using Selenium

OIM's UI functionalities can be tested by automation tool like Selenium. There are lot of test cases we need to perform on OIM UI, after doing some developments or implementation (just to verify whether all existing functionalities are working fine). Some time it is very painful job to perform all per-defined test cases again and again. Using Selenium, all the UI based pre-defined test cases can be executed automatically with out any human intervention, and this way we can achieve automated testing on OIM, which is faster than manual testing, efficient and error free.

this blog will give an example of how we can build Selenium test script for OIM.

Selenium test script works on web element of an web page, like button, link etc. If we can identify those element, then it is not a very difficult job to build a test script for a scenario.

for example, I need to perform the below scenario on OIM PS3

************ As Requester ************************
 1. Login to OIM identity console as requester.
 2. Go to catalog and search for a disconnected application "".
 3. Click on Add To cart and checkout.
 4. Fill the application form.
 5. Provide business justification and submit the request.
 6. Logout from the OIM Identity console.

**************** As Approver *********************
 7. Login to OIM identity console as approver.
 8. Go to Pending Approval and search for the requested id generated by requester.
 9. Select the request and approve the same.
10. Logout from OIM Identity console.

**************** As Implementer *******************
11. Login to OIM Identity console as implementer.
12. Go to Pending Fulfillment and Search for the request id generated by requester.
13. Select the request and complete the same.
14. Now go to Track Request and verify the status of the request.

If I need to perform the automated testing of the above test scenario, I have to convert each and every steps with selenium methods. for example I if need to click a button or enter text into a text field, I need to first get the XPath or Element id of those components. Then using those details selenium can identify those element in  browser and perform action (like click or enter data).

in my case //*[@id=\"pt1:_pt_it1::content\"] is the XPath representation of User Login field of OIM login page. similarly //*[@id=\"pt1:_pt_cb1\"] is for Submit button, and so on.





Now here is the full Java code for Selenium Test. For basic of Selenium and how to setup environment refer Selenium HQ

Please check the below video for how the actual testing looks like.



Please note, all the XPaths mentioned in the above code, may not be exactly same for you (before running the test, verify all the XPaths form chrome browser).

Friday, 20 July 2018

Reverse Engineering on OIM Event Handlers

If someone give me an OIM environment and ask to find out all the event handlers deployed on it and their associated class, it is not that easy process to find out. In this article, I am going to describe how one can find all the event handlers (User, Role etc.) and their qualified class name deployed on OIM (PS3).

Before we start, we need to understand where we generally use event handlers in OIM. It is used normally during any OIM events like create/modify/delete/disable/enable of users or assign/revoke role etc. where create, modify, delete, assign are kind of operation and user, role are entities.

In order to find out how many event handlers are there, follow the below steps:

1. Login to weblogic EM console and expand Identity and Access -> OIM -> oim(11.1.2.0.0)

2. Right click on it and select System MBean Browser.

3. Now naviage to oracle.iam -> server:oim -> Application:oim -> IAMAppDesignMBean

4. Click on ConfigQueryMBeanName

5. From right hand window, click on Operations




6. Click on the getEventHandlers.



7. In the parameter section put the parameter as below:
                  P1 --> Entity Type (user, role etc.)
                  P2 --> Operation (create, modify, delete etc.).

8. Once done click on Invoke.

9. It will display the result in the same page.


10. The output list contains all the event handlers’ doc available in the MDS.

11. It contains validation, pre-process, action, post process along with out of band handlers.

12. Each row contains 5 columns as below
              Stage: whether it is validation, pre-process, action or post process
              Order: Order number of the handlers.
              Name: name of the event handlers
              Location: the document location in MDS
              Conditional: true or false

13. Now pick the appropriate one you need to check further. Normally you can find out from the name.

14. Copy the MDS doc location.

15. Now navigate to oracle.mds.lcm -> Server:oim -> Application: OIMAppMetadata -> MDSAppRuntime

16. Click on MDSAppRuntime and from the right hand panel click on Operations



17. Now click on the first exportMetadata link as mentioned in the picture.


18. In the parameter section we have to provide 2 parameters as below:
              toLocation: Location where file will be downloaded (in the server where OIM is installed)
              docs: name of the MDS doc. In order to enter the doc, click on the pencil icon and add the doc like below. You can add more than one doc at a time. Click OK.



19. Once all the parameters are given click on Invoke.


20. If invoke is successful then success message will be displayed.

21. After this operation, login to the host machine and go to the mentioned output location.

22. You can find the directory structure as per the doc name and the file as below


23. Open the file in editor mode and check the list of event handler defined. You can find the list of event handlers like below:

<action-handler orch-target="oracle.iam.platform.kernel.vo.EntityOrchestration" class="oracle.iam.identity.usermgmt.impl.handlers.custom.CustomPostProcessHandler" entity-type="User" operation="CREATE" name="CustomPostProcessHandler" stage="postprocess" sync="TRUE" order="2000000"/>

24. Now you can get your desired event handler and their associated class name.

Note: if you want to change some of the existing event handlers functionality, simply change the class name and re-import.

Followers

OIM API for adding process task and retry failed task

 In this blog you can find how to add new process task and retry any failed/rejected tasks using API. Adding new process task: /************...