OIM 11g R2 being such a comprehensive provisioning solution, it provides API’s for almost every aspect of functionality available in the product. This makes it a little difficult to decide which examples are needed the most in the documentation. Fortunately, the documentation does supply samples that can definitely serve as a foundation for more complex pieces of code. Some of the API’s I found developers using more often than others are the ones related to the operations associated with users’ requests for resources. Amongst those the following API’s are mostly required:
- Request Creation/Submission
- Request History Data Access
- Child Table Data Manipulation
- Approval Information Data Access
This blog post will include a few samples on how to accomplish each one of the above mentioned operations within the context of a use case described shortly. The intent is to provide some useful API’s code samples that customers and partners can use to write their own custom code that requires such functionality.
As a starting point for this article, I figured that the best way to describe a series of API code samples is by using a use case. Here is ours:
A Home Building Company requires their Engineers and Site Managers to carry handheld devices (Smart Phones, Tablets, Radios) to keep information about their projects and also maintain communication with the corporate office. These devices are provisioned to their users along with a specific list of services enabled on the device. The users are provisioned these resources through the following process:
When the user is on boarded, it gets assigned to an Organization according to their role (Engineer, Architect, Site Manager, Designer, Sales Associate, etc). Depending on the organization the users belong to a certain type of device with specific capabilities can be requested. Users submit their requests for a device and a set of capabilities through OIM. Now, the request for provisioning of the resource is not supposed to reach the administrator that will setup the contract for the device until all the individual services that will be enabled in the contract are approved. The fact that a device service is requested doesn’t mean it will be granted to the requester. Each individual service requires a different set of approvals. Once all the requested services have been processed (approved or denied) then the request arrives in the administrator’s queue.
According to the Use Case described previously, the design of a solution that addresses the requirements needs to leverage the concept of Disconnected Application Instance. In this case in particular, the Disconnected Application Instance will have a Child Form used to store the Services that will be enabled on the device’s contract once it is provisioned.
As described above, the services go through approval individually. In order to accomplish this in a simple way we will represent the device contract services as roles, which can be assigned their own approval process and can be tracked individually. Now, suppose the HBC has a new requirement that expresses the need to provision application entitlements to a Portal that allows users to manage their own contract’s services and the access is controlled through AD group membership. Having the design already described allows for the use of access policies to provision such access automatically once the role for the individual service is approved, and the evaluation of access policies has been executed.
In summary, the code samples we provide in this section will focus on how to create the requests for the disconnected application instances and the roles representing the services available on the contract for the device. Then, the focus will be shifted to the API’s used to retrieve the data for a given request and read it. The user interface that allows the users to request such devices and services can be implemented as a customization to the catalog screens in OIM 11g R2. The screens will contain a drop down list of devices that are available to the users according to their organization. When a device is selected, a second catalog search will bring back the services that are tied to the selected device (For an example of cascading searches customization please refer to the following blog post OIM 11g R2 UI Customization Tips and Tricks
Now to the fun part, how do we make this happen? As I stated before, the main focus will be the Request Lifecycle Management API’s so we will not show the Catalog Search API’s samples neither how to customize the UI to input the data (a potential implementation of such logic is also discussed in the post mentioned earlier. Also, for all kinds of samples of UI customizations and other commonly used OIM API’s make sure to refer to the OIM 11g Academy
). So assuming the user has the means to select a device and a set of services for the selected device the requests for each one will be created as follows:
The code will traverse the list of services that were added to the cart first, and then create requests for them and obtain the request ids by submitting those requests. Then create the request for the actual device and populate the child table with the requested services. The child table will have three columns (fields): Service Name, Request ID for the role representing the service and the status of the Role (Pending/Approved/Rejected).
The first sample presented creates a request for a Role to be granted to the user. Consider the code in the following listing:
Two parameters are passed: the item of type Catalog and the userLogin of type String. The userLogin is necessary to extract the user Key which will be inserted in the request. The item parameter contains the information that describes the role as a Catalog Item. The Catalog class provides the details that can be used to populate the request for the actual entity. In case of roles as shown in the listing above, there is no need to populate a form, just create a RequestBeneficiaryEntity and set a couple of attributes in it. Things get more interesting when creating the request for the Application Instance. Here is how:
Same two parameters are passed but this time there is an additional call to build the list of attributes for the Application Instance Form. Below is the listing for the method buildAppInstanceAttributeList:
As presented in the listing below, in order to set the values of fields in the “process form”, what is being used is the field label not the field name. The reason why is because we are not really populating the form, we are populating the request data set, which in turn will serve as the source to populate the actual process form. This gives the ability to determine what information the requesters may see when submitting requests for resources, which may not be the entire set of fields in the actual process form. The other interesting thing is how to populate the Child Table, see below (this is a fragment from the method listing above):
In typical examples of how to accomplish child table record insertion that I have come across, all they show is how to insert one value into the child table; but what about inserting multiple rows in the child table and each row has multiple attributes. Well this example shows you how to accomplish insertion of child table records when you need to insert multiple rows that in turn have multiple columns. As shown in the code above, what needs to be done is to create an instance of RequestBeneficiaryEntityAttribute that represents the child table itself. Then you create an instance of RequestBeneficiaryEntityAttribute for each column in the child table. You set the values of each individual column and add those attributes to a list (see childAttributesList1). Then you call the addChildAttributes method on the attribute that represents the Child Form (see appRolesAttr) and pass the list containing the values of all the Child Attributes of the row. To insert multiple rows, you create multiple instances of the RequestBeneficiaryEntityAttribute that represents the Child Table itself and build the row as already explained. In the listing above the creation of appRolesAttris placed within a loop that in our case traverses the list of Services (Entitlements) that a device is supposed to have and then creates a child table row for each service.
That’s it for the request creation, now the requirements for the use case as designed need the means to monitor the requests for the individual services (roles) and determines when to resume the Device Provisioning process flow. For those of you that are new to Disconnected Application Instances and how they are provisioned, here is a little background: Disconnected Application Instances are configured just as regular connected applications that have a Target System (IT Resource/Resource Object combination), the only difference is that as disconnected Applications the IT Resource, Resource Object, provisioning process, process form, request data sets, etc are created by OIM behind the scenes. You can customize these artifacts after they are created, which in fact is what we need to do to add the services to the requested device. The process form will be customized to add the child table that will hold the contract services for the device. The code to populate the child form has been presented above.
In order to monitor the status of the Requests for Device Contract Services, we need to read that data and keep a count of Services that have already been processed versus those that haven’t. As a solution to this problem we decided to implement an asynchronous Web Service which is implemented as an Asynchronous BPEL process that invokes a Synchronous Web Service that monitors all the associated Role requests (contract service requests) mapped to the device’s request. The asynchronous BPEL process is presented in the figure below:
This BPEL process contains a loop task that will break the loop when the count of pending role requests reaches ‘Zero’. Every invocation of the OIMPendingRequestsCounterService results in a new count representing the number of requests for Contract Services (Roles) that are still awaiting approval. This is an easy way to create an asynchronous Web Service using JDeveloper’s features to create Asynchronous BPEL processes that can be invoked as asynchronous Web Services. The implementation of the OIMPendingRequestsCounterService is described next. Consider the listing presented below:
The most important components in this implementation are:
- OIMClient oimClient: This is used to obtain instances of OIM’s API’s.
- RequestService reqSvc: The Service used to obtain information about a request and to update the request’s data when appropriate.
- UserManager usrMgr: Used to obtain the User’s Key of the request’s beneficiary along with other information that might be needed.
Notice another new service introduced in OIM 11g R2, the ApplicationInstanceService. This is used to obtain the names of process and child forms plus their values. According to the listing above, the process is actually simple: Obtain the requested Entity from the request data. Find the Application Instance that is associated with the request by checking the entity sub type. Once the Application Instance has been found, now we can obtain the child form that contains the entitlements (contract services). Each row is represented by an occurrence of an attribute named after the child form’s table. So if multiple entries are present in the child table, they will be accounted for as separate instances of the attribute named after the child form’s table.
These attributes are added to a list that will be traversed to extract the individual rows one by one. Each row has child attributes (columns) which contain the value of the corresponding column within the row. All these information comes from the populated data set not the actual process form. In order to retrieve the data from the process form, the resources need to have already been provisioned. That is not the case in this situation because the Application Instance representing the device can’t be provisioned until all the services have gone through their approval processes. The following method is also important for the implementation:
This is the method that reads the child request data to determine if the Approval has been granted or denied; in other words, whether or not the child request has been already processed. So, to complete the implementation all you need to do is to modify the Composite that gets invoked when a Disconnected Application Instance is provisioned. The following picture shows this modification:
As shown in the previous picture, an Invoke activity along with a Receive activity are employed to call the asynchronous BPEL process that internally call the synchronous Web Service to monitor the Approval/Rejection of the requests for the Contract Services (Roles). This mechanism is fairly simple, but has room for optimization of course. For instance, you might want to implement an event generation mechanism to send a JMS Message to unblock the process flow of the Disconnected Application Provisioning SOA Composite and then process the Human task that will be sent to the Administrator of the Contract, who will manually carry out the processing for the provisioning of the device.
In this article, we have presented the audience with samples of how to use OIM API’s to programmatically implement a use case that involves the following Request Lifecycle Management operations:
- Create complex structure requests for Disconnected Application Instances.
- Create requests for Role Assignment.
- Implement Data Retrieval from Child Tables directly from the request data set.
I hope the samples presented in this article are helpful to your own implementations.
For this and many other useful OIM 11g R2 articles make sure to visit our OIM 11g Academy