20 Configuring Synchronization with a Connected Directory
You can synchronize the Oracle back-end directory with a connected directory.
Topics:
Note:
This chapter assumes that you are familiar with Connected Directory Integration Concepts and Considerations.
See Also:
The following chapters for step-by-step instructions about configuring integration between the Oracle back-end directory and the following connected directories:
20.1 Verifying Synchronization Requirements
You must meet the prerequisites described in this section, before you synchronize the Oracle back-end directory with a connected directory.
To prepare for synchronization between the Oracle back-end directory and a connected directory, do the following:
20.2 Creating Import and Export Synchronization Profiles Using expressSyncSetup
Use the expressSyncSetup
command to create import and export synchronization profiles for express synchronization.
Topics:
20.2.1 Understanding the expressSyncSetup Command
The expressSyncSetup
command allows you to create two synchronization profiles, one for import and one for export, using predefined assumptions.
If the Oracle Directory Integration Platform is already running, then after enabling the profile, you can immediately begin synchronizing users and groups between the containers in which users and groups are stored in the connected directory and the container in the Oracle back-end directory.
Note:
While customizing the synchronization profiles for your environment, you may need to add test users and groups to facilitate your deployment effort. Be sure to remove any test users and groups when you are finished customizing and testing your synchronization profiles.
To simplify the configuration, the expressSyncSetup
command assumes the following:
-
Entries for users of the default realm in Oracle Internet Directory are located in the container
cn=users,
default_realm_DN
, whereas users of the default realm in Oracle Unified Directory and Oracle Directory Server Enterprise Edition are located in the containercn=users,
default_metadata_suffix
. -
Entries for groups of the default realm are located in the container
cn=groups,
default_realm_DN
for Oracle Internet Directory, and in the container default_metadata_suffix for Oracle Unified Directory and Oracle Directory Server Enterprise Edition. -
The Oracle Directory Integration Platform master mapping rules files created during installation are located in $ORACLE_HOME
/ldap/odi/conf
. -
Master domain mapping rules are located in the $ORACLE_HOME
/ldap/odi/conf/
directory. -
The logon credential is that of an Oracle Directory Integration Platform administrator with sufficient privileges to configure a profile, a realm, and access controls on the Users container in the Oracle directory server. Members of the dipadmingrp have the necessary privileges.
In Oracle Internet Directory, the Oracle Directory Integration Platform Administrators group is as follows:
cn=dipadmingrp,cn=dipadmins,cn=directory integration platform,cn=products,cn=oraclecontext
In Oracle Unified Directory and Oracle Directory Server Enterprise Edition, the Oracle Directory Integration Platform Administrators group is as follows:
cn=dipadmingrp,cn=dipadmins,cn=directory integration platform,<suffix>
20.2.2 Verifying Users and Groups Synchronization in the Connected Directory
You can verify that users and groups are synchronizing between cn=users,default_naming_context
in the connected directory, and cn=users,
default_realm
in the Oracle back-end directory.
Run the expressSyncSetup
command and verify that users and groups are synchronizing:
WARNING:
In order to successfully customize your import and export synchronization profiles, do not enable SSL until you have finished with all other configuration tasks.
20.3 Configuring Advanced Integration Options
When you install Oracle Directory Integration Platform, sample import and export synchronization profiles are automatically created for each of the supported Oracle and third-party connected directories.
The import and export synchronization profiles created during the install process or with the expressSyncSetup
command are only intended as a starting point for you to use when deploying your integration of the Oracle back-end directory and a connected directory. Because the default synchronization profiles are created using predefined assumptions, you must further customize them for your environment, as described in these topics:
-
Configuring the Connected Directory Connector for Synchronization in SSL Mode
-
Enable Password Synchronization from the Oracle Back-end Directory to a Connected Directory
See Also:
The individual connected directory integration chapters for information on the sample synchronization profiles that were created during the installation process
Before customizing the sample synchronization profiles that were created during the installation process, be sure to copy them with the copy
operation of the manageSyncProfiles
command, then enable the copies with the activate
operation of the manageSyncProfiles
command.
20.3.1 Configuring the Realm
Oracle Directory Integration Platform provides you the option to configure the realm.
Note:
If your Oracle back-end directory is Oracle Unified Directory or Oracle Directory Server Enterprise Edition, the default container in those directories is the metadata suffix. Consequently, you may need to add cn=users,
<metadata_suffix> and cn=groups,
<metadata_suffix> entries and update the domain mapping rules as needed.
To configure the realm, do the following:
20.3.2 Customizing Access Control Lists
This section discusses how to customize ACLs for import profiles, export profiles, and for other Oracle components. It contains these topics:
20.3.2.1 Customizing ACLs for Import Profiles
The import profile uses the identity used by the Oracle Directory Integration Platform to access the Oracle back-end directory. ACLs must enable the import profile to add, modify, and delete objects in either the users and groups containers or the subtree where entries are accessed. By default, import profiles are part of the DIP Administrator group (cn=dipadmingrp,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext
) and of the import profile group (cn=odipigroup,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext
). Those groups have appropriate privileges on cn=oraclecontext suffix but they need to be given appropriate privileges to perform the required actions for an import profile.This group has privileges to perform all operations on any entry under the DN of the default realm.
Customizing an ACL for Oracle Unified Directory or Oracle Directory Server Enterprise Edition Back-end Directories
If your Oracle back-end directory is either Oracle Unified Directory or Oracle Directory Server Enterprise Edition, the import profile can add, modify, and delete users and groups under the DN of the metadata suffix. For a non-metadata suffix, the ACL has to be set as follows so that the containers can import the users and groups from the other source:
dn: <Container DN> changeType: modify add: aci aci: (target="ldap:///<Container DN>")(version 3.0; acl "Entry-level DIP permissions"; allow (all,proxy) groupdn="ldap:///cn=dipadmingrp,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext"; allow (all,proxy) groupdn="ldap:///cn=odipigroup,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext"; ) - add: aci aci: (targetattr="*")(version 3.0; acl "Attribute-level DIP permissions"; allow (all,proxy) groupdn="ldap:///cn=dipadmingrp,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext"; allow (all,proxy) groupdn="ldap:///cn=odipigroup,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext";)
Customizing an LDIF ACL for Oracle Unified Directory or Oracle Directory Server Enterprise Edition Back-end Directories
Refer to the ACL example given above. As needed, replace <Container DN>
with the DN under which the operations are to be performed.
You can upload an LDIF file using the following ldapmodify
command:
$ORACLE_HOME/bin/ldapmodify -h <backend-host> -p <backend-port> -D <binddn> -f <ldif-file>
After executing the command, you will be prompted for the password for privileged directory user.
Customizing an ACL for an Oracle Internet Directory Back-end Directory
If your Oracle back-end directory is Oracle Internet Directory, you should not need to customize the ACLs for import synchronization with the default realm that is installed with Oracle Internet Directory Release 14c (14.1.2.1.0). If you are upgrading from an earlier version of Oracle Internet Directory, or if the synchronization is with a nondefault Oracle Internet Directory realm, then be sure that the necessary privileges in the proper subtree or containers are granted to the import profiles handling the synchronization.
See Also:
The chapter about access controls in Oracle Fusion Middleware Administrator's Guide for Oracle Internet Directory
For an ACL template in LDIF format, see the file $ORACLE_HOME/ldap/schema/oid/oidRealmAdminACL.sbs
. If your Oracle back-end directory is Oracle Internet Directory and you have not changed the ACLs on the default realm, then this template file can be applied directly after instantiating the substitution variables, replacing %s_SubscriberDN%
with the default realm DN in Oracle Internet Directory, and replacing %s_OracleContextDN%
with cn=OracleContext
,default_realm_DN
respectively.
For example, if realmacl.ldif
is the instantiated file, then you can upload it by using the following ldapmodify
command:
$ORACLE_HOME/bin/ldapmodify -h <backend-host> -p <backend-port> -D <binddn> -f <ldif-file>
After executing the command, you will be prompted for the password for privileged directory user.
20.3.2.2 Customizing ACLs for Export Profiles
To enable the Oracle Directory Integration Platform to access a connected directory, you must create an identity in the connected directory. This identity is configured in each export profile.
To Customize the ACL to Support the Synchronization of User Records Located Outside of the Default Realm
If your Oracle back-end directory is Oracle Internet Directory and you need to synchronize user records located outside of the Oracle Internet Directory default realm, modify the ACL using an LDIF file as follows.
Note:
This ACL change is required to export OID user passwords that are outside of the default realm to connected directories using DIP sync.
20.3.3 Customizing Mapping Rules
Mapping rules, an important part of the synchronization profile, determine the directory information to be synchronized and how it is to be transformed when synchronized. You can change mapping rules at run time to meet your requirements.
Each sample synchronization profile includes default mapping rules. These rules contain a minimal set of default user and group attributes configured for out-of-the-box synchronization.
Note:
When a synchronization is underway, it relies on the mapping rules configured prior to any changes in the directory. To ensure consistent mapping, you may need to remove an already synchronized entry or perform a full synchronization.
Mapping rules govern the way data is transformed when a source directory and a destination directory are synchronized. Customize the default mapping rules found in the sample profiles when you need to do the following:
-
Change distinguished name mappings. The distinguished name mappings establish how the connected directory DIT maps to the Oracle back-end directory DIT.
-
Change the attributes that need to be synchronized.
-
Change the transformations (mapping rules) that occur during the synchronization.
You can perform any mapping if the resulting data in the destination directory conforms to the schema in that directory.
See Also:
-
The section "Configuring Mapping Rules" for a full discussion of mapping rules
-
The section "Supported Attribute Mapping Rules and Examples" for examples of how attribute values are transformed when synchronized from one directory to another
-
The file $ORACLE_HOME
/ldap/odi/conf/activeimp.map.master
for an example of import mapping rules
Once you have established a working synchronization between the Oracle back-end directory and a connected directory, you can customize the attribute mapping rules for your synchronization profiles to meet the needs of your deployment.
To customize the attribute mapping rules for your synchronization profiles:
20.3.4 Configuring the Connected Directory Connector for Synchronization in SSL Mode
By default, SSL is not enabled for the import and export synchronization profiles created with the expressSyncSetup
command. Whether or not you synchronize in the SSL mode depends on your deployment requirements.
For example, synchronizing public data does not require SSL, but synchronizing sensitive information such as passwords does. To synchronize password changes between the Oracle back-end directory and a connected directory, you must use SSL server authentication mode.
Note:
Be sure that you can successfully synchronize users in non-SSL mode before attempting to configure your synchronization profiles for SSL.
Securing the channel requires:
-
Enabling SSL between the Oracle back-end directory and the Oracle Directory Integration Platform
-
Enabling SSL between the Oracle Directory Integration Platform and the connected directory
Although you can enable SSL either between the Oracle back-end directory and the Oracle Directory Integration Platform, or between that server and the connected directory, Oracle recommends that you completely secure the channel before you synchronize sensitive information. In certain cases, such as password synchronization, synchronization can occur only over SSL.
Configuring SSL requires the following:
-
Running the Oracle directory server in SSL mode as described in the chapter on Secure Sockets Layer (SSL) in Oracle Fusion Middleware Administrator's Guide for Oracle Internet Directory.
-
Running the Oracle Directory Integration Platform in the SSL mode as described in Security Features in Oracle Directory Integration Platform. The SSL mode for Directory Integration Platform must be the same mode used when the the Oracle back-end directory server started. SSL mode 1 is no authentication and SSL mode 2 is server authentication.
Note:
-
If the Oracle back-end directory is Oracle Internet Directory, then Oracle Directory Integration Platform supports both No Authentication SSL mode (SSL mode 1) and SSL Server Authentication (SSL mode 2). If Oracle Unified Directory or Oracle Directory Server Enterprise Edition is your Oracle back-end directory, then SSL Server Authentication (SSL mode 2) is the only SSL option.
-
Oracle does not recommend using No Authentication (SSL Mode 1).
-
-
Running the connected directory server in SSL mode. Communication with a connected directory over SSL requires SSL server authentication. This requires that both the Oracle back-end directory and the Oracle Directory Integration Platform be run in SSL server authentication mode.
Perform the following steps to configure communication with a connected directory in SSL mode:
-
Generate a certificate for the connected directory. Only the trust point certificate from the server is required. Put the certificate in the connected directory's certificate store.
-
Export the trusted Certificate Authority (CA) certificates to Base 64 encoded format.
-
Import the trusted CA certificates to the Java KeyStore (JKS) using the keytool command. If Oracle Directory Integration Platform is already using an existing JKS, identify the location of it using the
-keystore
PATH_TO_JKS
option. If Oracle Directory Integration Platform does not already have a JKS to use, keytool will create one at the location identified by the-keystore
PATH_TO_JKS
option.For example:
keytool –importcert –trustcacerts –alias mycert –file PATH_TO_JKS \ -keystore PATH_TO_JKS
If this is the first time you are using the JKS identified by the
-keystore
PATH_TO_JKS
option, you must provide its password and also perform the following steps 3.a and 3.b:-
Update the Directory Integration Platform configuration with the location and password used in step 3 by using the
manageDIPServerConfig
command. For example:manageDIPServerConfig set -h HOST –p PORT -D WLS_USER \ -attribute keystorelocation -value PATH_TO_JKS
-
Update the credential in the Credential Store Framework (CSF) using the following WLST command and replacing the PASSWORD variable with the password used when the keystore was created:
createCred(map="dip", key="jksKey", user="jksUser", password="PASSWORD",desc="jks password")
-
-
Modify the connected directory connection information, including the host name, profile, and
connectedDirectoryURL
attribute, using the modify operation of the manageSyncProfiles command.manageSyncProfiles update -profile profile_name -file myMapFile
When you configure the
connectedDirectoryURL
attribute, use the following format:host:port:sslmode
Supported values for
sslmode
are as follows:Table 20-1 Supported Values for sslmode in connectedDirectoryURL Attribute
Supported sslmode Value Description 0
No SSL mode. Supported for all directory types.
1
No Authentication mode. No certificate. Supported only for Oracle Internet Directory.
Note:
Oracle does not recommend using No Authentication (SSL Mode 1).2
Server-Only Authentication mode. Requires certificate. Supported for all directory types.
-
If you used a new JKS in step 3, you must restart the Oracle Directory Integration Platform in SSL mode. If you used an existing JKS in step 3, go to step 6 now.
-
Add a test user and verify that it synchronizes successfully. If the test user does not synchronize successfully, then troubleshoot your SSL configuration.
Note:
-
The Oracle Directory Integration Platform does not support SSL in client/server authentication mode.
See Managing the SSL Certificates of Back-End Directories and Connected Directories.
-
Oracle Directory Integration Platform 14c supports Transport Layer Security (TLS) v1.2 protocol for communication with connected directories.
20.3.5 Enable Password Synchronization from the Oracle Back-end Directory to a Connected Directory
For more information, see Password Synchronization..
20.3.6 Configuring External Authentication Plug-ins
Oracle Internet Directory supports Java-based external authentication plug-ins. Oracle recommends that you use the Java plug-ins instead of the older, PL/SQL-based plug-ins, which only support Microsoft Active Directory and Oracle Directory Server Enterprise Edition / Sun Java System Directory Server.
The configuration tool for the plug-ins is a Java program called oidexcfg
. You use it to configure Java-based external authentication plug-ins for Microsoft Active Directory, Oracle Directory Server Enterprise Edition (Sun Java System Directory Server), Novell eDirectory, IBM Tivoli Directory Server, and OpenLDAP.
Note:
The oidexcfg
tool configures an external authentication plug-in to work only with a single domain. You must perform the steps described in "Configuring External Authentication Against Multiple Domains" to set up an external authentication plug-in to work with multiple domains.
To configure an external authentication plug-in, perform the following steps:
Note:
Do not change the default attribute names for the external authentication plug-in. For example, changing the default attribute name for orclpluginflexfield
will throw an error.
20.3.7 Configuring External Authentication Against Multiple Domains
To set up an external authentication plug-in to work with multiple external authentication domains, you must perform some manual instructions after you run the external configuration tool. Proceed as follows:
-
Configure the external authentication plug-in as described in "Configuring External Authentication Plug-ins".
-
Search for the plug-in configuration entries created by the configuration tool in step 1, and redirect the search output to a file. Use an
ldapsearch
command similar to this:ldapsearch -p 3060 -D binddn -q -s sub -L \ -b "cn=plugin,cn=subconfigsubentry" cn="oidexplg_*_ad" >> output.ldif
Note:
You will be prompted for the password.
The example shows an Microsoft Active Directory
cn
. Use the correct plug-incn
for the type of plug-in you configured, as shown in Table 20-2. You can use*
as a wildcard, as shown in the example.Note:
For multiple Microsoft Active Directory domains or server external authentication plug-ins, you must synchronize each Microsoft Active Directory server set of users into separate Oracle Internet Directory containers or trees and ensure that appropriate DN is listed in the corresponding plug-in's
orclpluginsubscriberdnlist
value.For example, default plug-ins like
cn=oidexplg_bind_ad,cn=plugin,cn=subconfigsubentry
andcn=oidexplg_compare_ad,cn=plugin,cn=subconfigsubentry
must includeorclpluginsubscriberdnlist=cn=ad1,cn=users,dc=mycompany,dc=com
.New plug-ins like
cn=oidexplg_bind_ad2,cn=plugin,cn=subconfigsubentry
andcn=oidexplg_compare_ad2,cn=plugin,cn=subconfigsubentry
must haveorclpluginsubscriberdnlist=cn=ad2,cn=users,dc=mycompany,dc=com
.You can keep the default names for the default plug-ins and provide a unique name for the new plug-ins.
Table 20-2 Distinguished Names of External Authentication Plug-ins
Plug-in Type DN Microsoft Active Directory
cn=oidexplg_compare_ad, cn=plugin,cn=subconfigsubentry
cn=oidexplg_bind_ad, cn=plugin,cn=subconfigsubentry
Oracle Directory Server Enterprise Edition (Sun Java System Directory Server)
cn=oidexplg_compare_iplanet, cn=plugin,cn=subconfigsubentry
cn=oidexplg_bind_iplanet, cn=plugin,cn=subconfigsubentry
Novell eDirectory
cn=oidexplg_compare_Novell eDirectory, cn=plugin,cn=subconfigsubentry
cn=oidexplg_bind_Novell eDirectory, cn=plugin,cn=subconfigsubentry
OpenLDAP
cn=oidexplg_compare_openldap, cn=plugin,cn=subconfigsubentry
cn=oidexplg_bind_openldap, cn=plugin,cn=subconfigsubentry
-
Examine the output file. For an Microsoft Active Directory plug-in, the output file resembles the following:
dn: cn=oidexplg_compare_ad,cn=plugin,cn=subconfigsubentry cn: oidexplg_compare_ad objectclass: orclPluginConfig objectclass: top orclpluginname: oidexplg.jar orclplugintype: operational orclpluginkind: Java orclplugintiming: when orclpluginldapoperation: ldapcompare orclpluginsecuredflexfield;walletpwd: password orclpluginsecuredflexfield;walletpwd2: password orclpluginversion: 1.0.1 orclpluginisreplace: 1 orclpluginattributelist: userpassword orclpluginentryproperties: (!(&(objectclass=orcladobject)(objectclass=orcluserv2))) orclpluginflexfield;host2: myhost.us.example.com orclpluginflexfield;port2: 636 orclpluginflexfield;isssl2: 1 orclpluginflexfield;host: myhost.us.example.com orclpluginflexfield;walletloc2: /location/wallet orclpluginflexfield;port: 389 orclpluginflexfield;walletloc: /tmp orclpluginflexfield;isssl: 0 orclpluginflexfield;isfailover: 0 orclpluginclassreloadenabled: 0 orclpluginenable: 0 orclpluginsubscriberdnlist: cn=users,dc=us,dc=oracle,dc=com dn: cn=oidexplg_bind_ad,cn=plugin,cn=subconfigsubentry cn: oidexplg_bind_ad objectclass: orclPluginConfigobjectclass: top orclpluginname: oidexplg.jar orclplugintype: operational orclpluginkind: Java orclplugintiming: when orclpluginldapoperation: ldapbind orclpluginversion: 1.0.1 orclpluginisreplace: 1 orclpluginentryproperties: (!(&(objectclass=orcladobject)(objectclass=orcluserv2))) orclpluginclassreloadenabled: 0 orclpluginflexfield;walletloc2: /location/wallet orclpluginflexfield;port: 389 orclpluginflexfield;walletloc: /tmp orclpluginflexfield;isssl: 0 orclpluginflexfield;isfailover: 0 orclpluginflexfield;host2: myhost.us.example.com orclpluginflexfield;port2: 636 orclpluginflexfield;isssl2: 1 orclpluginflexfield;host: myhost.us.example.com orclpluginenable: 0 orclpluginsecuredflexfield;walletpwd: password orclpluginsecuredflexfield;walletpwd2: password orclpluginsubscriberdnlist: cn=users,dc=us,dc=oracle,dc=com
-
Create a new LDIF file from the output file as follows:
-
Change the entry names. In the example shown in the previous step, you would change
cn=oidexplg_compare_ad,cn=plugin, cn=subconfigsubentry
tocn=oidexplg_compare_
ad1
, cn=plugin,cn=subconfigsubentry
andcn=oidexplg_bind_ad, cn=plugin,cn=subconfigsubentry
tocn=oidexplg_bind_
ad1
, cn=plugin,cn=subconfigsubentry
. -
Change the value for
orclpluginenable
. Use value1
if you want to enable it, and use value0
if you want to disable it. -
Change the values for
orclpluginflexfield;host
andorclpluginflexfield;port
for the external directory host name and port number. -
Change the value for
orclpluginflexfield;isssl
. Use value1
if you want to enable the SSL connection against the external directory, and use value0
if you want to disable. If you use value1
, you will also need to change the value oforclpluginflexfield;walletloc
andorclpluginsecuredflexfield;walletpwd
for the wallet location and password. -
Change
orclpluginflexfield;isfailover
. Use value1
if to set up the failover against a backup external directory. If you use value1
, then you must also change the value oforclpluginflexfield;host2
,orclpluginflexfield;port2
for the host name and port number. To use an SSL connection against the backup directory server, you must to change the value fororclpluginflexfield;walletloc2
andorclpluginsecuredflexfield;walletpwd2
. -
Modify
orclpluginsubscriberdnlist
for the plug-in invocation naming context. -
Modify
orclPluginRequestGroup
for the plug-in request group. If this attribute is missing in the search output, then just add the attribute and value in the LDIF file.
-
-
Add the modified plug-in configuration entries to the Oracle Internet Directory server. Use a command similar to the following:
$ORACLE_HOME/ldap/bin/ldapadd -h host -p port -D binddn -q \ -v -f input.ldif
Note:
You will be prompted for the password.
20.4 Writing Custom Synchronization Connectors
Oracle Directory Integration Platform supports custom synchronization connectors. This section provides information to help you write custom connectors.
Topics:
20.4.1 Writing Inbound Connectors
You can create write an inbound connector for custom synchronization connectors.
Perform the following steps to write an inbound connector:
-
Implement the Reader. The Reader generally extends the target system connector class and implements the DISReadInterface. The different methods of the DISReadInterface are specified in its the javadoc.
Refer to "Sample Reader for Inbound Connectors" to see an example Reader implementation.
-
Create a sample config file. The following is a typical config file:
[INTERFACEDETAILS] Reader: Complete_classname_including_packageName SkipErrorToSyncNextChange: false SearchDeltaSize: 500 UpdateSearchCount: 100
-
Create a mapfile containing a set of mapping rules.
-
Create a properties file by setting the configfile, mapfile, and filter parameters.
To test the inbound connector:
- Create a test profile using the register operation of the manageSyncProfiles command. Refer to "Managing Synchronization Profiles Using manageSyncProfiles" for more information.
- Verify your logging messages.
- Verify synchronization occurred by examining Oracle Internet Directory to see if the appropriate entries were created.
20.4.2 Writing an Outbound Connectors
You can create write an outbound connector for custom synchronization connectors.
Perform the following steps to write an outbound connector:
-
Implement the Writer. The Writer generally extends the target system connector class and implements the DISWriteInterface. The different methods of the DISWriteInterface are specified in its Javadoc.
Refer to "Sample Writer for Outbound Connectors" to see an example Reader implementation.
-
Create a sample config file. The following is a typical config file:
[INTERFACEDETAILS] Reader: Complete_classname_including_packageName SkipErrorToSyncNextChange: false SearchDeltaSize: 500 UpdateSearchCount: 100
-
Create a mapfile containing a set of mapping rules.
-
Create a properties file by setting the configfile, mapfile, and filter parameters.
To test the outbound connector:
- Create a test profile using the register operation of the manageSyncProfiles command. Refer to "Managing Synchronization Profiles Using manageSyncProfiles" for more information.
- Verify your logging messages.
- Verify synchronization occurred by examining Oracle Internet Directory to see if the appropriate entries were created.
20.5 Sample Reader for Inbound Connectors
Following example shows a sample reader for inbound connectors.
package oracle.ldap.odip.gsi; import oracle.ldap.odip.engine.AttrHandler; import oracle.ldap.odip.engine.ChangeRecord; import oracle.ldap.odip.engine.Connector; import oracle.ldap.odip.engine.ConfigReader; import oracle.ldap.odip.engine.Constants; import oracle.ldap.odip.engine.DISReadInterface; import oracle.ldap.odip.engine.DISFilterInterface; import oracle.ldap.odip.engine.ODIException; import oracle.ldap.odip.engine.Debug; import oracle.ldap.odip.map.MapRules; import oracle.ldap.odip.map.OrclFilter; import oracle.ldap.odip.util.Utils; //Imports added for ODLLogger import oracle.core.ojdl.logging.ODLLogger; import oracle.dms.context.ExecutionContext; import oracle.core.ojdl.logging.ODLLevel; import oracle.core.ojdl.logging.ODLHandler; import java.util.logging.Handler; import java.util.logging.Level; import oracle.ldap.odip.DIPLogger; public class SampleReader implements DISReadInterface { /* ** Member variables used */ protected NamingEnumeration mEnumerate; protected Attributes mAttribs; protected Attribute mAttrib; protected Attribute mAttribAllValues; protected SearchResult mResult; protected MapRules mMapRules; /* ** Vector to store the list of required attributes */ protected Vector mReqAttrList = new Vector(); /* ** List of source attributes whose changes need to be mapped */ protected Vector mSrcAttrList = new Vector(); protected String mMapFilter; protected int mAppliedChangeNum = 0; protected int mAvailableChangeNum = 700; protected DISFilterInterface mFilter; /* ** LastChangeNumber that is read */ protected String mReadChangeNum; /* ** List of attributes to be returned in changelog LDAPSearch */ protected String[] mRetAttribs; private int mErrorCode = 0; /* ** Constructor */ public SampleReader() { } /** ** Constructor with the connector */ public SampleReader( Connector conn ) { super(conn); } /** ** Get the last change key value ** * @param boolean Operation is success/failure * @return Object lastkeyvalue to be stored */ public Object getLastChangeKey(boolean val) { if ( val == false ) { int nval = Integer.parseInt(mReadChangeNum); if ( nval > 0 ) { nval--; } mReadChangeNum = String.valueOf(nval); } return (mReadChangeNum); } /** ** Initializes required values from hashtable passed from Profile ** ** @param Connector connection details with credentials ** @param Hashtable with the required parameters ** @throws ODIException Indicating connection failure */ public void initialise(Connector conn,Hashtable pHash) throws ODIException { m_logger.finest ( "Entry: SampleReaders.initialise"); setValues(conn); mMapRules = (MapRules)pHash.get(Constants.MAPRULE_STR); readCtx = connect(); pHash.put("READCONTEXT", readCtx); pHash.put(Constants.READERCHANGEKEY_STR, Constants.CHANGE_NUM); String key = (String)pHash.get(Constants.LASTAPPLIEDCHG_STR); String val = null; if ( key != null ) val = (String)pHash.get(key); if ( val != null ) mAppliedChangeNum = Integer.parseInt((String)pHash.get(key)); mReadChangeNum = (String)pHash.get(key); pHash.put(key, mReadChangeNum); mFilter = (DISFilterInterface)pHash.get(Constants.MATCHRULE_STR); mAvailableChangeNum = Integer.parseInt(initAvailableChgKey()); mSaveLastChgNum = mAppliedChangeNum; try { SearchControls pControls = new SearchControls(); pControls.setSearchScope(SearchControls.OBJECT_SCOPE); pControls.setReturningAttributes(mRetAttribs); pControls.setTimeLimit(3000000); mEnumerate = mLdapCtx.search("","objectclass=*",pControls); while ( mEnumerate.hasMoreElements() ) { mResult = (SearchResult)mEnumerate.nextElement(); mAttribs = mResult.getAttributes(); } // END INFEASIBLE ConfigReader configInfo = (ConfigReader) pHash.get(Constants.CONFINFO_STR); if (configInfo != null) { mUpdateSearchCount = configInfo.getUpdateSearchCount(); mSearchDelta = configInfo.getSearchDeltaSize(); } } catch (Exception ex) // BEGIN INFEASIBLE { throw new ODIException(ODIException.LDAP_INITIALIZATION_EXCEPTION,ex); } // END INFEASIBLE m_logger.finest ( "Exit: SampleReaders.initialise"); } /** ** Search the changelog ** @throws ODIException */ public int searchChanges() throws ODIException { int temp; int searchDelta = (int) mSearchDelta; if ( mAvailableChangeNum <= mAppliedChangeNum ) return -1; int minChgNum = mAppliedChangeNum+1; if ( mAvailableChangeNum - mAppliedChangeNum >= searchDelta) temp = mAppliedChangeNum + searchDelta; else temp = mAvailableChangeNum; String searchF = ""; if ( mFilter != null ) { searchF = mFilter.getSearchFilter(); m_logger.log(ODLLevel.NOTIFICATION,"SEARCHF", searchF ); } StringBuffer filter = new StringBuffer(300); /** * SearchChanges is called to get all changes * */ try { mEnumerate = mReadCtx.search( filter.toString()); } catch ( Exception ex ) // BEGIN INFEASIBLE { throw ( new ODIException(ODIException.LDAP_SEARCH_EXCEPTION, ex) ); } finally { m_logger.log(ODLLevel.NOTIFICATION, "SEARCH_SUCCESSFUL" ,new Integer( temp )); mAppliedChangeNum = temp; return mErrorCode; } public boolean hasMore() throws ODIException { boolean retval = false; int count =0; try { if ( mEnumerate.hasMoreElements() ) { retval = true; } else { while ( mAvailableChangeNum > mAppliedChangeNum ) { if ( count >= mUpdateSearchCount ) break; searchChanges(); count++; if (mEnumerate.hasMoreElements()) { retval = true; break; } else mReadChangeNum = String.valueOf(mAppliedChangeNum); } } } catch( Exception ex ) // BEGIN INFEASIBLE { throw (new ODIException(ODIException.LDAP_HASMORE_EXCEPTION,ex)); } // END INFEASIBLE if (retval == false) { // no more results mReadChangeNum = (new Integer(mAvailableChangeNum)).toString(); } return retval; } /** ** Read the next change from the source ** ** @return Object the header part of the changes read. */ public Object getNextChange() throws ODIException { try { if ( mEnumerate.hasMoreElements() ) { mResult = (SearchResult)mEnumerate.nextElement(); mAttribs = mResult.getAttributes(); } catch ( Exception e ) // BEGIN INFEASIBLE { throw (new ODIException (ODIException.LDAP_GETNEXT_EXCEPTION, e)); } // END INFEASIBLE return mAttribs; } /** ** Create the change record from the data read from the file. ** ** @returns ChangeRecord */ public ChangeRecord createChangeRecord(String dn) throws ODIException { // Create the changerecord based on the mAttribs which contains all the attributes. } public String initAvailableChgKey() throws ODIException { // set the available changekey value. This reads the value equivalent to the latest changelog number in the ldap world. } }
20.6 Sample Writer for Outbound Connectors
Following example shows a sample writer for Outbound Connectors.
*/ import oracle.ldap.odip.engine.AttrHandler; import oracle.ldap.odip.engine.ChangeRecord; import oracle.ldap.odip.engine.ConfigReader; import oracle.ldap.odip.engine.Connector; import oracle.ldap.odip.engine.Constants; import oracle.ldap.odip.engine.DISWriteInterface; import oracle.ldap.odip.engine.ODIException; import oracle.ldap.odip.map.MapRules; import oracle.ldap.odip.util.Utils; import oracle.core.ojdl.logging.ODLLogger; import oracle.core.ojdl.logging.ODLLevel; import oracle.core.ojdl.logging.ODLHandler; import java.util.logging.Handler; import java.util.logging.Level; import oracle.ldap.odip.DIPLogger; public class SampleWriter implements DISWriteInterface { protected Hashtable mProfile; protected int mErrorCode = 0; protected String mLastKeyValue; protected String mLastWrittenKey; protected Vector mWriteFilter = new Vector(); protected MapRules mMapRules; protected String mNamingContext = ""; private String mOrigDstDn = ""; protected boolean mHandleModAsAdd = false; /* Constructor */ public LDAPWriter() { } public LDAPWriter(Connector conn) { super(conn); } public void initialise(Connector conn, Hashtable pHash) throws ODIException { m_logger.finest("Entry: LDAPWriter.initialise"); setValues(conn); mProfile = pHash; mMapRules = (MapRules) pHash.get(Constants.MAPRULE_STR); connect(); ConfigReader configInfo = (ConfigReader) pHash.get(Constants.CONFINFO_STR); if (configInfo != null) { //mSearchDelta = configInfo.getSearchDeltaSize(); mHandleModAsAdd = configInfo.getHandleModAsAdd(); } mLastWrittenKey = (String) pHash.get(Constants.READERCHANGEKEY_STR); pHash.put("WRITECONTEXT", mLdapCtx); NamingEnumeration filter = (NamingEnumeration) pHash.get("WriteFilter"); try { while (filter.hasMoreElements()) { mWriteFilter.add((String) filter.next()); } } catch (Exception ex) { //System.out.println("Error in initializing filter"); } /* ** Get the lastapplied changekey value from the profile ** and use that string to determine the 'lastappliedchangenum' ** or lastappliedchangetime to be stored as the 'lastkeyvalue' ** ** Each of the insert/modify/delete routines, if the operation is ** successful, that lastkeyvalue is updated correspondingly. Otherwise ** it has the previous successful operation value */ m_logger.finest ( "Exit: LDAPWriter.initialise" ); } public void setChanges(ChangeRecord chgrec) { mChanges = chgrec; } public ChangeRecord getChanges() { return mChanges; } public String getLastChangeKey() { return mLastKeyValue; } public int writeChanges() throws ODIException { m_logger.finest("Entry: LDAPWriter.writeChanges"); mErrorCode = 0; m_logger.log(ODLLevel.FINE, "\n Output ChangeRecord " + mChanges.toString()); String dn = mChanges.getChangeKey(); if ( mHandleModAsAdd && (mChanges.getChangeType() == Constants.CHGTYPE_MODIFY)) { try { mLdapCtx.getAttributes( mChanges.getChangeKey() ); } catch (NameNotFoundException nnfe) { m_logger.log(ODLLevel.ERROR,"ERROR_DN_CONN_DIR"); mChanges.setChangeType(Constants.CHGTYPE_MODRADD); } catch (NamingException ne) { m_logger.log(ODLLevel.ERROR,"LDAP_WNAMING_EXCEPTION" , ne); } } m_logger.log(ODLLevel.FINE, "Changetype is " + mChanges.getChangeType()); mChanges.setChangeKey(ndn); if (dn.length() > 1) { //testnew(dn); switch (mChanges.getChangeType()) { case Constants.CHGTYPE_ADD: if (mChanges.size() > 0) { insert(); } break; case Constants.CHGTYPE_MODIFY: // non-changelog-based changes if (mChanges.size() > 0) { modify(); } else { mErrorCode = -1; } break; case Constants.CHGTYPE_DELETE: delete(); break; case Constants.CHGTYPE_MODRADD: // non-changelog-based changes if (mChanges.size() > 0) { modifyRadd(); } break; case Constants.CHGTYPE_MODRDN: modRDNchangelog(dn); break; case Constants.CHGTYPE_MODDN: m_logger.log(ODLLevel.FINE, "Processing moddn"); modDNchangelog(dn); break; default: //INFEASIBLE break; } } else // BEGIN INFEASIBLE { m_logger.log(ODLLevel.ERROR, "ENTRY_NOT_EXISTS_DELETE"); m_logger.log(ODLLevel.FINE, "Synchrozing a deletion, entry to delete is not found. Ignore."); mErrorCode = 99; return mErrorCode; } // END INFEASIBLE Object chgInfo = mChanges.getChangeInfo(); try { if (chgInfo instanceof Attributes) { Attributes attrs = (Attributes) chgInfo; mLastKeyValue = (String) ((Attribute) attrs.get(mLastWrittenKey)).get(); } } catch (Exception ex) { //System.out.println("Caught the exception here " + mErrorCode); if (mErrorCode != 0) { m_logger.log(ODLLevel.ERROR, "EXCEPTION_FOR_DN", new Object [] { dn, new Integer ( mErrorCode ) , ex.toString()}); } } mChanges.setChangeKey(mOrigDstDn); return mErrorCode; } public void insert() throws ODIException { m_logger.finest("Entry: LDAPWriter.insert"); String dn = mChanges.getChangeKey(); Enumeration attrdtls = mChanges.getAll(); m_logger.log(ODLLevel.FINE, "Processing Insert Operation .."); while (attrdtls.hasMoreElements()) { AttrHandler temp = (AttrHandler) attrdtls.nextElement(); attr = attrHandlerToAttr((AttrHandler) temp); if (attr != null && temp.getAttrChgType() != Constants.ATTRCHGTYPE_DELETE) { attrs.put(attr); } } createEntry(dn, attrs); m_logger.finest("Exit: LDAPWriter.insert"); } public void modify() throws ODIException { m_logger.finest("Entry: LDAPWriter.modify"); String attrname = mChanges.getChangeKey(); m_logger.log(ODLLevel.FINE, "Processing Modify Operation .."); int pos = attrname.indexOf('='); String naming = null; if (pos > 0) { naming = attrname.substring(0, pos).trim(); } } /** * Delete the entry */ public void delete() { m_logger.finest("Entry: LDAPWriter.delete"); try { m_logger.log(ODLLevel.FINE, "Processing Delete Operation .."); } /** ** Handle the ModRDN operation ** ** @throws ODIException */ protected void modDNchangelog(String newDn) throws ODIException { String newDN = null; m_logger.log(ODLLevel.FINE, "Processing change log based ModRDN operation .." + " DN passed in: " + newDn); String dn = mChanges.getChangeKey(); } /** ** Handle the ModRDN operation ** ** @throws ODIException */ protected void modRDNchangelog(String newDn) throws ODIException { } protected void performModDN(String oldDN, String newDN) throws ODIException { } /* ** First check whether the 'dn' already exists. ** If exists, ** do a modify. ** else ** construct objectclasses and do a add */ // public void modifyRadd(boolean rdn) throws ODIException public void modifyRadd() throws ODIException { m_logger.finest("Entry: LDAPWriter.modifyRadd"); } /** ** Compare the value with the old value, and replace it, if the new value ** is different from the old value */ public void checkNReplace(String dn, Attributes attrs) throws ODIException { } //BEGIN INFEASIBLE public int getErrorCode() { return mErrorCode; } public int getChangeType() { return mChanges.getChangeType(); } public String getEventType() { return ""; } //END INFEASIBLE }
20.7 expressSyncSetup command
The expressSyncSetup
command located in the ORACLE_HOME/bin
directory allows you create import and export synchronization profiles for express synchronization.
Note:
-
Best security practice is to provide a password only in response to a prompt from the command.
-
You must set the
WLS_HOME
andORACLE_HOME
environment variables before executing any of the Oracle Directory Integration Platform commands. -
The Oracle WebLogic Managed Server where Oracle Directory Integration Platform is deployed must be configured for SSL to execute this command in SSL mode. See Configuring SSL in Oracle Fusion Middleware Securing Oracle WebLogic Server for more information.
-
Oracle Directory Integration Platform 14c supports Transport Layer Security (TLS) v1.2 protocol for communication with connected directories. See Transport Layer Security Protocol and Cipher Suites.
Syntax for expressSyncSetup
expressSyncSetup -h HOST -p PORT -D wlsuser -pf PROFILE -conDirType CONNECTED_DIRECTORY_TYPE -conDirURL CONNECTED_DIRECTORY_URL -conDirBindDN CONNECTED_DIRECTORY_BIND_DN -conDircontainer SYNC_CONTAINER [-ssl -keystorePath PATH_TO_KEYSTORE -keystoreType TYPE] [-enableProfiles {true | false}] [-help]
Arguments for expressSyncSetup Command
Table 20-3 dipStatus utility Arguments
Argument | Description |
---|---|
-h | -host |
Oracle WebLogic Server where Oracle Directory Integration Platform is deployed. |
-p | -port |
Listening port of the Oracle WebLogic Managed Server where Oracle Directory Integration Platform is deployed. |
-D | -wlsuser |
Oracle WebLogic Server login ID. Note: You will be prompted for the Oracle WebLogic Server login password. You cannot provide the password as a command-line argument. Best security practice is to provide a password only in response to a prompt from the command. If you must execute |
-pf | -profile |
Profile name. Specify the name of the profile in ASCII characters only, as non-ASCII characters are not supported in the profile name. |
-conDirType |
Connected directory type. The supported values are |
-conDirUrl |
URL where the connected directory is running. The format is host:port. |
-conDirBindDN |
Connected directory server bind DN. For example:
Note: You will be prompted for the connected directory bind DN password. You cannot provide the password as a command-line argument. Best security practice is to provide a password only in response to a prompt from the command. If you must execute |
-conDirContainer |
The synchronization container. For example:
|
-ssl |
Executes the command in SSL mode. Note: The Oracle WebLogic Managed Server where Oracle Directory Integration Platform is deployed must be configured for SSL to execute this command in SSL mode. For more information, see "Configuring SSL" in Oracle Fusion Middleware Securing Oracle WebLogic Server. |
-enableProfiles |
Specify |
-keystorePath |
The full path to the keystore. |
-keystoreType |
The type of the keystore identified by |
-help |
Provides usage help for the command. |
-search-size-limit |
Specify |
Tasks and Examples for expressSyncSetup
expressSyncSetup -h myhost.mycompany.com -p 7005 -D login_ID -pf myProfile \
-conDirType ACTIVEDIRECTORY -conDirUrl server.mycompany.com:5432 \
-conDirBindDN administrator@idm2003.net -conDirContainer ou=sales,dc=us,dc=com \
-enableProfiles false \
expressSyncSetup -help