The Identity Manager adapter interface provides general methods that you must customize to suit your particular environment. This section briefly describes:
Standard resource adapter-specific methods are specific to the resource you are updating to synchronize with Identity Manager.
The body of a resource adapter consists of resource-specific methods. Consequently, the resource adapter provides methods that are only generic placeholders for the specific methods that you will write.
This section describes how the methods used to implement operations are categorized. The information is organized into the following sections:
When writing a custom adapter
Call the setdisabled() method on any WSUser object that is returned by a custom method.
If the adapter implements the AsynchronousResourceAdapter class, then note that this adapter might be working with users that are partially initialized. (These users are created outside Identity Manager, but not fully populated with attributes.) The Provisioner does not automatically convert a Create operation to an Update operation if the WSUser already exists on the resource. Your resource adapter must distinguish this case.
The following table describes the methods used to create a Resource instance.
Table 9–14 Methods Used to Create a Resource Instance
The following methods are responsible for establishing connections and disconnections as an authorized user. All resource adapters must implement these methods.
ResourceAdapterBase provides methods that you can use to check the validity of an operation, such as whether the connection to the resource is working, before the adapter attempts the actual operation.
The following table describes methods you can use to verify that your adapter is communicating with the resource and that the authorized account has access.
Table 9–15 Methods Used to Check Communication
The getFeatures() method specifies which features are supported by an adapter. The features can be categorized as follows:
General features
Account features
Group features
Organizational unit features
The ResourceAdapterBase class defines a base implementation of the getFeatures() method. The Enabled in Base? column in the following tables indicates whether the feature is defined as enabled in the base implementation in ResourceAdapterBase.
Table 9–16 General Features
Feature Name |
Enabled in Base? |
Comments |
---|---|---|
ACTIONS |
No |
Indicates whether before and after actions are supported. To enable, override the supportsActions method with a true value. |
RESOURCE_PASSWORD_CHANGE |
No |
Indicates whether the resource adapter supports password changes. To enable, override the supportsResourceAccount method. |
Table 9–17 Account Features
Table 9–18 Group Features
Feature Name |
Enabled in Base? |
Comments |
---|---|---|
GROUP_CREATE,GROUP_DELETE, GROUP_UPDATE |
No |
Indicates whether groups can be created, deleted, or updated. Use the put operation to if these features are supported on the resource. |
Table 9–19 Organizational Unit Features
Feature Name |
Enabled in Base? |
Comments |
---|---|---|
ORGUNIT_CREATEORGUNIT_DELETEORGUNIT_UPDATE |
No |
Indicates whether organizational units can be created, deleted, or updated. Use the put operation to if these features are supported on the resource. |
If your custom adapter overrides the ResourceAdapterBase implementation of the getFeatures method, add code similar to the following:
public GenericObject getFeatures() { GenericObject genObj = super.getFeatures(); genObj.put(Features.ACCOUNT_RENAME, Features.ACCOUNT_RENAME); genObj.remove(Features.ACCOUNT_UPDATE, Features.ACCOUNT_UPDATE); .. other features supported by this Resource Adapter … return genObj; } |
To disable a feature by overriding a different method (such as supportsActions) add code similar to the following:
public boolean supportsActions() { return true; } |
The following tables describe the methods used to create, delete, and update accounts on Resources.
Table 9–20 Creating Accounts on the Resource
Method |
Description |
---|---|
realCreate() |
Creates the account on the resource. Receives a user object as input, and contains the account attribute information needed to create the user account (such as account name, password, and user name) |
Table 9–21 Deleting Accounts on the Resource
Method |
Description |
---|---|
realDelete() |
Deletes one or more accounts on the resource. Receives a user object or list of user objects as input. By default, this method creates a connection, calls realDelete, closes the connection for each user object in the list. |
Table 9–22 Updating Accounts on the Resource
Method |
Description |
---|---|
realUpdate() |
Updates a subset of the account attributes. By default, this method creates a connection, calls realUpdate, and closes the connection for each user object in the list. NOTE: User account attributes from the resource are merged with any new changes from Identity Manager. |
Table 9–23 Getting User Information
Method |
Description |
---|---|
getUser() |
Retrieves information from the resource about user attributes. Receives a user object as input (typically with only an account identity set), and returns a new user object with values set for any attribute defined in resource schema map. |
You can use list methods to establish processes that adapters use to retrieve user information from the resource.
Table 9–24 List Methods
Method |
Description |
---|---|
getAccountIterator() |
Used to discover or import all the users from a resource. Implements the Account Iterator interface to iterate over all users of a resource. |
listAllObjects () |
Given a resource object type (such as accountID or group), returns a list of that type from the resource. Implement this method to generate lists that are used by the resource, such as a list of resource groups or distribution lists. This method is called from the user form (not called by provisioning engine). |
Best Practice
When writing an AccountIterator interface implementation for a custom adapter, try to do the following:
Have the AccountIterator.next() method return a user that contains all attributes in the schema map when getAccountIterator() is called. The reconciler will trim the schema (in a cloned resource used for the getAccountIterator() request) to request only those attributes the reconciler needs. Generally, the reconciler needs only the accountId attribute; but there are cases when the reconciler has additional attributes in the schema. Other getAccountIterator() users, such as Load From Resource, potentially need all of the schema attributes.
Try to create a “smart” adapter that does the right thing based on what is in the schema map. If your adapter can just list the accounts and get the requested information, then the adapter should just do those tasks. Otherwise, the adapter might have to fetch an account to get the required attributes. Adapters that are not smart always get all the attributes.
Make your adapter as scalable as possible, which generally means the adapter does not list or fetch all of the accounts at once. Instead, your adapter should iterate over the accounts as the AccountIterator.next() method is called. Avoid having your adapter do much in the AccountIterator constructor.
The following example shows code for retrieving information from a resource and converting that information into information that Identity Manager can work with.
Resource Adapters: Retrieving Information on a Resource
public WSUser getUser(WSUser user) throws WavesetException { String identity = getIdentity(user); WSUser newUser = null; try { startConnection(); Map attributes = fetchUser(user); if (attributes != null) { newUser = makeWavesetUser(attributes); } } finally { stopConnection(); } return newUser; } |
Method |
Description |
---|---|
supportsAccountDisable() |
Returns true or false depending on whether the resource supports native account disable. |
realEnable() |
Implements native calls that are needed to enable the user account on the resource. |
realDisable() |
Implements native calls that are needed to disable the user account on the resource. |
You can disable an account by using the disable utilities supported by the resource or the account disable utility provided by Identity Manager.
Use native disable utilities whenever possible.
Native support for disabling an account: Certain resources provide a separate flag that, when set, prevents users from logging in. Example utilities include User Manager for Active Directory Users and Computers for Active Directory, and ConsoleOne or Netware Administrator for NDS/Netware. When an account is enabled, the user’s original password is still valid. You can determine whether native support for account disable is available on your resource by implementing the supportsAccountDisable method.
Identity Manager disable utility: If the resource does not support disabling an account, or supports disable by means of resetting the user’s password, the Identity Manager provisioning engine disables the account. You can perform the disable by setting the user account to a randomly generated, non-displayed, non-retained password. When the account is enabled, the system randomly generates a new password, which is displayed in the Identity Manager Administrative interface or emailed to the user.
Use the following general steps to enable pass-through authentication in a resource type:
Ensure that the adapter’s getFeatures() method returns ResourceAdapter.ACCOUNT_LOGIN as a supported feature.
If your custom adapter overrides the ResourceAdapterBase implementation, add the following code.
public GenericObject getFeatures() { GenericObject genObj = super.getFeatures(); genObj.put(Features.ACCOUNT_RENAME, Features.ACCOUNT_RENAME); .. other features supported by this Resource Adapter … return genObj; } |
If your custom adapter does not override the getFeatures() implementation in the ResourceAdapterBase class, it will inherit the getFeatures() implementation that is exported for ACCOUNT_LOGIN by default.
Add the <LoginConfigEntry> element to the adapter’s prototypeXML.
Implement the adapter’s authenticate() method.
The authenticate() method authenticates the user against the resource by using the authentication property name/value pairs provided in the loginInfo map. If authentication succeeds, be sure that the authenticated unique ID is returned in the WavesetResult by adding a result as follows:
result.addResult(Constants.AUTHENTICATED_IDENTITY, accountID); |
If authentication succeeded, but the user’s password was expired, then in addition to the identity added above, also add the password expired indicator to the result to be returned. This will ensure that the user will be forced to change their password on at least resource upon next login to Identity Manager.
result.addResult(Constants.RESOURCE_PASSWORD_EXPIRED, new Boolean(true)); |
If authentication fails (because the user name or password is invalid), then:
throw new WavesetException("Authentication failed for " + uid + "."); |
Active Sync-specific methods provide the mechanism for updating Identity Manager, which is the primary purpose of your Active Sync-enabled adapter adapter. These methods are based on pulling information from the authoritative resource. In addition, you use these methods to start, stop, and schedule the adapter.
The methods you are going to write in this section of the adapter are based on generic methods supplied with the skeleton adapter file. You must edit some of these methods, which are categorized by task.
The following sections describe general guidelines for creating Active Sync-enabled adapter methods:
You initialize and schedule the adapter by implementing the init() and poll() methods.
The init() method is called when the adapter manager loads the adapter. There are two methods for loading the adapter:
The manager can load the adapter at system startup if the adapter startup type is automatic.
An administrator loads the adapter by clicking Start on the Resources page if the adapter startup type is manual.
In the initialization process, the adapter can perform its own initialization. Typically, this involves initializing logging (with the ActiveSyncUtil class), and any adapter-specific initialization such as registering with a resource to receive update events.
If an exception is thrown, the adapter is shut down and unloaded.
All of the adapter’s work is performed by the poll() method. Scheduling the adapter requires setting up a poll() method to search for and retrieve changed information on the resource.
This method is the main method of the Active Sync-enabled adapter. The adapter manager calls the poll() method to poll the remote resource for changes. The call then converts the changes into IAPI calls and posts them back to a server. This method is called on its own thread and can block for as long as needed.
It should call its ActiveSyncUtil instance’s isStopRequested method and return when true. Check isStopRequested as part of the loop condition when looping through changes.
To configure defaults for polling, you can set the polling-related resource attributes in the adapter file. Setting these polling-related attributes provides administrators with a means to later use the Identity Manager interface to set the start time and date for the poll interval and the length of the interval.
Scheduling Parameters
You use the following scheduling parameters in Active Sync-enabled adapters:
RA_SCHEDULE_INTERVAL
RA_SCHEDULE_INTERVAL_COUNT
RA_SCHEDULE_START_TIME
RA_SCHEDULE_START_DATE
See Table 9–6 for a description of these parameters.
Scheduling Parameters in the prototypeXML
The scheduling parameters are present in the string constant ActiveSync. ACTIVE_SYNC_STD_RES_ATTRS_XML, along with all other general Active Sync-related resource attributes.
The following table describes the usage of scheduling parameters using some sample polling scenarios.
Table 9–26 Sample Polling Scenarios
Polling Scenario |
Parameters |
---|---|
Daily at 2 A.M. |
Interval = day, count =1, start_time=0200 |
Four times daily |
Interval=hour, count=6. |
Poll once every two weeks on Thursday at 5 P.M |
Interval = week, count=2, start date = 20020705 (a Thursday), time = 17:00. |
Most Active Sync-enabled adapters are also standard adapters, where a single Java class both extends ResourceAdapterBase (or AgentResourceAdapter) and implements the Active Sync interface.
The following example shows how to retrieve the attribute and pass the update through to the base.
public Object getAttributeValue(String name) throws WavesetException { return getResource().getResourceAttributeVal(name); } public void setAttributeValue(String name, Object value) throws WavesetException { getResource().setResourceAttributeVal(name,value); |
When an update is received, the adapter uses the IAPI classes, notably IAPIFactory to:
Collect the changed attributes
Map the changes to a unique Identity Manager object
Update that object with the changed information
Using the Active Sync event parameter configurator for the resource, IAPIFactory.getIAPI constructs an IAPI object, either IAPIUser or IAPIProcess from a map of changed attributes. If an exclusion rule (iapi_create, iapi_delete, or iapi_update) is configured for the resource, IAPIFactory checks if the account is excluded. If a non-null object is created and returned by the Factory, the adapter can modify the IAPI object (for example, by adding a logger), then submits it.
When the object is submitted, the form associated with the resource is expanded with the object view before the view is checked in. For more information about forms and views, see Deployment Reference.
In SkeletonActiveSyncResourceAdapter, this process is handled in the buildEvent and processUpdates methods.
No system requirements are associated with adapter shutdown. Identity Manager calls the shutdown method, which is an opportunity for your adapter to cleanup any objects still in use from the polling loop.