B Sample Schema, Scripts, and Connector Generation and Installation Procedure

This appendix provides a complete example of a use case for the Generic Scripting connector, including sample scripts and the connector generation and installation procedures.

This example uses Oracle Database as the target system and the sample scripts for connector operations are written in Groovy.

This appendix discusses the following topics:

B.1 Summary of Steps to Generate and Use the Connector

The following is a summary of steps to generate and use the Generic Scripting connector for a sample environment:

  1. Create a properties for your target system schema. See Defining the Schema for detailed information about creating a schema file for your target system.

  2. Create a resource properties file if the sample target system requires additional parameters to successfully connect with the target system. See Preparing the Resource Properties File for detailed information about creating a resource properties file.

  3. Determine and create scripts for the operations that you want the connector to perform. This involves determining the mode in which you want to run the connector, target resource or trusted source.

  4. Configure the ScriptConfiguration.groovy file. See Configuring the ScriptConfiguration.groovy File for detailed information about the entries in the ScriptConfiguration.groovy file.

  5. Generate the Generic Scripting Connector based on your target system schema specified in the schema.properties file. See Generating the Connector for detailed information about running the metadata generator to generate the connector.

  6. Install the connector included in the connector installation media. See Installing the Connector for detailed information about connector installation.

  7. Install the connector that you generated in Step 5. See Installing the Connector for detailed information about connector installation.

  8. Configure the IT resource for your target system. See Configuring the IT Resource for the Target System for more information.

  9. Create a form for your target system and associate it with an application instance. See the following sections for detailed information:

  10. Replace the groovy-all.jar file with the latest version available on the computer hosting Oracle Identity Manager. See Replacing the groovy-all.jar File for detailed information about replacing the groovy-all.jar file.

B.2 Sample Schema File for Database Creation

The following is a sample schema file for Database creation:

CREATE TABLE "GENERIC_PARENT"
  (
    "USERID"   VARCHAR2(20 BYTE) NOT NULL ENABLE,
    "PASSWORD" VARCHAR2(20 BYTE),
    "STATUS"   VARCHAR2(20 BYTE),
    "LAST_UPDATE" TIMESTAMP (6) DEFAULT CURRENT_TIMESTAMP,
    "FIRSTNAME"       VARCHAR2(20 BYTE),
    "LASTNAME"        VARCHAR2(20 BYTE),
    "ORG"             VARCHAR2(20 BYTE),
    "CITY"            VARCHAR2(20 BYTE),
    "EMPLOYEE_NUMBER" NUMBER,
    "STARTDATE" DATE,
    "USERNAME" VARCHAR2(20 BYTE),
    "EMAIL"    VARCHAR2(20 BYTE),
    "ENDDATE" DATE,
    "LONGVALUE" LONG,
    "FLOATVALUE" FLOAT(126),
    "CHARVALUE" CHAR(1 BYTE),
    CONSTRAINT "GENERIC_PARENT_PK" PRIMARY KEY ("USERID") 
  )
  
  CREATE TABLE "GENERIC_GROUP"
  (
    "USERID"    VARCHAR2(20 BYTE),
    "GROUPNAME" VARCHAR2(20 BYTE),
    "STARTDATE" DATE,
    "GROUPID" NUMBER,
    CONSTRAINT "GENERIC_GROUP_GENERIC_PAR_FK1" 
FOREIGN KEY ("USERID") REFERENCES "GENERIC_PARENT" ("USERID") ENABLE
  )
  
  CREATE TABLE "GENERIC_ROLE"
  (
    "USERID"   VARCHAR2(20 BYTE),
    "ROLENAME" VARCHAR2(20 BYTE),
    "ROLEID"   NUMBER,
    "STARTDATE" DATE,
    CONSTRAINT "ROLE_FK" FOREIGN KEY ("USERID") REFERENCES "GENERIC_PARENT" ("USERID") ENABLE
  )
Trigger for Last_Update

CREATE OR REPLACE TRIGGER UPDATE_LASTUPDATED 
BEFORE INSERT OR UPDATE ON GENERIC_PARENT 
REFERENCING OLD AS OLDREC NEW AS NEWREC 
FOR EACH ROW
BEGIN
  :NEWREC.LAST_UPDATE := sysdate;
END;

Create Procedure

create or replace package types 
as type cursorType is ref cursor; 
end; 

B.3 Sample Schema Description

The example target system (an Oracle Database) contains a schema named GENERIC, which in turn contains the GENERIC_PARENT, GENERIC_GROUP, GENERIC_ROLE, and GENERIC_ORGANIZATIONS tables.

The following sections describe the columns of each table in the GENERIC schema:

B.3.1 GENERIC.GENERIC_PARENT Table Description

Table B-1 lists the columns of the GENERIC.GENERIC_PARENT table.

Table B-1 GENERIC.GENERIC_PARENT Table Description

Column Name Type Description

USERID

VARCHAR2(20)

NOT NULL, PRIMARY

PASSWORD

VARCHAR2(20)

 

STATUS

VARCHAR2(20)

 

LAST_UPDATE

TIMESTAMP (6)

This column is used during incremental reconciliation.

FIRSTNAME

VARCHAR2(20)

 

LASTNAME

VARCHAR2(20)

 

ORG

VARCHAR2(20)

 

CITY

VARCHAR2(20)

 

EMPLOYEE_NUMBER

NUMBER

 

STARTDATE

DATE

 

USERNAME

VARCHAR2(20)

 

EMAIL

VARCHAR2(20)

 

ENDDATE

DATE

 

LONGVALUE

LONG

 

FLOATVALUE

FLOAT(126)

 

CHARVALUE

CHAR(1)

 

B.3.2 GENERIC.GENERIC_GROUP Table Description

Table B-2 lists the columns of the GENERIC.GENERIC_GROUP table.

Table B-2 GENERIC.GENERIC_GROUP Table Description

Column Name Type Description

USERID

VARCHAR2(20)

FOREIGN KEY

GROUPNAME

VARCHAR2(20)

 

STARTDATE

DATE

 

GROUPID

NUMBER

 

B.3.3 GENERIC.GENERIC_ROLE Table Description

Table B-3 lists the columns of the GENERIC.GENERIC_ROLE table.

Table B-3 GENERIC.GENERIC_ROLE Table Description

Column Name Type Description

USERID

VARCHAR2(20)

FOREIGN KEY

ROLENAME

VARCHAR2(20)

 

STARTDATE

DATE

 

ROLEID

NUMBER

 

B.3.4 GENERIC.ORGANIZATIONS Table Description

Table B-4 lists the columns of the GENERIC.ORGANIZATIONS table.

Table B-4 GENERIC.ORGANIZATIONS Table Description

Column Name Type

ORGNAME

VARCHAR2(20)

ORGID

VARCHAR2(20)

B.4 Sample Schema File for the Target System

Create a schema file representing the structure of your target system. The following is a sample schema file which also includes the LAST_UPDATE attribute that will be used during incremental reconciliation:

#Sample Schema file

#List of fields
FieldNames=USERID,PASSWORD,USERNAME,STATUS,EMAIL,FIRSTNAME,LASTNAME,ORGANIZATION,CITY,EMPLOYEE_NUMBER,STARTDATE,ENDDATE,LONGVALUE,FLOATVALUE,CHARVALUE,GENERIC_GROUP,GENERIC_ROLE

#Unique ID Attribute
UidAttribute=USERID

#Account Name attribute
NameAttribute=USERNAME

#Multivalued attributes
GENERIC_GROUP.Multivalued=true
GENERIC_ROLE.Multivalued=true

#Subfields for complex child form
GENERIC_GROUP.Subfields=GROUPNAME,STARTDATE,GROUPID
GENERIC_ROLE.Subfields=ROLENAME,ROLEID,STARTDATE

#Complex child form objectClass
GENERIC_ROLE.EmbeddedObjectClass=MyROLES
GENERIC_GROUP.EmbeddedObjectClass=MyGROUPS

#Datatypes (Default:String)
GENERIC_ROLE.STARTDATE.DataType=Long
GENERIC_GROUP.STARTDATE.DataType=Long
GENERIC_GROUP.GROUPID=Integer
GENERIC_ROLE.ROLEID=Integer

STARTDATE.DataType=Long
ENDDATE.DataType=Long
EMPLOYEE_NUMBER.DataType=Integer
LONGVALUE.DataType=Long
FLOATVALUE.DataType=Double

#Incremental reconciliation attribute with datatype set to Long
LAST_UPDATE.DataType=Long

#Parent and child form mandatory fields
GENERIC_ROLE.ROLENAME.Required=true
GENERIC_GROUP.GROUPNAME.Required=true

#Date format
SystemDateFormat=ddmmyy

#Password Attribute
PasswordAttribute=PASSWORD

#Account Status Attribute and Mapping
StatusAttribute=STATUS
STATUS.True=Enabled
STATUS.False=Disabled

B.5 Sample ScriptConfiguration.groovy File

The following is a sample ScriptConfiguration.groovy file which shows sample entries for both the trusted and target sections:

/*
 * Run like:
 * In Windows: GenericScriptGenerator.cmd ..\resources\ScriptConfiguration.groovy trusted
 * In Linux/Unix: sh GenericScriptGenerator.sh ../resources/ScriptConfiguration.groovy trusted
 */
trusted {
    /* 
     * ITResource name
     */
    itResourceDefName='GenScr' // This will be used as a base name for all metadata across the connector
    //  itResourceName="$itResourceDefName" //the same as itResourceDefName by default

    /*
     * Output files
     */
      connectorDir="../$itResourceDefName"                    // output dir of the connector, is the same as it resource name by default
      xmlFile='GenScr-ConnectorConfig.xml'           // name of the dm xml of the connector
      configFileName='GenScr-CI.xml'        // name of the config xml
      propertiesFile='GenScr.properties'   // name of the resources/properties file
      version='11.1.1.5.0'    // connector version

    /*
     * Trusted/Target mode
     * For trusted, we will not create forms, dataobjects and event handlers
     * For target, we will create all above metadata
     */
    trusted=true                                                // Flag to denote if the mode is trusted or not

    /*
     * Location of the generic script bundle jar
     */
    bundleJar='../lib/org.identityconnectors.genericscript-1.0.11150.jar'

    /*
     * The Configuration used to run the generic script bundle mentioned above, and get the schema by calling its SchemaOp, which is required for generating metadata 
     */
    config = [
        'schemaFile' : 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/trusted/schema_sampletarget.txt', //This property is used during metadata generator,  provide file:///url of the file
        'resourceProperties' : 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/trusted/resource.properties', // Location of properties file which defines target specific resource parameters, provide file:///url of the file
        'host' : 'example.org',
        'port' : '1521',
        'user' : 'generic',
        'changeLogColumn':'LAST_UPDATE',
        'executeQueryScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/trusted/executequeryutil.groovy',  // provide the file:///url of the script
        'syncScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/trusted/sync.groovy', // provide the file:///url of the script
        'connectionScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/trusted/connection.groovy', // provide the file:///url of the script
        'checkAliveScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/trusted/checkAlive.groovy', // provide the file:///url of the script
        'disposeScript': '', // provide the file:///url of the script
        'scriptType': 'GROOVY' // proved script type, valid entries are GROOVY,BEANSHELL,JAVASCRIPT
    ]

      /**
      *  Provide the attribute list that need to be handled as Date on process form
      *  Make sure these fields datatype in schema should be long
      *  dateAttributeList is not a mandatory field
      **/

    dateAttributeList = ["STARTDATE","ENDDATE"]

    /**
     * Define alias for object class if it is other than ObjectClass.ACCOUNT_NAME and ObjectClass.GROUP_NAME  
     */

    //objectClassAlias = ['Person']

    /**
     *   Alias are used to map the OIM User Form attributes with the Connector Attributes. 
     *   The Format is of 'Connector Attribute':'OIM User Form Attribute'
     *   Mandatory alias shouldn't be removed. Customer can update these mandatory attributes but should not be removed
     *   Customer can add other aliases to the OIM User form fields
     **/
    // Mapping is mandatory for attributes User Login, Last Name,Organization, Xellerate Type and Role. One can modify the required mappings but shouldn't delete them. 
    //UID field is not required in trusted but if customer wanted to add UID field then one can map it to a valid OIM User Form Label
 alias = ['__NAME__':'User Login', 'LASTNAME':'Last Name','Organization':'Organization Name', 'Employee Type':'Xellerate Type', 'Role':'Role']
    //Extend the aliases to include more connector attributes for trusted by mapping
    alias += ['__ENABLE__':'Status', 'FIRSTNAME':'First Name', 'EMAIL':'Email', 'STARTDATE':'Start Date','ENDDATE':'End Date','EMPLOYEE_NUMBER':'Employee Number']}

/*
 *
 * Run like:
 * In Windows: GenericScriptGenerator.cmd ..\resources\ScriptConfiguration.groovy target
 * In Linux/Unix: sh GenericScriptGenerator.sh ../resources/ScriptConfiguration.groovy target */

target {
    /*
     * ITResource name
     */
    itResourceDefName='GenericScriptTarget' // This will be used as a base name for all metadata across the connector
    //  itResourceName="$itResourceDefName" //the same as itResourceDefName by default

    /**
     * Give the name of the Application Instance that need to be generated. By default Application Instance name is taken as itResourceDefName
     * Application Instance is not a mandatory field
     **/
    //applicationInstanceName="$itResourceDefName"

    /*
     * Output files
     */
    //  connectorDir="../$itResourceDefName"                    // output dir of the connector, is the same as it resource name by default
    //  xmlFile='GenericScriptTarget-ConnectorConfig.xml'           // name of the dm xml of the connector
    //  configFileName='GenericScriptTarget-CI.xml'                     // name of the config xml
    //  propertiesFile='GenericScriptTarget-generator.properties'   // name of the resources/properties file
    //  version='11.1.1.5.0'        // connector version

    /*
     * Location of the generic script bundle jar
     */
    bundleJar='../lib/org.identityconnectors.genericscript-1.0.11150.jar'

    /*
     * The Configuration used to run the generic script bundle mentioned above, and get the schema by calling its SchemaOp, which is required for generating metadata
     */
    config = [
        'schemaFile' : 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/schema_sampletarget.txt', //This property is used during metadata generator,  provide file:///url of the file
        'resourceProperties' : 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/resource.properties', // Location of properties file which defines target specific resource parameters, provide file:///url of the file
        'host' : 'example.com',
        'port' : '1521',
        'user' : 'generic',
        'changeLogColumn':'LAST_UPDATE',
        'createScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/create.groovy',   // provide the file:///url of the script
        'updateScript': 'file:///scratch/jode/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/update.groovy',  // provide the file:///url of the script
        'deleteScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/update.groovy',  // provide the file:///url of the script
        'executeQueryScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/executequeryutil.groovy',  // provide the file:///url of the script
        'lookupScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/lookup.groovy', // provide the file:///url of the script
        'syncScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/syncutil.groovy', // provide the file:///url of the script
        'addMultiValuedAttributeScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/addchilddata.groovy', // provide the file:///url of the script
        'removeMultiValuedAttributeScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/removechilddata.groovy', // provide the file:///url of the script
        'connectionScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/connection.groovy', // provide the file:///url of the script
        //'checkAliveScript': 'file:///scratch/jdoe/OIMR2PS3/mw3722/idm6004/server/ConnectorDefaultDirectory/genericscript-11.1.1.5.0/metadata-generator/resources/target/checkAlive.groovy', // provide the file:///url of the script
        //'disposeScript': '', // provide the file:///url of the script
        'scriptType': 'GROOVY' // proved script type, valid entries are GROOVY,BEANSHELL,JAVASCRIPT
    ]
    
    /**
      *  Lookup List is the list of attributes for which we need to create lookups and map those fields as lookup in form. 
      *  For Main Process Form Fields and a Multivalued field the format is 
      *         lookupAttributeList=["FieldName"]
      *  For Embedded Multi Valued field the format is
      *         lookupAttributeList=["ObjectClassName.SubFieldName"]
      *  lookups will be generated with the FieldNames in format Lookup.${ITResource}.${FieldName}
      *
      *  lookupList is not a mandatory field
      */        
        
    lookupAttributeList=['MyROLES.ROLENAME','MyGROUPS.GROUPNAME','ORGANIZATION']

     /* entitlementAttributeList is the list of fully Qualified field names to which entitlements need to be tagged. 
      * If you require entitlements for a multi valued attribute which is embedded then the format should be as 
      *         entitlementAttributeList=["${ObjectClass}.SubFieldName"]
      * If the attribute is just a MultiValued then the format is
      *         entitlementAttributeList=["MultiValuedFieldName"]
      *
      * entitlementAttributeList is not a mandatory attribute
      */

       entitlementAttributeList=["MyROLES.ROLENAME","MyGROUPS.GROUPNAME"]

     /**
     * Define alias for object class if it is other than ObjectClass.ACCOUNT_NAME and ObjectClass.GROUP_NAME  
     */
     
    //objectClassAlias = ['Person']
    
    /**
      *  Provide the attribute list that need to be handled as Date on process form
      *  Make sure these fields datatype in schema should be long
      *  dateAttributeList is not a mandatory field
      **/
    dateAttributeList = ["STARTDATE","ENDDATE","MyROLES.STARTDATE","MyGROUPS.STARTDATE"]
    /*
     * Target attribute to user fields alias
     */
    //Mandatory alias
    alias = ['__UID__':'USERID', '__NAME__':'USERNAME']
    //Optional aliases if any (Can also be used to give short names for lengthy attribute names)
    alias += ['GENERIC_ROLE':'GR','GENERIC_GROUP':'GG','ENDDATE':'ed', 'EMPLOYEE_NUMBER':'Emp']

    /*
     * Generate prepopulate adapters
     */
    prepopulate = ['__NAME__':'User Login', 'FIRSTNAME':'First Name', 'LASTNAME':'Last Name', '__PASSWORD__':'Password','EMAIL':'Email']

}

B.6 Sample Resource Properties File

The following is a sample resource.properties file that contains additional parameters that the connector uses to establish a connection between Oracle Identity Manager and the target system:

portNumber=1521
databaseName=orcl

B.7 Sample Scripts for Connector Operations

This section lists the scripts used to perform connector operations on the sample target system using the Generic Scripting connector.

All scripts in this section have been written in Groovy scripting language.

B.7.1 Check Alive Script

The check alive script periodically verifies whether the physical connection between the connector and target system is alive. The following is a sample check alive script:

package groovy;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.jdbc.driver.OracleDriver;
import org.identityconnectors.framework.common.exceptions.ConnectionFailedException;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
import groovy.sql.Sql;

ResultSet result = null;
PreparedStatement stmt = null;
trace.info("Checking database connection is valid or not");
try {
    if (conn == null
    || conn.isClosed()) {
        trace.info("Connection is closed")
        throw new ConnectionFailedException("Connection Failed ");
    }
    trace.info("test connection using SELECT 1 FROM DUAL");
    //execute sample query to check database connection is valid or not
    stmt = conn.prepareStatement("SELECT 1 FROM DUAL");
    result = stmt.executeQuery();
    trace.info("connection is valid");
} catch (SQLException ex) {
    //Throw an error if any error while executing the query
    throw new ConnectionFailedException("Connection Failed ");
}

B.7.2 Connection Script

The connection script creates the connection between the connector and target system. The following is a sample connection script:

package groovy;
import java.sql.Connection;
import java.sql.DriverManager;
import oracle.jdbc.driver.OracleDriver;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
import groovy.sql.Sql;
import oracle.jdbc.pool.OracleDataSource;
import org.identityconnectors.common.security.GuardedString;

Connection ret = null;
try {
    OracleDataSource ds = new OracleDataSource()
    ds.user = configuration.getUser() // Read user from IT resource
    //Password field is encrypted, use GuardedString.Accessor for reading password
    GuardedString guard= configuration.getPassword()
    guard.access(new GuardedString.Accessor()
            {
                public void access(char[] clearChars)
                {
                    ds.password=new String(clearChars);
                }
            }
            );

    ds.driverType = 'thin'
    ds.serverName = configuration.getHost()
    ds.portNumber = Integer.parseInt(configuration.getPortNumber()) //get Port number defined in resources.properties file ( portNumber = 19999)
    ds.databaseName = configuration.getDatabaseName() //get database name defined in resources.properties file ( portNumber = 19999)
    // load the driver class..
    test =  Sql.newInstance(ds)
    ret =test.createConnection()
    ret.setAutoCommit(true);
}//end try
catch (Exception e)
{
    trace.error(e, "Exception while connecting to database");
    throw ConnectorException.wrap(e);
}
//Must return connection object, so that same connection will be available to all subsequent scripts
return ret;

B.7.3 Dispose Script

The following is a sample script to dispose any configuration object:

package groovy;
import org.identityconnectors.framework.common.exceptions.ConnectionFailedException;

trace.info("[Dispose-Groovy] Closing the connection");

try {
    //Close the connection. conn is the script argument
    conn.close();
}
catch(Exception e) {
    throw new ConnectionFailedException("Could not close connection, Connection already closed");
}

B.7.4 Create Script

The following is a sample groovy script for performing a create provisioning operation:

"package groovy
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.*;
import java.util.Date.*;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.common.objects.*;

import java.text.*;

// START HERE
System.out.println("[Create-Groovy] Attributes::"+attributes);
//USERID,PASSWORD,USERNAME,STATUS,EMAIL,FIRSTNAME,LASTNAME,ORGANIZATION,CITY,EMPLOYEE_NUMBER,STARTDATE,ENDDATE,LONGVALUE,FLOATVALUE,CHARVALUE
//Get all the attributes from script argument

// This shows how to read arrtibures


String uid = attributes.get("__NAME__")!=null? attributes.get("__NAME__").getValue().get(0):null;
GuardedString pass = attributes.get("__PASSWORD__")!=null? attributes.get("__PASSWORD__").getValue().get(0):null;
String uname = attributes.get("__NAME__")!=null? attributes.get("__NAME__").getValue().get(0):null;
enableValue = attributes.get("__ENABLE__")!=null? attributes.get("__ENABLE__").getValue().get(0):true;
String email=attributes.get("EMAIL")!=null? attributes.get("EMAIL").getValue().get(0):null;
String first=attributes.get("FIRSTNAME")!=null? attributes.get("FIRSTNAME").getValue().get(0):null;
String last=attributes.get("LASTNAME")!=null? attributes.get("LASTNAME").getValue().get(0):null;
String org=attributes.get("ORGANIZATION")!=null? attributes.get("ORGANIZATION").getValue().get(0):null;
String city=attributes.get("CITY")!=null? attributes.get("CITY").getValue().get(0):null;
emp=attributes.get("EMPLOYEE_NUMBER")!=null? attributes.get("EMPLOYEE_NUMBER").getValue().get(0):null;
startdate = attributes.get("STARTDATE")!=null? attributes.get("STARTDATE").getValue().get(0):null;
enddate = attributes.get("ENDDATE")!=null? attributes.get("ENDDATE").getValue().get(0):null;
String longval=attributes.get("LONGVALUE")!=null? attributes.get("LONGVALUE").getValue().get(0):null;
floatval=attributes.get("FLOATVALUE")!=null? attributes.get("FLOATVALUE").getValue().get(0):null;
charval=attributes.get("CHARVALUE")!=null? attributes.get("CHARVALUE").getValue().get(0):null;

PreparedStatement createStmt = null;
String ret =null;
try {
        
        //Call Target API to create a user 
        
        //createStmt =   conn.prepareStatement(....); or createStmt =   conn.createStatement(....);
        //createStmt =   conn.prepareStatement("INSERT INTO generic_view(USERID,PASSWORD,USERNAME,STATUS,EMAIL,FIRSTNAME,LASTNAME,ORGANIZATION,CITY,EMPLOYEE_NUMBER,STARTDATE,ENDDATE,LONGVALUE,FLOATVALUE,CHARVALUE) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); 
                //Set the input parameters
        createStmt =   conn.prepareStatement("INSERT INTO GENERIC_PARENT(USERID,PASSWORD,USERNAME,STATUS,EMAIL,FIRSTNAME,LASTNAME,ORG,CITY,EMPLOYEE_NUMBER,STARTDATE,ENDDATE,LONGVALUE,FLOATVALUE,CHARVALUE) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
        createStmt.setString(1, uid);
        if(pass!=null)
        {
        pass.access(new GuardedString.Accessor(){ 
       public void access(char[] clearChars) {  createStmt.setString(2, new String(clearChars));} 
        });
        }
        else
        createStmt.setString(2,null);
        
        createStmt.setString(3, uname);

        if(enableValue)
                createStmt.setString(4,"Enabled");
        else
                createStmt.setString(4,"Disabled");
        createStmt.setString(5, email);
        createStmt.setString(6, first);
        createStmt.setString(7, last);
        createStmt.setString(8, org);
        createStmt.setString(9, city);    
        
        if (emp!=null)
        createStmt.setInt(10, emp);
        else 
        {
        createStmt.setNull(10, java.sql.Types.INTEGER);
        }

        DateFormat formatter = new SimpleDateFormat("dd-MMM-yy");


        if (startdate!=null)
        {
                if (startdate == 0){

                createStmt.setString(11,null);

}
                else
        {
        Date da=new Date(startdate);
        st=formatter.format(da);
        createStmt.setString(11,st);

        
        //createStmt.setString(11,null);
        }
        }

        if(enddate!=null)
        {
        if (enddate == 0)
                createStmt.setString(12,null);
                else
        {

        Date eda= new Date(enddate);
        et= formatter.format(eda);
        createStmt.setString(12,et);
       //createStmt.setString(12,null);
        }
        }
        //else createStmt.setObject(12, null);

        createStmt.setString(13, longval);
        if(floatval!=null)
        {
        createStmt.setDouble(14, floatval);}
        else createStmt.setNull(14, java.sql.Types.FLOAT);
        if(charval!=null)
        createStmt.setString(15, charval);
        else createStmt.setObject(15, null);

       createStmt.executeUpdate();
        

        
} finally{
        //close the sql statements
        if (createStmt != null)
                createStmt.close();
}
System.out.println("[Create] Created User::"+uid);
//Return Uid from the script
return new Uid(uid);
"

B.7.5 Update Script

The following is a sample groovy script for performing an update provisioning operation:

"package groovy
import java.sql.PreparedStatement;
import oracle.jdbc.driver.OraclePreparedStatement;
import java.sql.ResultSet;
import java.text.*;
import java.util.Date.*;
import org.identityconnectors.framework.common.exceptions.*;
import org.identityconnectors.framework.common.objects.*;
import org.identityconnectors.common.security.GuardedString;
import java.text.*;


System.out.println("[Update-Groovy] Atrributes::"+ attributes);

//During an Update operation,OIM  sends the UID attribute along with updated attributes.

//Get all the values of attributes

String uid = attributes.get("__UID__")!=null? attributes.get("__UID__").getValue().get(0):null;
GuardedString pass = attributes.get("__PASSWORD__")!=null? attributes.get("__PASSWORD__").getValue().get(0):null;
String uname = attributes.get("__NAME__")!=null? attributes.get("__NAME__").getValue().get(0):null;
enableValue = attributes.get("__ENABLE__")!=null? attributes.get("__ENABLE__").getValue().get(0):true;
String email=attributes.get("EMAIL")!=null? attributes.get("EMAIL").getValue().get(0):null;
String first=attributes.get("FIRSTNAME")!=null? attributes.get("FIRSTNAME").getValue().get(0):null;
String last=attributes.get("LASTNAME")!=null? attributes.get("LASTNAME").getValue().get(0):null;
String org=attributes.get("ORG")!=null? attributes.get("ORG").getValue().get(0):null;
String city=attributes.get("CITY")!=null? attributes.get("CITY").getValue().get(0):null;
emp = attributes.get("EMPLOYEE_NUMBER")!=null? attributes.get("EMPLOYEE_NUMBER").getValue().get(0):null;
startdate = attributes.get("STARTDATE")!=null? attributes.get("STARTDATE").getValue().get(0):null;
enddate = attributes.get("ENDDATE")!=null? attributes.get("ENDDATE").getValue().get(0):null;
longval = attributes.get("LONGVALUE")!=null? attributes.get("LONGVALUE").getValue().get(0):null;
floatval = attributes.get("FLOATVALUE")!=null? attributes.get("FLOATVALUE").getValue().get(0):null;
charval=attributes.get("CHARVALUE")!=null? attributes.get("CHARVALUE").getValue().get(0):null;


//Throw exception if uid is null
if(uid==null) throw new ConnectorException("UID Cannot be Null");

PreparedStatement upstmt = null;
//upstmt=null;
try {
                
        //Call Target APIS to update the record
        
        //stmt =   conn.prepareStatement(....); or stmt =   conn.createStatement(....);
        //upstmt = conn.prepareStatement("UPDATE GENERIC_PARENT SET PASSWORD=COALESCE(?,PASSWORD),USERNAME=COALESCE(?,USERNAME),STATUS=COALESCE(?, STATUS), EMAIL= COALESCE(?, EMAIL),FIRSTNAME=COALESCE(?, FIRSTNAME),LASTNAME =COALESCE(?, LASTNAME), ORGANIZATION= COALESCE(?, ORGANIZATION), CITY= COALESCE(?, CITY), EMPLOYEE_NUMBER= COALESCE(?, EMPLOYEE_NUMBER), STARTDATE=COALESCE(to_date(?,'dd-Mon-yy'), STARTDATE),ENDDATE=COALESCE(to_date(?,'dd-Mon-yy'), ENDDATE),LONGVALUE=COALESCE(?, LONGVALUE),FLOATVALUE=COALESCE(?, FLOATVALUE),CHARVALUE=COALESCE(?, CHARVALUE) WHERE USERID =?");
        upstmt = conn.prepareStatement("UPDATE GENERIC_PARENT SET PASSWORD=COALESCE(?,PASSWORD),USERNAME=COALESCE(?,USERNAME),STATUS=COALESCE(?, STATUS), EMAIL= COALESCE(?, EMAIL),FIRSTNAME=COALESCE(?, FIRSTNAME),LASTNAME =COALESCE(?, LASTNAME), ORG= COALESCE(?, ORG), CITY= COALESCE(?, CITY), EMPLOYEE_NUMBER= COALESCE(?, EMPLOYEE_NUMBER),STARTDATE=COALESCE(to_date(?,'dd-Mon-yy'), STARTDATE),ENDDATE=COALESCE(to_date(?,'dd-Mon-yy'), ENDDATE),FLOATVALUE=COALESCE(?, FLOATVALUE),CHARVALUE=COALESCE(?, CHARVALUE) WHERE USERID =?");


        //Set the input parameters
        if(pass!=null)
        {
        pass.access(new GuardedString.Accessor(){ 
   public void access(char[] clearChars) {  upstmt.setString(1, new String(clearChars));
        System.out.println("password is "+ new String(clearChars)); } 
        });
        }
        else
        upstmt.setString(1,null);

        upstmt.setString(2, uname);
        if(enableValue)
                upstmt.setString(3,"Enabled");
        else
                upstmt.setString(3,"Disabled");
        upstmt.setString(4, email);
        upstmt.setString(5, first);
        upstmt.setString(6, last);
        upstmt.setString(7, org);
        upstmt.setString(8, city);
        println("before employee");
        if (emp!=null)
upstmt.setInt(9, emp);
else 
{
upstmt.setNull(9, java.sql.Types.INTEGER);
}

                        println("before startdate");
DateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
        if (startdate!=null)
        {
        Date da=new Date(startdate);
        st=formatter.format(da);
        upstmt.setString(10,st);
        }
        else
        upstmt.setString(10,null);

        if(enddate!=null)
        {
        Date eda= new Date(enddate);
        et= formatter.format(eda);
        upstmt.setString(11,et);
        }
        else
        upstmt.setString(11,null);


println("before long");
        //if(longval!=null){upstmt.setLong(12, longval);}
        //else upstmt.setNull(12, java.sql.Types.BIGINT);
println("before float");
        if(floatval!=null){upstmt.setDouble(12, floatval);}
        else upstmt.setNull(12, java.sql.Types.FLOAT);
        if(charval!=null)
        upstmt.setString(13, charval);
        else upstmt.setObject(13, null);
        upstmt.setString(14, uid);

        upstmt.executeUpdate();
        

} finally {
        if (upstmt!= null)
                upstmt.close();
};
System.out.println("[Update] Updated user::"+ uid);
return new Uid(uid);"

B.7.6 Delete Script

The following is a sample groovy script for performing a delete provisioning operation:

"package groovy;
import java.sql.PreparedStatement;
import org.identityconnectors.framework.common.objects.*;

//Get the UID from the input map 'attributes'
String uid      = attributes.get("__UID__").getValue().get(0);

System.out.println("[Delete-Groovy] Deleting user:: "+ uid);

try {
        ///Delete data from child tables and then, main table
        
        //Delete user roles
        st = conn.prepareStatement("DELETE FROM GENERIC_ROLE WHERE USERID=?");
        st.setString(1, uid);
        st.executeUpdate();
//      st.close();
        
        //Delete user groups
        st = conn.prepareStatement("DELETE FROM GENERIC_GROUP WHERE USERID=?");
        st.setString(1, uid);
        st.executeUpdate();
        //st.close();
        
        //Delete user account
        st = conn.prepareStatement("DELETE FROM GENERIC_PARENT WHERE USERID=?");
        st.setString(1, uid);
        st.executeUpdate();
} finally {
        if (st != null)
                st.close();
};
System.out.println("Deleted user:: "+ uid);
"

B.7.7 Add Child Data Script

The following is a sample groovy script for adding multivalued child data:

"package groovy
import org.identityconnectors.framework.common.objects.*;
import java.text.*;

System.out.println("[addMultiValuedAttributeScript-Groovy] Adding Child data::"+ attributes);
childst =null;
try {
        //Adding Group data
        
        childDataEOSet = null;
        
        //The child attributes are returned as a set of embedded objects. Each  Embedded object
        // will provide a row of data in the child table.
        
        // Logic for handling simple multi valued attributes
        
        if(attributes.get("GENERIC_GROUP")!=null) // Here "Groups" is object class of simple multi-valued attribute
        {
                
                childDataEOSet=attributes.get("GENERIC_GROUP").getValue();
                childst=conn.prepareStatement("INSERT INTO GENERIC_GROUP VALUES (?,?,?,?)");
                String id      = attributes.get("__UID__").getValue().get(0);

                if(childDataEOSet !=null){
                        //Iterate through child data and insert into table
                        System.out.println("[addMultiValuedAttributeScript] Adding Group data.");
                        for( iterator = childDataEOSet.iterator(); iterator.hasNext(); )
                        {
                                eo = iterator.next();
                                attrsSet=eo.getAttributes();
                                grpattr=AttributeUtil.find("GROUPID",attrsSet);
                                //grpattr=  eo; 
                                if(grpattr!=null){
                                        // You are iterating simple multi valued attributes here, Call target APIs here
                                        //conn object is available here
                                        groupid=grpattr.getValue().get(0);
                                        groupname=AttributeUtil.find("GROUPNAME",attrsSet).getValue().get(0);
                                        groupstart=AttributeUtil.find("STARTDATE",attrsSet).getValue().get(0);
                                
                                        childst.setString(1, id);
                                        childst.setString(2, groupname);
                                        Date da=new Date(groupstart);
        
                                        SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
                                        String st=formatter.format(da);
                                        

                                        childst.setString(3, st);
                                        childst.setString(4, groupid);

                                        childst.executeUpdate();
                                        childst.clearParameters();
                                }
                        };
                }
        }
} finally {
                if (childst != null)
        childst.close();
        
};

try {
        childDataEOSet = null;
// Logic for handling Complex multi valued attributes
        if(attributes.get("GENERIC_ROLE")!=null)// Here "Roles" is object class of simple multi-valued attribute
        {
                
                childDataEOSet=attributes.get("GENERIC_ROLE").getValue();
                childst=conn.prepareStatement("INSERT INTO GENERIC_ROLE VALUES (?,?,?,?)");

                String id      = attributes.get("__UID__").getValue().get(0);

                if(childDataEOSet !=null)
                {
                        System.out.println("[addMultiValuedAttributeScript] Adding Role data.");
                        for( iterator = childDataEOSet.iterator(); iterator.hasNext(); )
                        {
                                eo = iterator.next();
                                attrsSet = eo.getAttributes(); // Get all the attributes of child object
                                roleattr=AttributeUtil.find("ROLEID",attrsSet);
                                
                                
                                // You are iterating complex multi valued attributes here, Call target APIs here
                            //conn object is available here
                                if(roleattr!=null){
                                        // You are iterating simple multi valued attributes here, Call target APIs here
                                        //conn object is available here
                                        roleid=roleattr.getValue().get(0);
                                        rolename=AttributeUtil.find("ROLENAME",attrsSet).getValue().get(0);
                                        rolestart=AttributeUtil.find("STARTDATE",attrsSet).getValue().get(0);
                                
                                        childst.setString(1, id);
                                        childst.setString(2, rolename);
                                        childst.setString(3, roleid);
                                        Date da=new Date(rolestart);
        
                                        SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
                                        String st=formatter.format(da);
                                        

                                        childst.setString(4, st);
                                        

                                        childst.executeUpdate();
                                        childst.clearParameters();
                                }

                        };
                }
        }
} finally {
if (childst != null)
                childst.close();
        
};

B.7.8 Remove Child Data Script

The section lists a sample groovy script for for removing multivalued child data. The script calls the DELETE_USERGROUP and DELETE_USERROLE stored procedures that have been created on the target system.

The procedure for DELETE_USERGROUP is as follows:

"create or replace PROCEDURE DELETE_USERGROUP
(user_id GENERIC_GROUP.USERID%TYPE , group_id GENERIC_GROUP.GROUPID%TYPE )
 AS
BEGIN
DELETE from GENERIC_GROUP where groupid=group_id and userid=user_id;
END DELETE_USERGROUP;"

The procedure for DELETE_USERROLE is as follows:

"create or replace PROCEDURE DELETE_USERROLE
(user_id GENERIC_ROLE.USERID%TYPE , role_id GENERIC_ROLE.ROLEID%TYPE )
 AS
BEGIN
DELETE FROM GENERIC_ROLE where userid=user_id and roleid=role_id  ;
END DELETE_USERROLE;"

The following is a sample groovy script for removing multivalued child data:

"import org.identityconnectors.framework.common.objects.*;
System.out.println("[removeMultiValuedAttributeScript] Removing Child data::"+ attributes);

try {
        childDataEOSet = null;
        delSt = null;
        //Get UID 
        String id      = attributes.get("__UID__").getValue().get(0);
        if(attributes.get("GENERIC_GROUP")!=null)
        {
                childDataEOSet=attributes.get("GENERIC_GROUP").getValue();
                //Delete child data using stored procedure
                delSt= conn.prepareCall("{call DELETE_USERGROUP(?,?)}");
            if(childDataEOSet !=null){
                        System.out.println("[removeMultiValuedAttributeScript] Removing Group data.");
                        //Iterate through child data and delete
                        for( iterator = childDataEOSet.iterator(); iterator.hasNext(); )
                        {
                                eo = iterator.next();
                                attrsSet = eo.getAttributes();
                                grpattr=AttributeUtil.find("GROUPID",attrsSet);
                                if(grpattr!=null){
                                        groupid=grpattr.getValue().get(0);
                                        delSt.setString(1, id);
                                        delSt.setString(2, groupid);
                                        delSt.executeUpdate();
                                        System.out.println("[removeMultiValuedAttributeScript] Deleted Group::"+ grpattr);
                                }
                        };
                }

        }
} finally {
        if (delSt != null)
        delSt.close();
};

try {
        childDataEOSet = null;
        delSt = null;
        String id      = attributes.get("__UID__").getValue().get(0);
        if(attributes.get("GENERIC_ROLE")!=null)
        {
                childDataEOSet=attributes.get("GENERIC_ROLE").getValue();
                delSt= conn.prepareCall("{call DELETE_USERROLE(?,?)}");
            if(childDataEOSet !=null){
                        System.out.println("[removeMultiValuedAttributeScript] Removing Role data.");
                        for( iterator = childDataEOSet.iterator(); iterator.hasNext(); )
                        {
                        
                                eo = iterator.next();
                                attrsSet = eo.getAttributes();
                                roleattr=AttributeUtil.find("ROLEID",attrsSet);
                                if(roleattr!=null){
                                        rolename=roleattr.getValue().get(0);
                                        delSt.setString(1, id);
                                        delSt.setString(2, rolename);
                                        delSt.executeUpdate();
                                        System.out.println("[removeMultiValuedAttributeScript] Deleted Role::"+ rolename);
                                }
                        };
                }
        }
} finally {
        if (delSt != null)
                delSt.close();
};

B.7.9 Lookup Field Synchronization Script

The section lists a sample groovy script for performing lookup field synchronization on the Role Name, Group Name, and Organization lookup fields. This script calls the GET_ROLES, GET_GROUPS, and GET_ORGANIZATIONS stored procedures that have been created on the target system.

The procedure for GET_ROLES is as follows:

"create or replace PROCEDURE GET_ROLES
( user_cursor OUT TYPES.cursorType
) AS
BEGIN
OPEN user_cursor FOR
SELECT ROLENAME,ROLEID from GENERIC_ROLES;
END GET_ROLES;"

The procedure for GET_GROUPS is as follows:

"create or replace PROCEDURE GET_GROUPS
( user_cursor OUT TYPES.cursorType
) AS
BEGIN
OPEN user_cursor FOR
SELECT GROUPNAME,GROUPID from GENERIC_GROUPS;
END GET_GROUPS;"

The procedure for GET_ORGANIZATIONS is as follows:

create or replace PROCEDURE GET_ORGANIZATIONS
( user_cursor OUT TYPES.cursorType
) AS
BEGIN
OPEN user_cursor FOR
SELECT ORGNAME,ORGID from GENERIC.ORGANIZATIONS;
END GET_ORGANIZATIONS;

The following is a sample groovy script for performing lookup field synchronization:

"package groovy;
import org.identityconnectors.framework.common.objects.*;
rs = null;
st = null;
try {
        System.out.println("[Lookup] Lookup Recon timing::"+ timing);
        System.out.println("[Lookup] Attributes to Get::"+ ATTRS_TO_GET);
        
        // This script is common for all lookups. Read the timing ( input) and return the data accordingly
        // The format of timing is : executeQuery:<objectclass>, objectclass is the value of object type in schedule job
        
        // ATTRS_TO_GET and timing are the script arguments
        
        String codekey =  ATTRS_TO_GET[0];
        String decodekey = ATTRS_TO_GET[1];
        System.out.println("0"+ ATTRS_TO_GET[0]);
        System.out.println("1"+ ATTRS_TO_GET[1]);

        if( timing.equals("executeQuery:ROLENAME"))
        {
                System.out.println("[Lookup] Getting Roles.");
                st = conn.prepareCall("{call GET_ROLES(?)}");
        }       
        else if ( timing.equals("executeQuery:GROUPNAME"))
        {
                System.out.println("[Lookup] Getting Groups.");
                st = conn.prepareCall("{call GET_GROUPS(?)}");
        
        }
        else if ( timing.equals("executeQuery:ORGANIZATION"))
        {
                System.out.println("[Lookup] Getting Organizations.");
                st = conn.prepareCall("{call GET_ORGANIZATIONS(?)}");
        
        }
        st.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.CURSOR);
        st.execute();
        rs = st.getObject(1);
        while (rs.next()) {
                cob = new ConnectorObjectBuilder();
        
        util.addAttribute(codekey,rs.getString(codekey));
        util.addAttribute(decodekey,rs.getString(decodekey));

                
        if (!util.build()) return;      
        }
        
} finally {
        if( null != rs)
                rs.close();
        if( null != st)
                st.close();
        
}
"

B.7.10 Full and Filtered Reconciliation Script

This section lists a sample groovy script for performing full or filtered reconciliation. This script calls the GET_GENERICGROUP, GET_GENERICROLE, and GENERIC_EXECUTE_QUERY stored procedures for full and filtered reconciliation.

The following stored procedures have been created on the target system for full or filtered reconciliation:

"create or replace PROCEDURE GET_GENERICGROUP
( user_cursor OUT TYPES.cursorType, userin IN VARCHAR2
) AS
BEGIN
OPEN user_cursor FOR
SELECT GROUPID,GROUPNAME,STARTDATE from GENERIC_GROUP where USERID=userin;
END GET_GENERICGROUP;"
"create or replace PROCEDURE GET_GENERICROLE
( user_cursor OUT TYPES.cursorType, userin IN VARCHAR2
) AS
BEGIN
OPEN user_cursor FOR
SELECT ROLEID,ROLENAME,STARTDATE from GENERIC_ROLE where USERID=userin;
END GET_GENERICROLE;"
"create or replace
PROCEDURE GENERIC_EXECUTE_QUERY
( user_cursor OUT TYPES.cursorType
) AS
BEGIN
OPEN user_cursor FOR
SELECT GENERIC_PARENT.USERID,GENERIC_PARENT.PASSWORD, GENERIC_PARENT.FIRSTNAME , GENERIC_PARENT.LASTNAME, GENERIC_PARENT.EMAIL ,GENERIC_PARENT.ORG,GENERIC_PARENT.CITY,GENERIC_PARENT.STARTDATE ,GENERIC_PARENT.EMPLOYEE_NUMBER,GENERIC_PARENT.STATUS,GENERIC_PARENT.USERNAME FROM GENERIC_PARENT;
END GENERIC_EXECUTE_QUERY;

To execute procedure from sqldeveloper
var rc refcursor
EXECUTE GENERIC_EXECUTE_QUERY(:rc)
print rc"

The script for full and filtered reconciliation is as follows:

"package groovy
import org.identityconnectors.framework.common.objects.*;
import java.lang.reflect.*;
import java.lang.String;
import org.identityconnectors.common.security.GuardedString;
import java.text.*;
import java.util.Set;
import java.util.Date.*;
import java.sql.Date.*;
rs = null;
st = null;
try {
        if( !filterMap.isEmpty())
        {
                System.out.println("[Execute Query] Performing Recon with Filter. Filter is::"+ filterMap+" And Filer Params are::"+filterMap);
                //String[] filter = filterParams.get(0).split(":");
               //   st = conn.prepareCall("{call EXECUTE_QUERY_WITH_FILTER(?,?,?)}");
                //st.setString(2, filter[0]);
                //st.setString(3, filter[1]);
                 filterAttr = filterMap.get("filterattribute");
        filterOp = filterMap.get("filteroperator");
        //              if("EQUALto".equalsIgnoreCase(filterOp))
        //      {
        //              dbOp="=";
        //      }
        filterVal = filterMap.get("filtervalue");
                

        st = conn.prepareCall("{call EXECUTE_QUERY_WITH_FILTER(?,?,?)}");
                st.setString(2, filterAttr);
                st.setString(3, filterVal);
                //st.setString(4, filterOp);

        }
        else // Full recon 
        {
                // // Call target apis to get all records
                System.out.println("[Execute Query] Performing Full Recon.");
                //SELECT GENERIC_PARENT.USERID,GENERIC_PARENT.PASSWORD, GENERIC_PARENT.FIRSTNAME, GENERIC_PARENT.LASTNAME, GENERIC_PARENT.EMAIL ,GENERIC_PARENT.ORG,GENERIC_PARENT.CITY,GENERIC_PARENT.STARTDATE ,GENERIC_PARENT.EMPLOYEE_NUMBER,GENERIC_PARENT.STATUS,GENERIC_PARENT.USERNAME,GENERIC_PARENT.ENDDATE,GENERIC_PARENT.LONGVALUE,GENERIC_PARENT.FLOATVALUE,GENERIC_PARENT.CHARVALUE FROM GENERIC_PARENT;
                st = conn.prepareCall("{call GENERIC_EXECUTE_QUERY(?)}");
    }
        st.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.CURSOR);
        st.execute();
        rs = st.getObject(1);
                
                
        while (rs.next()) {
                cob = new ConnectorObjectBuilder();
                cob.setObjectClass(ObjectClass.ACCOUNT);
                Attribute uid= AttributeBuilder.build(new String("__UID__"),rs.getString(1));
                Attribute fname= AttributeBuilder.build(new String("FIRSTNAME"),rs.getString(3));
                Attribute lname= AttributeBuilder.build(new String("LASTNAME"),rs.getString(4));
                Attribute email= AttributeBuilder.build(new String("EMAIL"),rs.getString(5));
                Attribute org= AttributeBuilder.build(new String("ORG"),rs.getString(6));
                Attribute city= AttributeBuilder.build(new String("CITY"),rs.getString(7));
                //dbDate = rs.getDate(8);
                //Attribute startdate = AttributeBuilder.build(new String("STARTDATE"),rs.getString(8));
                
                Attribute emp= AttributeBuilder.build(new String("EMPLOYEE_NUMBER"),rs.getString(9));
                Attribute status= AttributeBuilder.build(new String("STATUS"),rs.getString(10));
                Attribute name= AttributeBuilder.build(new String("__NAME__"),rs.getString(11));
                
                
                //dbDate = rs.getDate(12);
                
                //Attribute enddate = AttributeBuilder.build(new String("ENDDATE"),dbDate.getTime());
                //Attribute longval= AttributeBuilder.build(new String("LONGVALUE"),rs.getString(13));
                //Attribute floatval= AttributeBuilder.build(new String("FLOATVALUE"),rs.getString(14));
                //Attribute charval= AttributeBuilder.build(new String("CHARVALUE"),rs.getString(15));

                
                cob.addAttribute(fname);
                cob.addAttribute(lname);
                cob.addAttribute(uid);
                cob.addAttribute(name);
                cob.addAttribute(email);
                //cob.addAttribute(startdate);
                //cob.addAttribute(enddate);
                cob.addAttribute(status);
                cob.addAttribute(org);
                cob.addAttribute(city);
                //cob.addAttribute(longval);
                //cob.addAttribute(floatval);
                //cob.addAttribute(charval);
                cob.addAttribute(emp);

        //      util.addAttribute(Uid.NAME,rs.getString(1)); 
        //      util.addAttribute(Name.NAME,rs.getString(11)); // Name must be provided
        //      util.addAttribute('FIRSTNAME',rs.getString(3));
        //      util.addAttribute('LASTNAME',rs.getString(4));
        //      util.addAttribute('EMAIL',rs.getString(5));
        //      util.addAttribute('ORGANIZATION',rs.getString(6));
        //      util.addAttribute('CITY',rs.getString(7));
        //      util.addAttribute('STARTDATE',rs.getDate(8));
        //      util.addAttribute('EMPLOYEE_NUMBER',new Integer(rs.getString(9)));
        //      
        //      util.addAttribute('STATUS',rs.getString(10));
        //      util.addAttribute('ENDDATE',rs.getDate(12));
        //      util.addAttribute('LONGVALUE',new Long(rs.getString(13)));
        //      util.addAttribute('FLOATVALUE',new Double(rs.getString(14)));
        //      util.addAttribute('CHARVALUE',rs.getString(15));

        roleStmt = conn.prepareCall("{call GET_GENERICROLE(?,?)}");

                roleStmt.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.CURSOR);
            roleStmt.setString(2, rs.getString(1));
            roleStmt.execute();
                roleResultSet = roleStmt.getObject(1);
                java.util.List<EmbeddedObject> eoList = new ArrayList<EmbeddedObject>();
                while (roleResultSet.next()) {
                        Attribute roleId= AttributeBuilder.build(new String("ROLEID"),roleResultSet.getString(1));
                Attribute roleName= AttributeBuilder.build(new String("ROLENAME"),roleResultSet.getString(2));
                //      dbDate = roleResultSet.getDate(3);
                //Attribute startdater = AttributeBuilder.build(new String("STARTDATE"),dbDate.getTime());
        
                        EmbeddedObjectBuilder roleEA = new EmbeddedObjectBuilder();
                        roleEA.addAttribute(roleId);
                        roleEA.addAttribute(roleName);
                        //roleEA.addAttribute(startdater);
                        roleEA.setObjectClass(new ObjectClass("GENERIC_ROLE"));
                        eoList.add(roleEA.build());
                }  
                roleResultSet.close();
                EmbeddedObject[] roleEm = eoList.toArray(new EmbeddedObject[eoList.size()]);
        cob.addAttribute(AttributeBuilder.build("GENERIC_ROLE", (Object[]) roleEm));

                                groupStmt = conn.prepareCall("{call GET_GENERICGROUP(?,?)}");
                groupStmt.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.CURSOR);
            groupStmt.setString(2, rs.getString(1));
            groupStmt.execute();
                groupResultSet = groupStmt.getObject(1);
                java.util.List<EmbeddedObject> geoList = new ArrayList<EmbeddedObject>();
                //System.out.println("groupresutset display"+groupResultSet);

                while (groupResultSet.next()) {
                Attribute groupId= AttributeBuilder.build(new String("GROUPID"),groupResultSet.getString(1));

                Attribute groupName= AttributeBuilder.build(new String("GROUPNAME"),groupResultSet.getString(2));
                //      dbDate = groupResultSet.getDate(3);
                //Attribute startdateg = AttributeBuilder.build(new String("STARTDATE"),dbDate.getTime());
                        EmbeddedObjectBuilder groupEA = new EmbeddedObjectBuilder();
                        groupEA.addAttribute(groupId);
                        groupEA.addAttribute(groupName);
                        //groupEA.addAttribute(startdateg);
                        groupEA.setObjectClass(new ObjectClass("GENERIC_GROUP"));
                        geoList.add(groupEA.build());

                }  
                groupStmt.close();


                EmbeddedObject[] groupEm = geoList.toArray(new EmbeddedObject[geoList.size()]);

       
        
        
        cob.addAttribute(AttributeBuilder.build("GENERIC_GROUP", (Object[]) groupEm));
                if(!handler.handle(cob.build())) return;
        }
} finally {
if( null != rs)
        rs.close();
        if( null != st)
        st.close();
        
}
"

B.7.11 Incremental Reconciliation Script

This section lists a sample groovy script for performing incremental reconciliation. This script calls a stored procedure that has been created on the target system as follows:

"create or replace PROCEDURE EXECUTE_QUERY_INCREMENTAL
( user_cursor OUT TYPES.cursorType, columnName IN VARCHAR2, columnValue IN VARCHAR2
) AS
BEGIN
if columnValue is NULL then
open user_cursor for 'SELECT GENERIC_PARENT.USERID,GENERIC_PARENT.PASSWORD,GENERIC_PARENT.FIRSTNAME,GENERIC_PARENT.LASTNAME,GENERIC_PARENT.EMAIL,GENERIC_PARENT.ORG,GENERIC_PARENT.CITY,GENERIC_PARENT.STARTDATE,GENERIC_PARENT.EMPLOYEE_NUMBER,GENERIC_PARENT.STATUS,GENERIC_PARENT.USERNAME,GENERIC_PARENT.ENDDATE,GENERIC_PARENT.LAST_UPDATE,to_char(GENERIC_PARENT.LAST_UPDATE) FROM GENERIC_PARENT';
else
open user_cursor for 'SELECT GENERIC_PARENT.USERID,GENERIC_PARENT.PASSWORD,GENERIC_PARENT.FIRSTNAME,GENERIC_PARENT.LASTNAME,GENERIC_PARENT.EMAIL,GENERIC_PARENT.ORG,GENERIC_PARENT.CITY,GENERIC_PARENT.STARTDATE,GENERIC_PARENT.EMPLOYEE_NUMBER,GENERIC_PARENT.STATUS,GENERIC_PARENT.USERNAME,GENERIC_PARENT.ENDDATE,GENERIC_PARENT.LAST_UPDATE, to_char(GENERIC_PARENT.LAST_UPDATE) FROM GENERIC_PARENT where '|| columnName ||' >  to_timestamp ('''||columnValue||''')';
end if;
END EXECUTE_QUERY_INCREMENTAL;"

The following is a sample groovy script for performing incremental reconciliation:

"package groovy;
import org.identityconnectors.framework.common.objects.*;

import java.lang.reflect.*;

import org.identityconnectors.common.security.GuardedString;

import java.text.*;
import java.util.Date.*;
import java.sql.Date.*;

rs = null;
st = null;
try {

System.out.println("[Sync] Performing Incremental Recon.");
System.out.println("[Sync] Sync Attribute::"+syncattribute);
System.out.println("[Sync] Sync token:: "+synctoken);

// You have syncattribute and synctoken as script arguments for sync operation
// Call target APIs to get information

st = conn.prepareCall("{call EXECUTE_QUERY_INCREMENTAL(?,?,?)}");
//GENERIC_PARENT.USERID,GENERIC_PARENT.PASSWORD, GENERIC_PARENT.FIRSTNAME, GENERIC_PARENT.LASTNAME, GENERIC_PARENT.EMAIL ,GENERIC_PARENT.ORGANIZATION,GENERIC_PARENT.CITY,GENERIC_PARENT.STARTDATE 
//,GENERIC_PARENT.EMPLOYEE_NUMBER,GENERIC_PARENT.STATUS,GENERIC_PARENT.USERNAME,GENERIC_PARENT.ENDDATE,GENERIC_PARENT.LONGVALUE,GENERIC_PARENT.FLOATVALUE,GENERIC_PARENT.CHARVALUE
st.setString(2, syncattribute);
st.setString(3, synctoken!=null? synctoken.getValue():null);

st.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.CURSOR);
st.execute();
rs = st.getObject(1);
//SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z");
//DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

while (rs.next()) {
                cob = new ConnectorObjectBuilder();
                cob.setObjectClass(ObjectClass.ACCOUNT);
                
                Attribute uid= AttributeBuilder.build(new String("__UID__"),rs.getString(1));
                Attribute fname= AttributeBuilder.build(new String("FIRSTNAME"),rs.getString(3));
                Attribute lname= AttributeBuilder.build(new String("LASTNAME"),rs.getString(4));
                Attribute email= AttributeBuilder.build(new String("EMAIL"),rs.getString(5));
                Attribute org= AttributeBuilder.build(new String("ORG"),rs.getString(6));
                Attribute city= AttributeBuilder.build(new String("CITY"),rs.getString(7));

                //dbDate = rs.getDate(8);
                //Attribute startdate = AttributeBuilder.build(new String("STARTDATE"),dbDate.getTime());
                
                Attribute emp= AttributeBuilder.build(new String("EMPLOYEE_NUMBER"),rs.getString(9));

                Attribute status= AttributeBuilder.build(new String("STATUS"),rs.getString(10));
                Attribute name= AttributeBuilder.build(new String("__NAME__"),rs.getString(11));
                
                
                //dbDate = rs.getDate(12);
                //Attribute enddate = AttributeBuilder.build(new String("ENDDATE"),dbDate.getTime());
                //Attribute longval= AttributeBuilder.build(new String("LONGVALUE"),rs.getString(13));
                //Attribute floatval= AttributeBuilder.build(new String("FLOATVALUE"),rs.getString(14));
                //Attribute charval= AttributeBuilder.build(new String("CHARVALUE"),rs.getString(15));

                
                cob.addAttribute(fname);
                cob.addAttribute(lname);
                cob.addAttribute(uid);
                cob.addAttribute(name);
                cob.addAttribute(email);
                //cob.addAttribute(startdate);
                //cob.addAttribute(enddate);
                cob.addAttribute(status);
                cob.addAttribute(org);
                cob.addAttribute(city);
                //cob.addAttribute(longval);
                //cob.addAttribute(floatval);
                //cob.addAttribute(charval);
                //cob.addAttribute(emp);


                roleStmt = conn.prepareCall("{call GET_GENERICROLE(?,?)}");
                roleStmt.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.CURSOR);
            roleStmt.setString(2, rs.getString(1));
            roleStmt.execute();
                roleResultSet = roleStmt.getObject(1);
                java.util.List<EmbeddedObject> eoList = new ArrayList<EmbeddedObject>();
                while (roleResultSet.next()) {

                        Attribute roleId= AttributeBuilder.build(new String("ROLEID"),roleResultSet.getString(1));
                        Attribute roleName= AttributeBuilder.build(new String("ROLENAME"),roleResultSet.getString(2));

                //      dbDate = roleResultSet.getDate(3);
                //Attribute startdater = AttributeBuilder.build(new String("STARTDATE"),dbDate.getTime());
                
                        EmbeddedObjectBuilder roleEA = new EmbeddedObjectBuilder();
                        roleEA.addAttribute(roleId);
                        roleEA.addAttribute(roleName);
                        //roleEA.addAttribute(startdater);
                        roleEA.setObjectClass(new ObjectClass("GENERIC_ROLE"));
                        eoList.add(roleEA.build());

                }  
                roleResultSet.close();
                EmbeddedObject[] roleEm = eoList.toArray(new EmbeddedObject[eoList.size()]);
        cob.addAttribute(AttributeBuilder.build("GENERIC_ROLE", (Object[]) roleEm));
                
                groupStmt = conn.prepareCall("{call GET_GENERICGROUP(?,?)}");
                groupStmt.registerOutParameter(1, oracle.jdbc.driver.OracleTypes.CURSOR);
            groupStmt.setString(2, rs.getString(1));
            groupStmt.execute();
                groupResultSet = groupStmt.getObject(1);
                java.util.List<EmbeddedObject> geoList = new ArrayList<EmbeddedObject>();
                while (groupResultSet.next()) {
                        Attribute groupName= AttributeBuilder.build(new String("GROUPNAME"),groupResultSet.getString(2));
                        
                        //dbDate = groupResultSet.getDate(3);
                //Attribute startdateg = AttributeBuilder.build(new String("STARTDATE"),dbDate.getTime());
                        Attribute groupId= AttributeBuilder.build(new String("GROUPID"),groupResultSet.getString(1));

                        EmbeddedObjectBuilder groupEA = new EmbeddedObjectBuilder();
                        groupEA.addAttribute(groupName);
                        //groupEA.addAttribute(startdateg);
                        groupEA.addAttribute(groupId);

                        groupEA.setObjectClass(new ObjectClass("GENERIC_GROUP"));

                        geoList.add(groupEA.build());
                }  
                groupStmt.close();
                EmbeddedObject[] groupEm = geoList.toArray(new EmbeddedObject[geoList.size()]);
        cob.addAttribute(AttributeBuilder.build("GENERIC_GROUP", (Object[]) groupEm));


                Attribute timestamp= AttributeBuilder.build(new java.lang.String("LAST_UPDATE"),rs.getString(13));

        System.out.println(timestamp)
                token = AttributeUtil.getSingleValue(timestamp);
        System.out.println("token is"+token)
                SyncToken syncToken  = new SyncToken(token);

                SyncDeltaBuilder bld = new SyncDeltaBuilder();

                bld.setObject(cob.build());
                bld.setToken(syncToken);
                bld.setDeltaType(SyncDeltaType.CREATE_OR_UPDATE);
        println bld.build()
                handler.handle(bld.build());
        }
} 
finally {
        if( null != rs)
                rs.close();
        if( null != st)
                st.close();
}
"