Standard resource adapter-specific methods are specific to the resource you are updating to synchronize with Waveset.
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 Waveset, 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 10–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 10–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 10–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 10–17 Account Features
Table 10–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 10–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 10–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 10–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 10–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 Waveset. |
Table 10–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 10–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 Waveset 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 Waveset.
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.
Waveset disable utility: If the resource does not support disabling an account, or supports disable by means of resetting the user’s password, the Waveset 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 Waveset 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 Waveset.
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 + "."); |