Showing posts with label OIM Tutorial. Show all posts
Showing posts with label OIM Tutorial. Show all posts

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.

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.

Wednesday, 18 July 2018

Adding Command Button in OIM PS3 (Managed Bean Concept)

Adding a new command button in oi pages requires UI level customization, where you need to create managed bean. Managed Bean is a regular java bean registered with JSF or in other word, it is a java bean managed by JSF framework. If we create our own managed bean, then we can build our own Expression Language. Let us define a scenario first.

Scenario: Customer requires a button in catalog search page. When clicked, some popup message will be displayed.

In order to develop a custom managed bean, follow the below steps.

Pre-Requisite

Copy the jdev.lib folder from [OIM_HOME]/server directory to you local machine.

Development

1. Open JDeveloper IDE (I am using 11.1.1.7)
2. Click on new and create "Fusion Web Application (ADF)".


3. Follow the steps and click next to complete the creation of new application.
4. You can see there are 2 projects created Model and ViewController
3. Right click on ViewController project and click on New.
4. Choose Java from the left pane and select Java Class from the right pane.



5. click OK and provide the class name (e.g. CustomEventListener)


6. Click OK to create the java file.
7. the entire work space would look like below


8. Right click on the ViewController project and click on Project Properties.
9. In the properties page select Libraries and Classpath
10. Click on Add Library and and select the path of jdev.lib where you copied the shared libraries,
11. Add all three shared libraries from jdev.lib.



12. Click OK to close the window.
13. Now open the CustomEventListener.java and write below code as sample


package view;

import javax.faces.application.FacesMessage;
import javax.faces.event.ActionEvent;
import oracle.iam.ui.platform.utils.FacesUtils;

public class CustomEventListener {
    public CustomEventListener() {
        super();
    }
    
    public void testButtonActionListener(ActionEvent e) {
        
        System.out.println("This is a custom event listener");
        String loggedinUser = FacesUtils.getValueFromELExpression("#{oimcontext.currentUser['User Login']}").toString();
        FacesUtils.addFacesInformationMessage("This is a test message: "+loggedinUser);
        System.out.println("Current Logged In user: "+loggedinUser);
    }
        
}

**** The above code get the current logged in user from the OIM available EL and display a popup message.

9. Save the file. You can write your own logic.
10. Expand Web Content -> Page Flows and open adfc-config.xml
11. Under the Managed Bean section , click on + icon and add a new managed bean like below

Name: CustomELBean
Class: view.CustomEventListener
Scope: backingBean




12. Save the configuration.
13. Now we have to create the deployment profile. To do that, right click on the ViewController project and choose Deployment.

14. Delete the existing profile and click on New to add a new one.
15. From the Archive Type select ADF Library Jar File and in the Name put name of the jar (e.g. adflibTestEventListener1). Click OK to create the profile.


16. Click OK to finish the process.
18. Now right click on the ViewController project and click deploy and select the adflibTestEventListener1 to JAR file.


19. Now your adf library jar is ready for the deployment.

Deploying the Artifacts

1. Copy the oracle.iam.ui.custom-dev-starter-pack.war from OIM_HOME/server/apps directory to your local machine.

2. copy the adflibTestEventListener1.jar from the project deploy folder and move the same to oracle.iam.ui.custom-dev-starter-pack.war\WEB-INF\lib


3. Replace the modified oracle.iam.ui.custom-dev-starter-pack.war to the OIM_HOME/server/apps directory.

4. Stop the OIM managed server.
5. Delete the cache, tmp and stage folders from the [DOMAIN_HOME]/servers/[OIM_MANAGED_SERVER_NAME] directory

6. Start the OIM managed server.


Testing

1. Login into identity self service console using System Administrator privileges.
2. Import the below sandbox.


3. Activate the sandbox.
4. Go to the Self-Service home page and open catalog page.
5. Once the catalog page is opened, you can see an Extra button named Test. Clicking that button display a popup message with the logged-in user ID.




Note: sandbox contain a commandButton with actionListener property added like below

FileName: sandbox_button.zip\oracle\iam\ui\catalog\pages\mdssys\cust\site\site\access-request-train.jspx.xml

<?xml version='1.0' encoding='UTF-8'?>
<mds:customization version="11.1.1.66.73" xmlns:mds="http://xmlns.oracle.com/mds" motype_local_name="root" motype_nsuri="http://java.sun.com/JSP/Page">
   <mds:insert after="pt_pgl3(xmlns(f=http://java.sun.com/jsf/core))/f:facet[@name='separator']" parent="pt_pgl3">
      <af:commandButton xmlns:af="http://xmlns.oracle.com/adf/faces/rich" id="cb1001" text="Test" actionListener="#{backingBeanScope.customELBean.testButtonActionListener}"/>
   </mds:insert>
</mds:customization>

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: /************...