Monday, 5 September 2011

OIM11G Request Creation via API


  long resKey = 0L;
       String str = null;
       String resourceKey = null;
       Map<String, String> searchMap = new HashMap<String, String>();
       tcResultSet resultSet = null;                                  
       RequestData requestData = null;                               
       Beneficiary beneficiary = null;                    
       RequestBeneficiaryEntity entity = null;                       
       List<Beneficiary> beneficiaryList = null;                      
       List<RequestBeneficiaryEntity> entityList = null;              
       List<RequestBeneficiaryEntityAttribute> entityAttrList = null; 
 
       searchMap.put(RESOURCE_ATTR_NAME, RESOURCE);
       resultSet = _resourceService.findObjects(searchMap);
       resKey = resultSet.getLongValue(RESOURCE_ATTR_KEY);
       resourceKey = Long.toString(resKey);       
     
       RequestBeneficiaryEntityAttribute parantAttr = new RequestBeneficiaryEntityAttribute();
       parantAttr.setType(TYPE.String);
       parantAttr.setName("Title");
       parantAttr.setValue("Mr.");
  
       entityAttrList = new ArrayList<RequestBeneficiaryEntityAttribute>();
       entityAttrList.add(parantAttr);
  
       entity = new RequestBeneficiaryEntity();
       entity.setEntityKey(resourceKey);  
       entity.setEntityType(RequestConstants.RESOURCE);
       entity.setEntitySubType(RESOURCE); 
       entity.setEntityData(entityAttrList);
  
              entityList = new ArrayList<RequestBeneficiaryEntity>();
       entityList.add(entity);
 
       beneficiary = new Beneficiary();
       beneficiary.setBeneficiaryType(Beneficiary.USER_BENEFICIARY);
       beneficiary.setBeneficiaryKey(USER_KEY);
       beneficiary.setTargetEntities(entityList);      
   
       requestData = new RequestData();
       requestData.setRequestTemplateName(TEMPLATE);
       requestData.setJustification("Test");
       requestData.setBeneficiaries(beneficiaryList);
   
       RequestService reqsrvc = client.getService(RequestService.class);       
     
       str = reqsrvc.submitRequest(requestData);
       
       System.out.println("Value from submitRequest : '" + (str != null ? str : null) + "'");
 

Wednesday, 31 August 2011

OIM11G Cluster Installation Post Configuration for SOA

When running the IDM configuration wizard we are required to enter the load balancer URL but load balancer is not required for clustered installation. Thus URL for oim_server1 can be entered in the wizard and configuration be completed.
Now if in the clustered installation there are two oim severs (oim_server1, oim_server2 [oim_cluster]) and two soa servers (soa_server1, soa_server2 [soa_cluster]), there would be issues in approval flows if
oim_sever1 is shutdown (leaving oim_server2 and both the soa server running). The approvals would fail and in the BPEL fault we will see that the Approval Callback is trying to send the response back to oim_server1 rather then oim_server2. If we start back oim_server1 than the approvals along with call backs work fine.
Another scenarios which can be tried is to shut down oim_server2 instead of oim_server1 & than the approvals would works fine.
With the above test we can see that configuration is pointing the oim server to oim_server1 host rather than a cluster. So how to configure the domain post installation so that SOA would point to both the oim servers and would automatic failover? This can be done by changing the oimFrontEndUrl  in the oim-config.xml. This value can be changed to point to any proxy server (say OHS, Apache) and use the mod so plugin at the proxy and redirect requests from proxy to OIM cluster.

OIM11G Cluster Configuration

While doing clustered installation of OIM and SOA there is no way to define which component (SOA, OIM) is installed on the defined managed server at the time of installation. The document syas that when you first enter the configure managed servers screen, two managed servers called oim_server1 and soa_server1 are created automatically. Rename soa_server1 to WLS_SOA1 and oim_server1 to WLS_OIM1 and update their attributes as required for host/port and  then, add two new managed servers called WLS_OIM2 and WLS_SOA2 .Thus if four servers (Two OIM and two SOA) are defined in the domain then there is not way to know which servers are going to target the OIM application(s) and it's librarie(s) and which server is going to have the SOA application(s) and librarie(s). It surely does not work based on name like if server name contains OIM then that server is going to target OIM binaries and what happens if I want my servers to be named as instance1, instance2, instance3 and so on ....

The above problem can be solved by adding the servers in the domain creation wizard in a specified order or sequence. In the configure managed servers screen, the first server and each odd server entered is always the OIM server and the second server and each even server is the SOA server.


Automatic Request Dataset generation in OIM11G

OIM11G has the concept of datasets instead of object forms and these datasets are xml files which as I understand the document (or did till now)  has to be created manually. This xml file again have specific place holders for the resource name and the type of model to be used for the dataset and etc. Since this is created manually thus there are chances of typos/missing of tags etc which we can find only while uploading the data set into MDS (again are not very user friendly messages).
Thus a tool would be a great way to generate a dataset based on the process form and the provisioning process automatically. The xml file thus generated can be modified accordingly manually later on for any special requirements.
Thinking along the same lines I was trying to come up with a design of such a tool and hit upon this class  ‘oracle.iam.requestDataSetGeneration.impl.RequestDataSetGenrationUtil’ (inside OIMServer.jar). This class can be used as a standalone class to generate the dataset automatically for all the 6 request models for any resource, the only requirement is that the resource form and the provisioning process should be set in OIM or without any input it will create dataset for all the resources!
I tested the tool for few of the resources configured in my environment and all the datasets were created correctly with various widgets like lookup, text, date and etc.

This class is present in OIM11.1.1.3 and has been removed from OIM11.1.1.5, so make sure to get the OIMServer.jar from 11.1.1.3 to use this utility.

OIM11G Add addtional search criteria for user search during request creation

OOTB OIM11G request creation wizard provides only few fields to perform search criteria for user search. The following way can be used to add additonal search criteria fields to the wizard.

For example adding Employee Number to the user search criteria, perform the following steps:

1. Take a backup of the file:
$OIM_ORACLE_HOME/server/apps/oim.ear/iam-consoles-faces.war/WEB-INF/lib/OIMUI.jar

Note: Do NOT place the backup under $OIM_ORACLE_HOME. Use a location outside $MW_HOME for the backup!

2. Unzip the file OIMUI.jar
3. Edit the file
OIMUI.jar/oracle/iam/request/self/agentry/resources/Agent.xml and add the following section under USER_SEARCH_SHUTTLE_CAT (or USER_ENTITY_SEARCH_SHUTTLE_CAT
) form as shown below:

<Form>
  <Id>
    USER_SEARCH_SHUTTLE_CAT
  </Id>
   <Elements>
    <Criteria>
...
...
<Attribute>
  <Id>
    Employee Number
  </Id>
  <TransId>
    REQ_USER_EMP_NO
  </TransId>
  <Values minLimit="1">
  <DataType>
   TEXT
  </DataType>
  <Comparators>
  <Comparator>
   EQUALS
  </Comparator>
  </Comparators>
  <Value className="java.lang.String">
   <Comparator>
    EQUALS
   </Comparator>
   </Value>
   </Values>
</Attribute>
...
...


4. Add the following line in the file:
OIMUI.jar/oracle/iam/request/self/agentry/resources/Agent.properties

Attribute[REQ_USER_EMP_NO].name=Employee Number

5. Add the following line in the file:

OIMUI.jar/oracle/iam/request/self/agentry/resources/Agent_en.properties
Attribute[REQ_USER_EMP_NO].name=Employee Number

Note: also add the translation in the proprieties files for the other languages.

6. Repackage the OIMUI.jar
7. Restart the OIM managed server and check the create request wizard

How to extend Payload from OIM to SOA in OIM11G

At times it is required to connect to OIM from SOA BPEL flow to get additional attributes. This requires using oimClient to log in into OIM from SOA Java activity and querying the OIM database using APIs or queries. This can lead to performance issue as login into OIM takes time and then there is issue of not being able to share objects between various activities between SOA activities. Thus there has to be multiple logins from each activity and proper coding standards to be followed of log out of OIM in each activity. As a workaround, the OOTB payload can be extended to send me more attributes from OIM to SOA during approval processing.
This extending requires creating of plugin class and plugin point xml and uploading the plugin into OIM. This plugin would intercept the payload before it is sent to SOA and would add the other required attributes to it.

Implement the RequestPayloadFieldGenerator interface and use the following way to add additional fields in the method populateAdditionalPayloadField
@Override
public void populateAdditionalPayloadFields(RequestData requestdata, Process payload) {
// Get the details form payload in which you want to modify data element.
// e.g.: If you want to  modify data elements in other details

OtherDetails otherDetails = payload.getOtherDetails();

// Get the data elements list
List<Detailtype> detailtypesList = otherDetails.getDataElement();

//set your detail type in existing list
Detailtype detailtype = new Detailtype();
detailtype.setName(“Custom Attribute1”);
detailtype.setValue(“Custom VALUE1”);
detailtypesList.add(detailtype);
payload.setOtherDetails(otherDetails);

// Now the payload will be updated with above data element in other details section.
}
}
Plugin point definition file:

<?xml version='1.0' encoding='UTF-8'?>
<oimplugins xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oracle.com/schema/oim/plugin plugin.xsd">
<plugins pluginpoint="oracle.iam.request.plugins.RequestPayloadFieldGenerator">
<plugin pluginclass="com.oim.iam.payload.PayloadAdder " version="1.1" name=" PayloadAdder ">
<metadata name="DefaultPlugin">
<value>true</value>
</metadata>
</plugin>
</plugins>
</oimplugins>

How to get DataProvider in OIM11G

Dataprovider can be accessed in Schedule Tasks, Event Handlers and Adapters.
To get instance of the dataprovider one can use the following way:

XLDatabase.getInstance().getDatabase()


To compile the code, we would need to add the xlDataObjects.jar from designconsole lib directory.