Friday, August 24, 2012

Using Oracle Identity Analytics 11g Web Services

Introduction

The purpose of this document is to illustrate and provide a starting point to use web services exposed by Oracle Identity Analytics 11g. Apache CXF 2.6.1 is used to generate the wrapper libraries.

Build Library Setup



We also need a few jars to get everything compiled



Samples


To run the samples you need to configure the file settings.properties with the following
Property Name
Description
user
Username for connecting to OIA
password
Password for OIA user
wsdlurl
Address for WSDL file

auditService 

Enabling Web Services in Oracle Identity Analytics (OIA)
                Edit web.xml with the following changes.
a.       Add classpath:org/codehaus/xfire/spring/xfire.xml

b.      Uncomment the servlet definition and mapping for webservice



c.       Restart OIA.

Webservice Endpoints

For a server that is running on localhost with port 7001 we have four web service endpoints available. These four endpoints are

Creating Java client

We can easily call the web services by creating a java client for the above 4 endpoints. We will be using Apache CXF to build our client application. However there are other ways also like using Apache Axis 1.x and Apache Axis 2.x. Every framework has its own way to wrap the web service operations, which we will not be covering here.
With Apache CXF we have a neat little command line client wsdl2java which creates the java client classes for us. We created the clients for the above four web services as shown below
I first saved the WSDL document from the above URLs. Also since the default generation logic creates a rather weird data structure to use I have put in some customization in javabindings.xml which is specified during client generation.

Role Service



User Service





Business Unit Service
 
 

Audit Service


Javabindings.xml

Once this is done classes are created in the generated folder. Please note that I created separate java projects for each of the web service. If you do all of them in one project you would need to do some manual class changes.
I added some test code also, which I’ll explain below. The projects structure in my eclipse looks like:
Calling the webservice

Any operation that is to be requested needs authentication. The web service client classes do not have any in-built authentication wrappers built. Rather this functionality is present in Apache CXF’s classes. We will go step by step on how the client is created now.
Step 1: Getting the client instance

We have four endpoints, each of which has a different client class to start off with. Below is what we need to get started for User Service.
It will be similar for the other services, for audit we will get the AuditService and so on for the others.

Step 2: Setting up the authentication

As mentioned earlier we need to take help from Apache CXF’s classes to get the authentication working.  We wrapped all this up in one method in the class Common.
Here we are doing two things:
1.  Add logging by adding LoggingInInterceptor and LoggingOutInterceptor in the interceptor queue.
2.  Add username/password for authentication by inserting a WSS4JInterceptor


The above code is how Apache CXF wants it, so more details on why and how on this can be found on Apache CXF’s website.

Step 3: Calling the webservice

Each webservice has different operations available. However the way of operating is similar. Shown below is the easiest method to call getVersion() which is present in all the webservices.



Wednesday, August 8, 2012

Active Roles Server and OIM

Why do companies love web service? Active Directory follows the LDAP v3 protocol to communicate, but no some people are hell bent on getting web service over this neat little bundle wrapped in LDAP. So here comes ARS or Active Roles Server. The server itself provides a web based console to access the users contained inside Active Directory. It has a add-on component that one has to add to enable a web service interface (follows SPMLv2), which allows us to create users via a web service. This web service follows the SPML v2 standard, but so much for just following a new standard, when a already established standard is being used and that too being light weight!

When we first started developing the Active Directory Connector, fitting in the requirements, the default OOTB connector for Active Directory 9.x was being used. I wish it was used all the way, but the client wanted us to use the Active Roles Server web service.  I never had development experience with web services so I tried experimenting with OIM11’s SPML web service. I created a client using Axis 1.x for it and it worked perfectly. But when it came to ARS (Active Roles Server), it turned out ugly.
I started with Axis 1.x , created a client but had to spend a very long time to get my head around how to send the username/password for the request. It seemed like a crazy jungle where I have no help. But I finally had some help from a few YouTube videos and I was able to get it working. My idea was to use similar steps to complete the web service client for the ARS web service, but it all turned out into waste. I tried Axis 1.x / Axis 2.x. / Apache CXF / wsimport, but ended up with new problems every time. Axis 1.x created me a request class with Object[][] data type for a tag which was like – “<attr> <data><value></value></data><data><value></value></data> </attr>”. I had no clue how to get it from a Object[][]. Axis 2.x gave me the request class correctly but the response was not getting parsed and it used to throw an error when I got the response. Finally I went to the basics to solve all this mess.
A web service is a HTTP request. Why not hand craft the XML and send it. “Sound simple enough” is what I thought. I did not want to write all the code to create XML, so after looking for some time I found a neat little library called “Simple”.  It is available from http://simple.sourceforge.net/ . It has an easy to learn Java annotation based framework which allows to generate XML is pretty easy way. An example is like this

This class when converted to XML gives us something like this
Note: the formatting was slightly modified to make the XML fit
Once we are done with the XML conversion we create a HTTP request to the web service and send the XML. Here is how we send the request:

Here are the steps in plain English:

1. We need to create a request that is of type POST. So create a instance of class HttpPost
2. We also need to set header value “SOAPAction”. This will tell the web service what method we are calling. This can be inferred by testing your webservice from SOAPUI. Alternatively you can refer to the web service WSDL and get the values.  
3.The response is again a XML formatted document which we can parse using the standard Java DOM APIs.

To complete this post with an example, I have put in a few classes which will give an idea on how to put a web service client in place. The method is a rather low tech method, and it is up to the designer/developer to choose.

Sample Code


Tuesday, May 1, 2012

IceCreamed finally !

Being a GalaxyS user, I was rather disappointed when I heard the news that it would not be getting Android 4 aka Ice Cream Sandwich. It had been a long time since I got any upgrade for the phone's OS. My phone was behaving rather sluggishly these past few days. Time for IceCreamSandwich is what I thought :)

I started of by using Odin, a ROM flashing software which is what I got from a lot of blogs and forum posts. But bad luck was with me all the way and I bricked my phone. Not a hard brick fortunately. I was able to get the phone into download mode, and boy am I glad it was possible. After a lot tries with various versions of Odin, I finally moved to using another opensource software called Heimdall. This is much much better than the useless Odin, which is highly unreliable. It never even started off correctly for me, but all it did is brick my phone or make is useless. Thank god, there was someone who wrote Heimdall to help me. After all this commotion with Odin, I went back to my reliable Linux and flashed my original image which I got from samfirmware.com and first got my Phone to working condition. Once I had my phone running I had my heart beating at the normal pace once again.

To move to the next version I used ClockWork Mod and then used the Cyanogen Mod9 to get to the current awesome state. Because it is a Cyanogen Mod, it has loads of developer goodies, that are not of much use to the average user, but to a developer it is like sugar candy. Performance tweaks are also available to me now, from the settings. So aweseome! Also out of all the guides this one helped the most ( https://gurde.com/2012/04/how-to-android-ics-4-0-4-on-galaxy-s-i9000/ ).

Monday, March 26, 2012

OIM11g Request Terminologies


 OIM11g Request Terminologies

Thursday, February 16, 2012

Hello World – OIM11g Metadata and Plug-in Framework

Introduction

This tries to explain the import/export process for registering plug-in, schedulers, request datasets, etc.
The intended audience for this experiment is experienced OIM 9.x developers who are learning OIM 11.x.

The Setup

I am using
Component
Version
Operating System
Windows 2003 R2 (Enterprise x64 Edition)
Application Server
Weblogic 10.3.5
Database Server
Oracle 11gR2
OIM
11.1.1.5.0

Plug-ins

OIM 9.x had everything available from the design console when it came to developing workflows. But with OIM 11g a plug-in framework has been introduced. In OIM 9.x we had entity adapters to do this job, but now this plug-in framework is to supersede that. This plug-in framework allows us to register items that would be called at different stages of the processes like creation of user or an update of user. In OIM 9.x we did these operations using entity adapters, but now these adapters have been replaced by OIM plug-ins.

Meta Data

OIM 11g introduces a concept of metadata repository for components like schedulers, plug-ins, etc. A component like a scheduler would have a name, a set of parameters that it needs. All this is defined in XML (metadata) and needs to be uploaded into OIM’s metadata repository.

Creating a Plug-in

This has two steps:
1.       Register your plug-in class
2.       Upload metadata for this plug-in

Plug-in Structure

A plug-in composed of the following elements
1.       plugin.xml
2.       lib/plugin-name.jar
3.       resources/something.properties
The resources folder is optional and is not always required.

Registration

OIM can hold the plug-in code in the database or on file system. The default plug-in folder is the plugins folder inside server. To load data into the OIM database, we have some script provided by OIM that will help us load those items.

How to Create a Plug-in

Creating plug-in may look cumbersome when you start off, but after a while it will be like second nature to you. Here are the steps:
1.       Create the plug-in class
This is the most important step. After all you want to do something with this plug-in. The plug-in class needs to extend a plugin-point class. Some of the classes that you can extend are

Interface Class
oracle.iam.platform.kernel.spi.ActionHandler
oracle.iam.platform.kernel.spi.PreProcessHandler
oracle.iam.platform.kernel.spi.PostProcessHandler
oracle.iam.platform.kernel.spi.AuditHandler
oracle.iam.platform.kernel.spi.CancelledHandler
oracle.iam.platform.kernel.spi.CompensateHandler
oracle.iam.platform.kernel.spi.InvalidHandler
oracle.iam.platform.kernel.spi.ValidationHandler
oracle.iam.platform.kernel.spi.EntityPreviewer
oracle.iam.platform.kernel.spi.FailedHandler
oracle.iam.platform.kernel.spi.VetoHandler

Each of these classes will have some methods that are specific to the area where it will be used. For example, if it is a PreProcessHandler, you need to implement execute(), compensate() and cancel() method.
2.       Create the plugin.xml
The plug-in xml is fairly same for all the above cases. It is structured as:
<oimplugins xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <plugins pluginpoint="oracle.iam.platform.kernel.spi.EventHandler">
              <plugin
                     pluginclass="oim.helloworld.plugin.user.CreateUserPreHandler"
                     version="1.0" name="CreateUserPreHandler" />
       </plugins>
</oimplugins>
The pluginpoint will vary based on what item you are developing the plugin for.
3.       Creating the jar
Code created for the plug-in needs to be bundled in a jar file.
4.       Create the zip
OIM expects a zip file for the registration process. The structure is same as mentioned before. Inside the zip you should have plugin.xml and the lib folder always. The lib folder will contain the jar file
5.       Use the registration script
Now that we have the zip file ready with us, navigate to the plugin_utility folder. This folder is located inside the OIM_HOME/server folder.
Edit the ant.properties file to set wls.home and oim.home. Example:
Run the following command
ant –f pluginregistration.xml register
The script will ask for oim username and password and the weblogic url which would be something like t3://localhost:14000. After this it will ask for the path of the zip bundle. While entering the path use forward slashes instead of backslashes if you are on windows. Example:
C:/tmp/plugin-helloworld.zip


Being Conventional

When I started developing plug-ins it took me at least a zillion tries before I got it working, but that surely does not mean that you would take the same time. Below are some items that I keep in mind while creating plug-ins:
1.       One Plug-in Only
The plug-in xml allows us to put in multiple items together as a single XML. However I always register them as separate items. So if I have two items to register, I do them as two separate bundles.
2.       Plug-in XML Naming convention
While creating the plug-in we have to give a name to the plug-in (name attribute in the plug-in tag). The name of the plug-in is always the class name of the plug-in class. Example:
<plugin     pluginclass="oim.helloworld.plugin.user.CreateUserPreHandler"
                  version="1.0" name="CreateUserPreHandler" />
3.       Plug-in JAR Naming convention
All the code that we create for a plug-in goes into the lib folder. In all the plug-ins, the name of the jar file is the name of the plugin zip. Example:
If these are the plug-in contents:
lib/helloworld.jar
plugin.xml
The zip bundle to be used for registering this plug-in would be helloworld.zip
4.       XML Tags
Do have the XML header tag, something similar to 
<?xml version="1.0" encoding="UTF-8"?>
as the first line of your XML.
I use these rules when I create any plug-in, but these are not hard rules. You may have your own set of conventions, which may be quite different.

Creating MetaData

Now that we know how to create a plug-in and register it, we have to tell OIM how to use this plug-in. This process is again a XML based representation of the details. (Why do they have so many XMLs!)

MetaData Structure

The metadata is composed of one or more XML files. However as opposed to the plug-in registration, importing of these XMLs does not always work as expected if we import them at the wrong location. We will see more on this later.

Registration

Registration of metadata is similar to the plug-in registration process. Here are the steps:
1.       Build the metadata XML
The metadata xml is specific to the item that is being registered. Example:
PreProcess Event Handler Metadata XML
Scheduler Metadata XML

Always use the same name as defined in the plug-in.

2.       Configure weblogic.properties
This file is located in the server/bin directory. This contains information on where to look for metadata files. Configure the following items:
a.       wls_servername
wls_servername is the weblogic servername where OIM is running. Example: oim_server1
b.      application_name
application_name is the metadata that we need to import to. Set this to OIMMetadata
c.       metadata_from_loc
metadata_from_loc is the directory from where it will pick up the metadata files


3.       Put your metadata files in the import folder
The files that you want to import must be put in the metadata_from_loc folder which we configured in the last step.
However the xml needs to structured in a specific folder structure.
For schedulers, the structure should be something like /db/{SchedulerName}.xml
For plug-ins, the structure should be something like /metadata/abccorp/user/create/{PluginName}/EventHandlers.xml

For details on this refer the relevant documentation section in OIM.
4.       Run the weblogicImportMetadata.sh or weblogicImportMetadata.bat (Linux/Windows)
During this process you will see a Transfer complete message in the OIM logs like this:

5.       Run the PurgeCache.sh or PurgeCache.bat

6.       Some items work directly after this like schedulers, but some require the OIM server to be restarted like pre-process plug-ins. Restart the server appropriately after this.

Being Conventional

The plug-in registration was almost painless, compared to the metadata registration. It took me more time to get this working, compared to the plugin registration process. Along the way, I made some rules to create metadata xmls and importing them. These conventions are:
1.       One MetaData XML Import
If I have multiple XMLs to import, I separate them into separate batches. One XML was used in one import.
2.       Directory naming convention
If I am creating a pre-process/post-process handler or related plug-in I used the following structure
/metadata/{projectORcompanyname}/{entity:user or resource,etc}/{operation}/{plugin-name}/EventHandlers.xml
Example: For a preprocess handler for create operation on resource MyApp it would be
/metadata/projectx/myapp/create/CreatePreHandler/EventHandlers.xml
Here when I registered the plug-in the plug-in name was CreatePreHandler

Dumping the MetaData

All the metadata XMLs that we imported can be easily retrieved back from OIM. We can utilize the weblogic scripting tool or wlst to export all the metadata xmls.
Here is how we can export all the metadata that OIM has:

All the files will now be exported to C:/tmp/metadata-export

Cleaning Up

MetaData

Deleting metadata is simple enough if you compare the import process with this. Here are all the steps:
1.       Configure the weblogic.properties
Set the metadata_to_loc to the directory where we need to export the files.
2.       Set up the metadata_files to the items that we need to delete. If we want to delete more than one items then separate them using comma.
3.       Once this is done navigate to the server/bin directory. Run the delete script
4.       Enter the weblogic admin credentials
5.       This would delete the items from the metadata store.
6.       Purge the metadata cache after this using PurgeCache.bat or PurgeCache.sh as done during the creation steps.

Plug-ins

To delete plug-ins from OIM database we need to unregister it using the same ant script used to register. Here are the steps:
1.       Navigate to the server\plugin_utility folder.  Run the script like
2.       The script will prompt you for the credentials and the class to unregister. Enter the details and the plug-in should be removed


Monday, February 13, 2012

Hello World – OIM11g Approval Workflow

Introduction

An under the hood inspection of what happens when we have approval workflows in OIM 11g.
The intended audience for this experiment is experienced OIM 9.x developers who are learning OIM 11.x.

The Setup

I am using
Component
Version
Operating System
Windows 2003 R2 (Enterprise x64 Edition)
Application Server
Weblogic 10.3.5
Database Server
Oracle 11gR2
OIM
11.1.1.5.0
Code 

Hello World Scenarios

Create User via Self Request

Let us say I want a new user, but I will not create it using the direct form. I’ll try this via a self request.
 
















The default approval flow for OIM is
Template Approval > Request Approval > Operational Approval
OIM11g does not have any approver assigned to this template, but has xelsysadm as default approver for Request Approval and Operational Approval.
I approved the first level Request Approval and here is what I get.

Let us approve the next level.


I gave an effective date for the request, so the request is waiting for effective date to be reached.

I created one more request with no effective date and followed the same procedure and here is what I got at the end of it – a new user!


Create User via Self Request (Semi Approved)

In the last scenario we saw two levels of approval for the Create User process. I now want only one level of approval. There is no template level approval. We can suppress either Request Level Approval or Operational Level Approval. I suppressed the Request Level approval. A rule was created, which is something like this:
Now if I raise a request to create a user, the request directly moves on the operation level approval.

MyApp (Custom Resource) – Self Request

I did not have any connector installed in my system, so I created a dummy resource for this purpose. Here is what I did

Create Resource Object








Create Process Definition


































Create a Requester Role

Create a request template





User Setup

Give a user the requester role

Request the resource

Enough of configuration, I need my resource quick!























Request Level Approval

The request has no approval process defined, so it went to the default request level approver. Let us approve that.

Operation Level Approval

Request Level approval is done but we still need the operation level approval.
The request is now approved!



I got the resource provisioned!

MyApp (Custom Resource) – Object/Resource Forms

In the older OIM 9.x series to create forms, we could just go to the form designer and create some forms. Once they were associated with the resource object we were all set. It was all graphical and easy to learn. With the new OIM11.x it has become a jungle of terms with so much to digest, that by the time I actually get to the work, I’ll forget where I am. So here I’ll try to add one by one small features and then see how it works here.

One Field with No Mapping to Process Form


According to the documentation, I need an xml file to declare the form fields. Here is what I created

Let us try to do a self request for MyApp





Cool! Now I can see my new form field.

Simple Pre-populate

It would be so much better if the user login could be populated automatically. Let us write a plug-in to do that.
Here is a simple code for that.
You can see some simple System.out.println statements in the code above. I added them to see what is getting passed around. Not necessary, but let us see what do we see in logs when we create a new request.
My new request gets the user login automatically now!

User Only and Approver Only Fields

The metadata documentation mentions some fields to be approver only and some fields to be user only fields. Let us see what that means
Here is the xml I created

Requester View

When I do a self request here is what I get as a requester

If I go ahead and submit the request, I can see this

Approver View

What does the approver see?
I can see the approver only field here! I’ll deny the request and let us see what the requester gets.


Too bad he can’t see the approveronlyfield!

Lookups and IT Resources

Most forms will have lookups and/or IT Resources to select from. Let us see how we can do that here

Creating a Lookup, a IT Resource Type and IT Resource



The metadata XML

Here is the XML I used
So I have one lookup and one IT Resource field, which shows up like this when I do a self request

However, if you see the xml file I had to use AttributeReference instead of Attribute. I first tried using Attribute tag, but it didn’t work. I changed it to AttributeReference and thus had to refer to something in the parent form, which I created like this:
So now we have the IT Resource field and Lookup field. I’ll fill some data and submit the request


I’ll approve the request and then let us see how it shows up in My Resource.

So I have the resource, but the data doesn’t seem to have passed through. The auto-save is off for this process. Let us turn that on and see the result again with another request.
It worked! Now I have the IT Resource and Lookup data being passed through to the user and the resource is provisioned too, awesome!


Child Data

Till now we have mapped only the parent data to the process forms. Let us map some child data from request to process form’s child data.

Here is the XML I used:


Here is what I gave while creating the request:











 After approving the request, we get the big bang in our child table!

 




Dependent Fields

In an old project, we had a requirement where we wanted two fields to show up on the form field. The requirement was to have field2 have values based on field1’s selection. At that time OIM 9.1 was the latest version out, and I had no idea how to get that working in OIM. But with this new version of OIM it is possible. Let us see how we can do that.
The two fields that we have in our case are Country and State. So if I select India, the state list should have Indian states only. I added these two fields in the process form and here is how it looks now:
The XML file that I created has two new attributes to map to these two attributes.
      <AttributeReference name="Country" attr-ref="Parent Field Country"
            type="String" widget="lookup" lookup-code="Lookup.MyApp.Country"
            length="100" available-in-bulk="false" />
      <AttributeReference name="State" attr-ref="Parent Field State"
            type="String" length="100" widget="lookup-query" available-in-bulk="false">
            <lookupQuery
                  lookup-query="select lkv_encoded as State from lkv where lku_key = ( select lku_key from lku where LKU_TYPE_STRING_KEY = 'Lookup.MyApp.State' ) and lkv_decoded = '$Form Data.Country'"               
                  display-field="State" save-field="State" />
      </AttributeReference>

Once I upload this in OIM, and I do a self request here is what I get when I do a self request:
So we have the two fields showing up at the top right. Let me fill the Country to USA and see the State field values.
It worked! The query that I wrote in the XML allows me to refer to form data. Now I can have dependent fields in the request workflow.

Conclusion

The new approval workflow has three levels of approval, which being Template, Request and Operation in that order. Template level is optional by default, but the other two have XELSYSADM as the default approver. To suppress these we need create policies. However the older way of doing things was simpler and it would have been so much nicer if they had integrated it with the design console instead of using a XML based configuration.