Developing a Flat File Connector

17-4 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager Example 17–2 Implementation of PoolableConnector package org.identityconnectors.flatfile; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.identityconnectors.flatfile.io.FlatFileIOFactory; import org.identityconnectors.flatfile.io.FlatFileMetadata; import org.identityconnectors.flatfile.io.FlatFileParser; import org.identityconnectors.flatfile.io.FlatFileWriter; import org.identityconnectors.framework.api.operations.GetApiOp; import org.identityconnectors.framework.common.exceptions.AlreadyExistsException; import org.identityconnectors.framework.common.exceptions.ConnectorException; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeInfo; import org.identityconnectors.framework.common.objects.AttributeInfoBuilder; import org.identityconnectors.framework.common.objects.ConnectorObject; import org.identityconnectors.framework.common.objects.ConnectorObjectBuilder; import org.identityconnectors.framework.common.objects.ObjectClass; import org.identityconnectors.framework.common.objects.OperationOptions; import org.identityconnectors.framework.common.objects.ResultsHandler; import org.identityconnectors.framework.common.objects.Schema; import org.identityconnectors.framework.common.objects.SchemaBuilder; import org.identityconnectors.framework.common.objects.Uid; import org.identityconnectors.framework.common.objects.filter.AbstractFilterTranslator; import org.identityconnectors.framework.common.objects.filter.FilterTranslator; import org.identityconnectors.framework.spi.Configuration; import org.identityconnectors.framework.spi.ConnectorClass; import org.identityconnectors.framework.spi.PoolableConnector; import org.identityconnectors.framework.spi.operations.CreateOp; import org.identityconnectors.framework.spi.operations.DeleteOp; import org.identityconnectors.framework.spi.operations.SchemaOp; import org.identityconnectors.framework.spi.operations.SearchOp; import org.identityconnectors.framework.spi.operations.UpdateOp; The main connector class ConnectorClassconfigurationClass = FlatFileConfiguration.class, displayNameKey = FlatFile public class FlatFileConnector implements SchemaOp, CreateOp, DeleteOp, UpdateOp, SearchOpMapString, String, GetApiOp, PoolableConnector { private FlatFileConfiguration flatFileConfig; private FlatFileMetadata flatFileMetadata; private FlatFileParser flatFileParser; private FlatFileWriter flatFileWriter; private boolean alive = false; Override public Configuration getConfiguration { return this.flatFileConfig; } Override public void initConfiguration config { Developing Identity Connectors 17-5 this.flatFileConfig = FlatFileConfiguration config; FlatFileIOFactory flatFileIOFactory = FlatFileIOFactory.getInstanceflatFileConfig; this.flatFileMetadata = flatFileIOFactory.getMetadataInstance; this.flatFileParser = flatFileIOFactory.getFileParserInstance; this.flatFileWriter = flatFileIOFactory.getFileWriterInstance; this.alive = true; System.out.printlninit called: Initialization done; } Override public void dispose { this.alive = false; } Override public Schema schema { SchemaBuilder flatFileSchemaBldr = new SchemaBuilderthis.getClass; SetAttributeInfo attrInfos = new HashSetAttributeInfo; for String fieldName : flatFileMetadata.getOrderedTextFieldNames { AttributeInfoBuilder attrBuilder = new AttributeInfoBuilder; attrBuilder.setNamefieldName; attrBuilder.setCreateabletrue; attrBuilder.setUpdateabletrue; attrInfos.addattrBuilder.build; } Supported class and attributes flatFileSchemaBldr.defineObjectClass ObjectClass.ACCOUNT.getDisplayNameKey,attrInfos; System.out.printlnschema called: Built the schema properly; return flatFileSchemaBldr.build; } Override public Uid createObjectClass arg0, SetAttribute attrs, OperationOptions ops { System.out.printlnCreating user account + attrs; assertUserObjectClassarg0; try { FlatFileUserAccount accountRecord = new FlatFileUserAccountattrs; Assert uid is there assertUidPresenceaccountRecord; Create the user this.flatFileWriter.addAccountaccountRecord; Return uid String uniqueAttrField = this.flatFileConfig .getUniqueAttributeName; String uniqueAttrVal = accountRecord .getAttributeValueuniqueAttrField; System.out.printlnUser + uniqueAttrVal + created; return new UiduniqueAttrVal; } catch Exception ex { If account exists 17-6 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager if ex.getMessage.containsexists throw new AlreadyExistsExceptionex; For all other causes System.out.printlnError in create + ex.getMessage; throw ConnectorException.wrapex; } } Override public void deleteObjectClass arg0, Uid arg1, OperationOptions arg2 { final String uidVal = arg1.getUidValue; this.flatFileWriter.deleteAccountuidVal; System.out.printlnAccount + uidVal + deleted; } Override public Uid updateObjectClass arg0, Uid arg1, SetAttribute arg2, OperationOptions arg3 { String accountIdentifier = arg1.getUidValue; Fetch the account FlatFileUserAccount accountToBeUpdated = this.flatFileParser .getAccountaccountIdentifier; Update accountToBeUpdated.updateAttributesarg2; this.flatFileWriter .modifyAccountaccountIdentifier, accountToBeUpdated; System.out.printlnAccount + accountIdentifier + updated; Return new uid String newAccountIdentifier = accountToBeUpdated .getAttributeValuethis.flatFileConfig.getUniqueAttributeName; return new UidnewAccountIdentifier; } Override public FilterTranslatorMapString, String createFilterTranslator ObjectClass arg0, OperationOptions arg1 { TODO: Create a fine grained filter translator Return a dummy object as its not applicable here. All processing happens in the execute query return new AbstractFilterTranslatorMapString, String { }; } Override public ConnectorObject getObjectObjectClass arg0, Uid uid, OperationOptions arg2 { Return matching record String accountIdentifier = uid.getUidValue; FlatFileUserAccount userAcc = this.flatFileParser .getAccountaccountIdentifier; ConnectorObject userAccConnObject = convertToConnectorObjectuserAcc; return userAccConnObject; } non-Javadoc Developing Identity Connectors 17-7 This is the search implementation. The Map passed as the query here, will map to all the records with matching attributes. The record will be filtered if any of the matching attributes are not found see org.identityconnectors.framework.spi.operations.SearchOpexecuteQuery org.identityconnectors.framework.common.objects.ObjectClass, java.lang.Object, org.identityconnectors.framework.common.objects.ResultsHandler, org.identityconnectors.framework.common.objects.OperationOptions Override public void executeQueryObjectClass objectClass, MapString, String matchSet, ResultsHandler resultHandler, OperationOptions ops { System.out.printlnInside executeQuery; Iterate over the records and handle individually IteratorFlatFileUserAccount userAccountIterator = this.flatFileParser .getAccountIteratormatchSet; while userAccountIterator.hasNext { FlatFileUserAccount userAcc = userAccountIterator.next; ConnectorObject userAccObject = convertToConnectorObjectuserAcc; if resultHandler.handleuserAccObject { System.out.printlnNot able to handle + userAcc; break; } } } private void assertUserObjectClassObjectClass arg0 { if arg0.equalsObjectClass.ACCOUNT throw new UnsupportedOperationException Only user account operations supported.; } private void assertUidPresenceFlatFileUserAccount accountRecord { String uniqueAttrField = this.flatFileConfig.getUniqueAttributeName; String uniqueAttrVal = accountRecord.getAttributeValueuniqueAttrField; if uniqueAttrVal == null { throw new IllegalArgumentExceptionUnique attribute not passed; } } private ConnectorObject convertToConnectorObjectFlatFileUserAccount userAcc { ConnectorObjectBuilder userObjBuilder = new ConnectorObjectBuilder; Add attributes ListString attributeNames = this.flatFileMetadata .getOrderedTextFieldNames; for String attributeName : attributeNames { String attributeVal = userAcc.getAttributeValueattributeName; userObjBuilder.addAttributeattributeName, attributeVal; 17-8 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager if attributeName.equalsthis.flatFileConfig .getUniqueAttributeName { userObjBuilder.setUidattributeVal; userObjBuilder.setNameattributeVal; } } return userObjBuilder.build; } Override public void checkAlive { if alive throw new RuntimeExceptionConnection not alive; } } 3. This connector supports only the ContainsAllValuesFilter operation. Implement the ContainsAllValuesFilter operation Example 17–3 illustrates the sample implementation of org.identityconnectors.framework.common.objects.filter.AbstractFilterTranslator T that defines the filter operation. Example 17–3 Implementation of AbstractFilterTranslatorT package org.identityconnectors.flatfile.filteroperations; import java.util.HashMap; import java.util.Map; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.filter.AbstractFilterTranslator; import org.identityconnectors.framework.common.objects.filter.ContainsAllValuesFilter; public class ContainsAllValuesImpl extends AbstractFilterTranslatorMapString, String{ Override protected MapString, String createContainsAllValuesExpression ContainsAllValuesFilter filter, boolean not { MapString, String containsAllMap = new HashMapString, String; Attribute attr = filter.getAttribute; containsAllMap.putattr.getName, attr.getValue.get0.toString; return containsAllMap; } } 4. Create the connector bundle JAR. The MANIFEST.MF file must contain the following entries: ■ ConnectorBundle-FrameworkVersion ■ ConnectorBundle-Name ■ ConnectorBundle-Version Example 17–4 shows the contents of the MANIFEST.MF file: Developing Identity Connectors 17-9 Example 17–4 The MANIFEST.MF File Manifest-Version: 1.0 Ant-Version: Apache Ant 1.7.0 Created-By: 14.1-b02 Sun Microsystems Inc. ConnectorBundle-FrameworkVersion: 1.0 ConnectorBundle-Name: org.identityconnectors.flatfile ConnectorBundle-Version: 1.0 Build-Number: 609 Subversion-Revision: 4582 5. Update the connector bundle JAR as created in step 4. To do so: a. Extract the connector bundle JAR into any desired location. b. Create a lib directory in the directory in which you extracted the JAR. c. Add the dependent third-party JARs into the lib directory. d. JAR the entire directory.

17.1.1 Supporting Classes for File Input and Output Handling

This section shows the implementation of the following supporting classes for file input and output handling: ■ Example 17–5, FlatFileIOFactory ■ Example 17–6, FlatFileMetadata ■ Example 17–7, FlatFileParser ■ Example 17–8, FlatFileWriter Example 17–5 shows the implementation of the FlatFileIOFactory supporting class: Example 17–5 FlatFileIOFactory package org.identityconnectors.flatfile.io; import org.identityconnectors.flatfile.FlatFileConfiguration; public class FlatFileIOFactory { private FlatFileMetadata flatFileMetadata; private FlatFileConfiguration flatFileConfig; Provides instance of the factory param flatfileConfig Configuration bean for the flat file public static FlatFileIOFactory getInstanceFlatFileConfiguration fileConfig { return new FlatFileIOFactoryfileConfig; } Making it private to avoid public instantiation. Encouraging use of getInstance param fileConfig Note: The MANIFEST.MF file must contain the entires listed in step 4. 17-10 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager private FlatFileIOFactoryFlatFileConfiguration fileConfig { this.flatFileConfig = fileConfig; this.flatFileMetadata = new FlatFileMetadataflatFileConfig; System.out.printlnMetadata set; } Returns the metadata instance return public FlatFileMetadata getMetadataInstance { return this.flatFileMetadata; } Returns the FlatFileParser instance return public FlatFileParser getFileParserInstance { return new FlatFileParserthis.flatFileMetadata, this.flatFileConfig; } Returns the FlatFileWriter instance return public FlatFileWriter getFileWriterInstance { return new FlatFileWriterthis.flatFileMetadata, this.flatFileConfig; } } Example 17–6 shows the implementation of the FlatFileMetaData supporting class: Example 17–6 FlatFileMetadata package org.identityconnectors.flatfile.io; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import org.identityconnectors.flatfile.FlatFileConfiguration; This class contains all the metadata related information Example: Ordering of columns, Number of columns etc. author harsh public class FlatFileMetadata { private FlatFileConfiguration fileConfig; private ListString orderedTextFieldNames; Developing Identity Connectors 17-11 private String changeLogFieldName; private String uniqueAttributeFiledName; Instantiates the class with the file configuration. Making it package private to encourage instantiation from Factory class param fileConfig FlatFileMetadataFlatFileConfiguration fileConfig { Ideally you should not take connector specific configuration class in flat file resource classes. Change if this has to go to production. Probably make another configuration class for flat file with same signatures. this.fileConfig = fileConfig; initializeMetadata; validateConfigProps; } Returns the text field names in the order of their storage return public ListString getOrderedTextFieldNames { return this.orderedTextFieldNames; } Returns the number of columns public int getNumberOfFields { int numberOfTextFields = this.orderedTextFieldNames.size; return numberOfTextFields; } Specifies if number of tokens are matching with the standard length of metadata param countTokens return public boolean isDifferentFromNumberOfFieldsint countTokens { return getNumberOfFields = countTokens; } Reads the header line and sets the metadata private void initializeMetadata { Read the file. File recordsStore = this.fileConfig.getStoreFile; try { BufferedReader storeFileReader = new BufferedReadernew FileReader recordsStore.getAbsolutePath; Read the header line 17-12 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager String headerString = storeFileReader.readLine; Tokenize the headerString StringTokenizer tokenizer = new StringTokenizerheaderString, fileConfig.getTextFieldDelimeter; this.orderedTextFieldNames = new ArrayListString; while tokenizer.hasMoreTokens { String header = tokenizer.nextToken; this.orderedTextFieldNames.addheader; } System.out.printlnColumns read - + this.orderedTextFieldNames; } catch IOException e { throw new RuntimeExceptionHow can I read a corrupted file; } Store the change log and unique attribute field names this.changeLogFieldName = fileConfig.getChangeLogAttributeName; this.uniqueAttributeFiledName = fileConfig.getUniqueAttributeName; } Validate if the attribute names in config props object are present in the column names throws RuntimeException if validation fails private void validateConfigProps { Check if unique attribute col name is present if this.orderedTextFieldNames.containsthis.changeLogFieldName throw new RuntimeExceptionChange log field name + this.changeLogFieldName + not found in the store file ; Check if change col name is present if this.orderedTextFieldNames.containsthis.uniqueAttributeFiledName throw new RuntimeExceptionUnique attribute field name + this.uniqueAttributeFiledName + not found in the store file; } } Example 17–7 shows the implementation of the FlatFileParser supporting class: Example 17–7 FlatFileParser package org.identityconnectors.flatfile.io; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.identityconnectors.flatfile.FlatFileConfiguration; import org.identityconnectors.flatfile.FlatFileUserAccount; Developing Identity Connectors 17-13 import org.identityconnectors.flatfile.utils.AccountConversionHandler; public class FlatFileParser { private File recordsStore; private FlatFileConfiguration fileConfig; private FlatFileMetadata metadata; private AccountConversionHandler accountConverter; Instantiates the parser class. Making it package private to encourage instantiation from Factory class param metadata param fileConfig FlatFileParserFlatFileMetadata metadata, FlatFileConfiguration fileConfig { this.fileConfig = fileConfig; this.recordsStore = fileConfig.getStoreFile; this.accountConverter = new AccountConversionHandlermetadata, fileConfig; this.metadata = metadata; } Returns all accounts in the file return public ListFlatFileUserAccount getAllAccounts { try { BufferedReader userRecordReader = new BufferedReader new FileReaderrecordsStore.getAbsolutePath; String recordStr; Skip headers userRecordReader.readLine; Loop over records and make list of objects ListFlatFileUserAccount allAccountRecords = new ArrayListFlatFileUserAccount; while recordStr = userRecordReader.readLine = null { try { FlatFileUserAccount accountRecord = accountConverter .convertStringRecordToAccountObjrecordStr; allAccountRecords.addaccountRecord; } catch RuntimeException e { System.out.printlnInvalid entry + e.getMessage; } } userRecordReader.close; return allAccountRecords; } catch IOException e { throw new RuntimeExceptionHow can I read a corrupted file; } } Gets the account of matching account identifier 17-14 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager param accountIdentifier return public FlatFileUserAccount getAccountString accountIdentifier { I know its not right to get all account details. Dont want to focus on efficiency and scalability as this is just a sample. Iterate over all records and check for matching account MapString, String matchSet = new HashMapString, String; matchSet.putfileConfig.getUniqueAttributeName, accountIdentifier; for FlatFileUserAccount userRecord : getAllAccounts { if userRecord.hasMatchingAttributesmatchSet return userRecord; } Got nothing.. return null; } Returns all records with matching Attributes If more than attributes are passed. it will check all the attributes param matchSet Checks if all provided attributes are matched public ListFlatFileUserAccount getAccountsByMatchedAttrs MapString, String matchSet { I know its not right to get all account details. Dont want to focus on efficiency and scalability as this is just a sample. Iterate over all records and check for matching account ListFlatFileUserAccount matchingRecords = new ArrayListFlatFileUserAccount; for FlatFileUserAccount userRecord : getAllAccounts { if userRecord.hasMatchingAttributesmatchSet matchingRecords.adduserRecord; } return matchingRecords; } Returns the records that fall after the specified change number This function helps in checking the function of sync param changeNumber the change number for the last search public ListFlatFileUserAccount getUpdatedAccountsint changeNumber { I know its not right to get all account details. Dont want to focus on efficiency and scalability as this is just a sample. Iterate over all records and check for matching account ListFlatFileUserAccount matchingRecords = new Developing Identity Connectors 17-15 ArrayListFlatFileUserAccount; String changeLogAttrName = fileConfig.getChangeLogAttributeName; for FlatFileUserAccount userRecord : getAllAccounts { int recordChangeNumber = userRecord .getChangeNumberchangeLogAttrName; if recordChangeNumber = changeNumber matchingRecords.adduserRecord; } return matchingRecords; } Returns an iterator that iterates over the records. This is provided for dynamic retrieval of records param matchSet Filters the records by matching the given attributes. Use null or empty set to avoid filtering return public IteratorFlatFileUserAccount getAccountIterator MapString, String matchSet { IteratorFlatFileUserAccount recordIterator = new FlatFileLineIterator this.metadata, this.fileConfig, matchSet; return recordIterator; } Gives the next change number. Logic is max of existing change numbers + 1 return public int getNextChangeNumber { int maximumChangeNumber = 0; I know its not right to get all account details. Dont want to focus on efficiency and scalability as this is just a sample. Iterate over all records and check for matching account String changeLogAttrName = fileConfig.getChangeLogAttributeName; for FlatFileUserAccount userRecord : getAllAccounts { int changeNumber = userRecord.getChangeNumberchangeLogAttrName; if changeNumber = maximumChangeNumber { maximumChangeNumber = changeNumber + 1; } } return maximumChangeNumber; } } Example 17–8 shows the implementation of the FlatFileWriter supporting class: Example 17–8 FlatFileWriter package org.identityconnectors.flatfile.io; import java.io.BufferedReader; 17-16 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import org.identityconnectors.flatfile.FlatFileConfiguration; import org.identityconnectors.flatfile.FlatFileUserAccount; import org.identityconnectors.flatfile.utils.AccountConversionHandler; Class for searching operations on files author Harsh public class FlatFileWriter { private File recordsStore; private FlatFileParser recordParser; private FlatFileConfiguration fileConfig; private AccountConversionHandler accountConverter; Initializes the writer with the configuration Making it package private to encourage use of Factory class for global instantiation param metadata param fileConfig FlatFileWriterFlatFileMetadata metadata, FlatFileConfiguration fileConfig { this.fileConfig = fileConfig; this.recordsStore = fileConfig.getStoreFile; recordParser = new FlatFileParsermetadata, fileConfig; accountConverter = new AccountConversionHandlermetadata, fileConfig; } Appends the user record at the end of param accountRecord public void addAccountFlatFileUserAccount accountRecord { try { BufferedWriter userRecordWriter = new BufferedWriter new FileWriterthis.recordsStore.getAbsolutePath, true; Set the latest changelog number int latestChangeNumber = recordParser.getNextChangeNumber; accountRecord.setChangeNumberfileConfig .getChangeLogAttributeName, latestChangeNumber; Validate if same account id doesnt exist String accountUid = accountRecord.getAttributeValuefileConfig .getUniqueAttributeName; FlatFileUserAccount accountByAccountId = recordParser .getAccountaccountUid; if accountByAccountId = null throw new RuntimeExceptionAccount + accountUid Developing Identity Connectors 17-17 + already exists; Put the user record in formatted way String userRecordAsStr = accountConverter .convertAccountObjToStringRecordaccountRecord; userRecordWriter.write\n + userRecordAsStr; Close the output stream userRecordWriter.close; } catch IOException e { Catch exception if any throw new RuntimeExceptionHow can I write on a corrupted file; } } Removes the entry for respective account identifier param accountIdentifier public void deleteAccountString accountIdentifier { String blankRecord = ; this.modifyAccountInStoreaccountIdentifier, blankRecord; } Updates the entry with respective account identifier param accountIdentifier param updatedAccountRecord return new accountIdentifier public String modifyAccountString accountIdentifier, FlatFileUserAccount updatedAccountRecord { Frame a record string and update back to file int nextChangeNumber = recordParser.getNextChangeNumber; String changeNumberFieldName = fileConfig.getChangeLogAttributeName; updatedAccountRecord.setChangeNumberchangeNumberFieldName, nextChangeNumber; String newRecordAsStr = accountConverter .convertAccountObjToStringRecordupdatedAccountRecord; Update to the file this.modifyAccountInStoreaccountIdentifier, newRecordAsStr; Return new UID String uniqueAttrFieldName = fileConfig.getUniqueAttributeName; String newAccountIdentifier = updatedAccountRecord .getAttributeValueuniqueAttrFieldName; return newAccountIdentifier; } Returns the complete flat file as string. return private String getCompleteFlatFileAsStr { try { 17-18 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager BufferedReader userRecordReader = new BufferedReader new FileReaderrecordsStore.getAbsolutePath; String recordStr; Loop over records and make list of objects StringBuilder flatFileStr = new StringBuilder; while recordStr = userRecordReader.readLine = null { if recordStr.isEmpty flatFileStr.appendrecordStr + \n; } userRecordReader.close; return flatFileStr.toString; } catch IOException e { throw new RuntimeExceptionHow can I read a corrupted file; } } Updates the account with the new record. this can also be used for delete param accountIdentifier param updatedRecord private void modifyAccountInStoreString accountIdentifier, String updatedRecord { try { Load the complete flat file String completeFlatFile = this.getCompleteFlatFileAsStr; Construct the string to be removed and replace it with blank FlatFileUserAccount accountToBeRemoved = recordParser .getAccountaccountIdentifier; String updatableString = accountConverter .convertAccountObjToStringRecordaccountToBeRemoved; String updatedFlatFile = completeFlatFile.replaceAll updatableString, updatedRecord; Rewrite the file BufferedWriter userRecordWriter = new BufferedWriter new FileWriterthis.recordsStore.getAbsolutePath, false; userRecordWriter.writeupdatedFlatFile; debug System.out.printlnOld string + updatableString; System.out.printlnNew String + updatedRecord; System.out.printlnnew file - + updatedFlatFile; Close the output stream userRecordWriter.close; } catch IOException e { Catch exception if any throw new RuntimeExceptionHow can I write on a corrupted file; } } } Developing Identity Connectors 17-19

17.2 Uploading the Identity Connector Bundle to Oracle Identity Manager Database

The identity connector bundle must be available to ICF in Oracle Identity Manager database. Follow the list of sections in order to integrate the ICF identity connector with Oracle Identity Manager. Some of the procedures include configuration by using the Oracle Identity Manager Design Console. ■ Registering the Connector Bundle with Oracle Identity Manager ■ Creating Basic Identity Connector Metadata ■ Creating Provisioning Metadata ■ Creating Reconciliation Metadata

17.2.1 Registering the Connector Bundle with Oracle Identity Manager

The connector bundle must be available for the Connector Server local to Oracle Identity Manager. Following is the procedure to accomplish this: 1. Copy the connector bundle JAR to the machine on which Oracle Identity Manager in installed. 2. Run the following command to upload the JAR. MW_HOMEserverbinUploadJars.sh

3. Select ICFBundle as the JAR type.

4. Enter the location of the connector bundle JAR.

5. Press Enter.

17.2.2 Creating Basic Identity Connector Metadata

This metadata configuration is needed for both provisioning and reconciliation. The set of procedures in this section are completed by using the Oracle Identity Manager Design Console. ■ Creating the IT Resource Type Definition ■ Creating the Resource Object ■ Creating the Main Configuration Lookup ■ Creating Object Type Configuration Lookup

17.2.2.1 Creating the IT Resource Type Definition

An IT resource type definition is the representation of a resources connection information. The configuration parameters in the IT resource type definition should be matched with the configuration parameters of the connector bundle. The values of the parameters in the IT resource will be set in the bundle configuration. Note: In this chapter, DW_HOME represents MW_HOMEOracle_IDM1. Note: You may include parameters the bundle configuration is not using. They produce no negative effects on the bundle operations. 17-20 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager 1. Log in to the Oracle Identity Manager Design Console. 2. Click IT Resource Type Definition under Resource Management. 3. Create a new IT Resource Type Definition with the Server Type defined as Flat File. 4. Add the following parameters as illustrated in Figure 17–1 . ■ Configuration Lookup is the marker of the main configuration lookup for the resource. The name of the parameter must be Configuration Lookup. It is a good practice to add a value to Default Field Value. ■ textFieldDelimeter maps to the textFieldDelimeter parameter in the bundle configuration. The value of this parameter will be passed. ■ storeFile maps to the storeFile parameter in the bundle configuration. The value of this parameter will be passed. Figure 17–1 IT Resource Type Definition in Design Console

17.2.2.2 Creating the Resource Object

The resource object is the Oracle Identity Manager representation of a resource. The connector bundle is tied to the resource object. 1. Log in to the Oracle Identity Manager Design Console. 2. Click Resource Objects under Resource Management. 3. Create a new resource object with the name FLATFILERO. As the resource object is a target resource dont check the Trusted Source box as illustrated in Figure 17–2 . Developing Identity Connectors 17-21 Figure 17–2 Resource Objects in Design Console

17.2.2.3 Creating Lookups

Separate lookups have to be defined for different objects supported by the connector bundle. This lookup can contain provisioning and reconciliation related information for those objects. The Main Configuration Lookup is the root for object specific lookups as it contains the pointers to those lookups. The following sections contain information on how to create lookups. ■ Creating the Main Configuration Lookup ■ Creating Object Type Configuration Lookup

17.2.2.3.1 Creating the Main Configuration Lookup The Configuration Lookup as defined

in Section 17.2.2.1, Creating the IT Resource Type Definition holds connector bundle configurations that are not counted as connection information. If a configuration parameter is not found in the IT Resource Type Definition, Oracle Identity Manager will look in the Configuration Lookup. The main Configuration Lookup contains bundle properties and bundle configurations. Bundle Property parameters are mandatory as they are needed for identifying the correct bundle. Bundle configurations that are not defined as part of the IT resource type definition discussed in Section 17.2.2.1, Creating the IT Resource Type Definition can be declared here.

1. Log in to the Oracle Identity Manager Design Console.

2. Click Lookup Definition under Administration.

3. Create a new lookup and add Lookup.FF.Configuration as the value for Code.

4. Add the following Lookup Code Information as illustrated in

Figure 17–3 . ■ Add VERSION as the required Bundle Version. ■ Add org.identityconnectors.flatfile as the required Bundle Name. Note: The values for Code Key should match exactly as illustrated. The values for Decode are specific to the connector bundle. 17-22 Oracle Fusion Middleware Developers Guide for Oracle Identity Manager ■ Add org.identityconnectors.flatfile.FlatFileConnector as the required Connector Name. ■ Add AccountId as the value of uniqueAttributeName. AccountId is a unique string identifier that represents the account to be provisioned or reconciled. It is the name of the column in the flat file. AccountId is unique and is used to represent a user account detail uniquely. ■ Add ChangeNumber as the value of changeLogAttributeName. When an account is created, a number is attached to it indicating the total accounts created. This value is maintained in the variable called ChangeNumber. ■ OBJECT_TYPE_NAME Configuration Lookup is the configuration lookup for the particular object type. In this example, the object type is User as User Configuration Lookup is defined. Figure 17–3 Lookup Definition in Design Console

17.2.2.3.2 Creating Object Type Configuration Lookup Object type configuration lookup

contains the parameters specific to the particular object type. Object type is an entity over which an identity connector operates. It is mapped to ICF ObjectClass. In Section 17.2.2.3.1, Creating the Main Configuration Lookup, User Configuration Lookup has been referenced so that User is the object type, in this case mapped to ObjectClass.ACCOUNT. Roles and UserJobData are two other object types. The object type name has to match with ObjectClass name supported by the identity connector bundle. The User object type is mapped to predefined ObjectClass.ACCOUNT, the Group object type is mapped to predefined ObjectClass.GROUP. If the identity connector supports multiple objects, then this step must be repeated for each.

1. Log in to the Oracle Identity Manager Design Console.

2. Click Lookup Definition under Administration.

Note: Because these use cases cover only the basic functionality, the configuration is kept to the mandatory attribute.