Monday, April 23, 2012

Custom transformation provider for OIM GTC connector

GTC based connector is one of the most used approaches for reconciling data into OIM, specially through the use of flat files. A common issue is that some customers do not allow direct communication between OIM and the HR system (for different reasons like outsourced HR system, security constraints and others), hence a flat file is made available to OIM so that it reconcile users.

Very often, there is a need to manipulate the data to be reconciled in OIM through the GTC connector. When that is true, most of customers end up creating event handlers to manipulate reconciled data. The problem with this approach is that in OIM 11g, only 'post process' event handlers can be used to manipulate reconciliation data (and the data can only be manipulated after reconciled into OIM), and this can make some manipulations really tricky and/or cumbersome.



OIM GTC framework provides a nice feature called 'Transformation Provider'. A 'Transformation Provider' is invoked by GTC at reconciliation data load time, before GTC creates the reconciliation event. Transformation providers are invoked per attribute, and different providers can be used for different attributes. They are all configured during the GTC reconciliation mapping stage.


The picture below shows where a custom transformation provider will show up in the GTC configuration:


This post shows an example of a custom transformation provider as well as how to deploy it. The objective of this transformation provider is delete enclosing double-quotes from the attribute data loaded from the flat file: the attribute value loaded from the file is "attrValue" and it will be transformed to attrValue. As you may be aware, GTC is not capable of doing that character trimming in the out-of-the-box configuration.

The transformation provider consists of a XML descriptor, a jar file containing the compiled code and a resource bundle file containing the errors messages. The XML file must be loaded into the MDS database, whereas the jar file must be uploaded to OIM.

Below the XML file that defines the provider:

<?xml version='1.0' encoding='UTF-8'?>
<Provider>
   <Transformation>
     <TransformationProvider class="oracle.iam.demo.gtc.CustomTransformationProvider" name="CustomTransformationProvider">
       <Configuration>
         <Parameter type="Runtime" datatype="String" required="YES" encrypted="NO" name="Input"/>
         <Response code="REMQUOTES_INPUTSTR_MISSING" description="Input String is Missing"/>
       </Configuration>
     </TransformationProvider>
  </Transformation>
</Provider> 
 
This file MUST be loaded to the MDS location below:

/db/GTC/ProviderDefinitions

Below the Java code with the transformation provider implementation:
package oracle.iam.demo.gtc;
package oracle.iam.demo.gtc;

import com.thortech.xl.gc.exception.ProviderException;

import com.thortech.xl.gc.spi.TransformationProvider;

import java.util.Hashtable;

public class CustomTransformationProvider implements TransformationProvider {
    
    public CustomTransformationProvider() {}

    private static String providerType = "TransformationProvider";
    private static String providerName = "CustomTransformationProvider";
    private static String errorRespNullInput = "REMQUOTES_INPUTSTR_MISSING";
    
    public String transformData(Hashtable input, Hashtable utils) throws ProviderException  {
        
        try  {         
            String wholeString = (String)input.get("Input");    
                
            return wholeString.substring(1,wholeString.length()-1);
        } 

        catch (Exception ex) {
            
            StringBuffer responseCode = new StringBuffer();
            responseCode.append(providerType);
            responseCode.append(".");
            responseCode.append(providerName);
            responseCode.append(".");
            responseCode.append(errorRespNullInput);
           
            throw new ProviderException(responseCode.toString(),"message");
        }                                            
    }
}

The class must be deployed within a jar file. The jar file must be loaded with '$OIM_HOME/server/bin/UploadJars.sh<bat>' as a 'JavaTask'`.

The resource bundle (and its translations) must be loaded as 'connectorResource' in OIM using the '$OIM_HOME/server/bin/UploadResourceBundles.sh<bat>' script. Below an example of the resource:

###### Transformation Provider  ######
GC.GCPROV.TransformationProvider.CustomTransformationProvider.REMQUOTES_INPUTSTR_MISSING=Input String Missing
GC.GCPROV.TransformationProvider.CustomTransformationProvider.REMQUOTES_INPUTSTR_MISSING.description=The input string is missing.

Make sure that the resource bundle is named after the transformation provider: CustomTransformationProvider.properties in this case. At least one translation must be loaded (like CustomTransformationProvider_en.properties).

Once you have the three pieces (XML, jar file and resources) deployed to OIM, you should be able to see the transformation provider available to be used in the GTC attribute mapping screen (as shown in the picture in this post).

The material and solution available in this post were gently provided by John Kimble, a co-worker at Oracle.

11 comments:

  1. Hi ,

    i tried exactly same code mentioned above in the blog but i am not able to see the provider in the drop down i don't know where i went wrong.

    and can you please provide me the resource bundle file it will be helpful

    Thank you

    ReplyDelete
    Replies
    1. Srivatsa,

      It is hard to say what went wrong. Trying purging the OIM cache, if that does not work, try restarting. If that does not work, the issue may be with the XML file, make sure it is well formed.

      There is nothing else needed for the resource. All you need are those two lines.

      Hope this helps.

      Delete
    2. do we need to mention somewhere this path
      /db/GTC/ProviderDefinitions...??

      Delete
    3. That is the path within MDS.

      You have to import your custom XML file that defines the transformation provider into that folder.

      Delete
  2. Hi ,

    i Used the same information which is provided above in the blog.
    But i am unable to see the custom provider in the GTC dropdown.

    can you please provide the full bundle resource which is created for this code. i created the .properties file with


    ###### Transformation Provider ######
    GC.GCPROV.TransformationProvider.CustomTransformationProvider.REMQUOTES_INPUTSTR_MISSING=Input String Missing
    GC.GCPROV.TransformationProvider.CustomTransformationProvider.REMQUOTES_INPUTSTR_MISSING.description=The input string is missing.

    i don't know were i made mistake.please help me to get through it.


    Thank you

    ReplyDelete
  3. Hi Daniel,

    Thanks for the reply. i didn't imported the xml file to /db/GTC/ProviderDefinitions path that's the reason i was not able to see the Custom providers.

    Now i am able to see the Custom providers in the drop-down. But when i am selecting the custom providers it is showing blank page i am not able to see the input fields. Below is my XML file.















    Thank you
    Sriatsa

    ReplyDelete
    Replies
    1. I'm getting the same issue. Did you resolve it? thanks.

      Delete
    2. It is not very clear to me what could be wrong. Make sure that the resource bundle is named after the transformation provider: CustomTransformationProvider.properties in the example from this post.

      Delete
  4. Hi Daniel,

    In my Reconciliation Mapping doesn't appear this 5 options for Action Mapping, just 4: "Create Mapping Without Transformation", "Create Mapping With Translation", "Create Mapping With Concatenation" and "Remove Mapping". Do you know why this CustomTransformationProvider does not appear to me? I have 6 GTC objects presenting this behavior.

    Thanks in advance!

    ReplyDelete
    Replies
    1. Gustavo,

      It is really hard to say what's wrong.

      I believe OIM is not picking your transformation because there is some misconfiguration in the XML that defines the provider.

      hope this helps

      Delete
  5. Hi Daniel

    We have to update the UDF fields created for the users in OIM using the data from a table .



    These table contains the AD ID ,and other fileds .



    OIM User (already available )will be updated based on AD ID ….i;e AD ID column will be used to find the user in OIM and then his UDF will be updated based on the respective data from other columns in the table .


    Thanks,
    Venu


    ReplyDelete

Note: Only a member of this blog may post a comment.