Oracle® Identity Management Application Developer's Guide
10g Release 2 (10.1.2) B14087-02 |
|
Previous |
Next |
This appendix explains how to use plug-ins to customize provisioning policy evaluation, data validation, data manipulation, and event delivery in typical deployments of Oracle Provisioning Service version 3.0.
The Oracle provisioning server cannot support all of the provisioning needs of a deployment. Hence, hooks are provided at various stages of user creation, modification, and deletion. These hooks enable an enterprise to incorporate its own business rules and to tailor information creation to its needs. The hooks take the form of Java plug-ins.
This appendix contains these topics:
There are three types of plug-ins:
Data entry plug-ins
Data manipulation and data access plug-ins
Event Delivery plug-ins
The data entry plug-ins can be used by applications that integrate with the provisioning framework using either synchronous or asynchronous provisioning. The data access plug-ins are used only by applications that are integrated with the provisioning framework for synchronous provisioning. The event delivery plug-ins are used only by applications that integrate with the provisioning framework using asynchronous provisioning.
Oracle Provisioning Console, Oracle integration and provisioning server, and other mechanisms that affect the base user information in the directory invoke these plug-ins when the information is created. By configuring a data entry plug-in, a deployment can do any of the following:
Validate attribute values for application users
Validate attribute values for base users
Enhance attribute values for application users
Enhance attribute values for base users
Evaluate provisioning policies
If you want the deployed application to maintain application user information you must configure a data access plug-in for it. This type of plug-in enables you to maintain the application information either outside of the directory or within it as several entries.
Data entry and data access plug-ins are typically invoked from one of these environments:
User provisioning console for Oracle Delegated Administration Services
Oracle directory integration and provisioning server
Provisioning API
Bulk Provisioning Tools
The event delivery plug-ins are required by applications that have the JAVA interface type and that subscribe for provisioning events. Applications that have synchronous provisioning should not implement event delivery plug-ins.
All of the plug-ins that you provide for an application must be in a JAR file that can be uploaded to the directory with the standard LDIF template. See the section "Configuration Template" for an example. The plug-in interface definitions are found in $ORACLE_HOME/jlib/ldapjclnt10.jar
. Refer to Oracle Internet Directory API Reference and the public interfaces for a more detailed description. If the application requires additional jar files, you can upload them too.
Data entry plug-ins take two forms:
Pre–data-entry plug-ins
Post–data-entry plug-ins
If you want to use either of these plug-ins, you must implement the oracle.idm.provisioning.plugin.IdataEntryPlugin
interface. This interface has three methods. Here it is:
/** * The applications can perform a post data entry operation by * implementing this method. * * @param appCtx the application context * @param idmUser the IdmUser object * @param baseUserAttr Base user properties * @param appUserAttr App user properties * @throws PluginException when an exception occurs. */ public PluginStatus process(ApplicationContext appCtx, IdmUser idmUser, ModPropertySet baseUserAttr, ModPropertySet appUserAttr)throws PluginException; /** * Returns the Modified Base User properties * * @return ModPropertySet modified base user properties. */ public ModPropertySet getBaseAttrMods(); /** * Returns the Modified App User properties * * @return ModPropertySet modified app user properties. */ public ModPropertySet getAppAttrMods();
Typically the plug-in implementer uses these methods for data validation or policy evaluation. In the latter case, a base user attribute is used to make the decision.
The application context object contains this information:
LDAP directory context
If you want the application to perform a directory operation, you can have it obtain the LDAP context from the application object. Note that this LDAP context should not be closed in the plug-in.
Plug-in call mode
The plug-in is called from Oracle Provisioning Console, Oracle directory integration and provisioning server, or another environment that invokes the provisioning API. If the calling environment is Oracle Directory Integration and Provisioning, the provisioning service calls the plug-in. The two possible values are INTERACTIVE_MODE
and AUTOMATIC_MODE
. The first indicates that the plug-in was invoked through interaction between Oracle Delegated Administration Services and a client application. The second indicates that the plug-in was invoked by Oracle Directory Integration and Provisioning, where user intervention does not occur.
Client locale
The plug-in may want to know what the client locale is, especially if it is invoked from Oracle Delegated Administration Services.
Plug-in call operation
You may decide to have data entry plug-ins for both create and modify user operations. You may even implement these plug-ins in the same class. Under these conditions, the plug-in must determine which operation is invoked. The application context object uses the values OP_CREATE
and OP_MODIFY
to identify the operation.
Plug-in invocation point
The data entry plug-in is typically used to determine whether a user needs to be provisioned for an application. The policy evaluation and data validation that occurs can be performed in either a pre–data-entry plug-in or a post–data-entry plug-in. You may choose either or both. If you choose both, you can implement them in the same class. The application context object specifies which one is actually invoked. It uses the values PRE_DATA_ENTRY
and POST_DATA_ENTY
to do this.
Callback context
If you decide to have both pre and post plug-ins for an operation and you want the pre plug-in to share information with the post plug-in, you can set the callback context in the application context object of the pre–data-entry plug-in. The post– data-entry plug-in can then obtain and use this callback context.
Logging
You can use the log methods provided in the application context object to log information for the plug-in.
The calling sequence looks like this:
Download and instantiate a plug-in object based on the configuration information object in Oracle Internet Directory
Construct an application context object that will be passed to the plug-in.
Call process method()
Call getBaseAttrMods()
to obtain base user attributes that are modified in process()
.
Merge the base user attributes returned by getBaseAttrMods()
with the base user attributes, depending on the plug-in execution status. The execution status can be either success
or failure
. The plug-in implementer must return a valid plug-in execution status object. If null is returned, the execution status is considered a failure.Merging of the base user will only be done if the plug-in execution status is successful.
Call getAppAttrMods()
for the plug-in. This method obtains application user attributes that are modified in process()
.
Merge the application user attributes returned by getAppAttrMods()
with the application user attributes, depending on the user provisioning status returned by the plug-in.
The pre–data-entry plug-in generates values for application attributes. The attribute defaults specified during application registration are passed to this plug in along with the current base user attributes. The returned values are displayed in the UI if the invocation environment is interactive like Oracle Delegated Administration Services.
The pre–data-entry plug-in can decide whether the user should be provisioned for an application. The plug-in examines base user attributes to make the decision. It is invoked during create and modify operations. You can support both operations with one plug-in class, or you can assign one class to each.
If the application decides to have pre–data- entry plug-ins for create and modify operations, two configuration entries must be created in Oracle Internet Directory under the application container. The first entry is for the create operation:
This
dn: cn=PRE_DATA_ENTRY_CREATE, cn=Plugins, cn=FILES, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: oracle.myapp.provisioning.UserCreatePlugin orclODIPPluginAddInfo: Pre Data Entry Plugin for CREATE operation
The second entry is for the modify operation:
dn: cn=PRE_DATA_ENTRY_MODIFY, cn=Plugins, cn=FILES, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: oracle.myapp.provisioning.UserModifyPlugin orclODIPPluginAddInfo: Pre Data Entry Plugin for MODIFY operation
In this example, separate classes for create and modify plug-ins are shown.
The post–data-entry plug-in validates data entered by the user in the UI. In addition, it generates derived attribute values. If the plug in fails for any one application, the UI does not proceed. All applications must successfully validate the data before a user entry can be created in the directory. However, in the case of non-UI environment or automatic route, the plug-in implementer can decide to raise an error or continue, based on the plug-in call mode (INTERACTIVE_MODE
or AUTOMATIC_MODE
).
Like the pre–data-entry plug-in, the post–data-entry plug-in is invoked during create and modify operations. The application can decide to implement one plug-in class for both operations or a separate class for each.
If you decide to have post–data-entry plug-ins for create and modify operations, create two configuration entries in Oracle Internet Directory under the application container. The first entry is for the create operation:
dn: cn=POST_DATA_ENTRY_CREATE, cn=Plugins, cn=FILES, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: oracle.myapp.provisioning.UserMgmtPlugin orclODIPPluginAddInfo: Post Data Entry Plugin for CREATE and MODIFY operations
The second entry is for the modify operation:
dn: cn=POST_DATA_ENTRY_MODIFY, cn=Plugins, cn=FILES, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: oracle.myapp.provisioning.UserMgmtPlugin orclODIPPluginAddInfo: Post Data Entry Plugin for MODIFY and CREATE operation
In this example, too, separate classes for create and modify plug-ins are shown.
The primary purpose of the data access plug in is to manage the application-specific information of the user in the directory. You can use this plug-in to create and retrieve the information.
The data access plug-in is invoked whenever a user is created and is requesting provisioning for an application—whether by Oracle Delegated Administration Services, by Oracle Directory Integration and Provisioning, or by bulk provisioning tools.
The data access plug-in is invoked during modify and delete operations as well. It can update the application information or remove it.
If you want to use the data access plug-in, implement the interface oracle.idm.provisioning.plugin.IDataAccessPlugin
. Here is the interface:
/** * The applications can create/modify/delete the user footprint by * implementing this method. * * @param appCtx the application context * @param idmUser IdmUser object * @param baseUserAttr Base user properties * @param appUserAttr App user properties * * @return PluginStatus a plugin status object, which must contain * the either <codE>IdmUser.PROVISION_SUCCESS</CODE> or * <codE>IdmUser.PROVISION_FAILURE</CODE> provisioning status * * @throws PluginException when an exception occurs. */ public PluginStatus process(ApplicationContext appCtx, IdmUser idmUser, ModPropertySet baseUserAttr, ModPropertySet ppUserAttr) throws PluginException; /** * The applications can return their user footprint by * implementing this method. Use <CODE> * oracle.ldap.util.VarPropertySet </CODE> * as the return object * * <PRE> * For Ex. * PropertySet retPropertySet = null; * retPropertySet = new VarPropertySet(); * * //Fetch the App data and add it to retPropertySet * retPropertySet.addProperty("name", "value"); * .. * return retPropertySet; * </PRE> * * @throws PluginException when an exception occurs. */ public PropertySet getAppUserData(ApplicationContext appCtx, IdmUser user, String reqAttrs[]) throws PluginException;
If you want to manage the user information for an application, create a plug-in configuration entry in the directory under the application container. The example that follows shows what this entry looks like:
dn: cn=DATA_ACCESS, cn=Plugins, cn=FILES, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: oracle.myapp.provisioning.UserDataAccPlugin orclODIPPluginAddInfo: Data Access Plugin
The primary purpose of the event delivery plug-in is to use the events notified by the Oracle integration and provisioning server. Events are delivered to the plug-in by the Oracle integration and provisioning server. Based on the event type and the action to be performed in the application repository, the plug-in performs the required operations. The interface definitions for this plug-in are as follows:
/* $Header: IEventPlugin.java 09-jun-2005.12:45:53 * /* Copyright (c) 2004, 2005, Oracle. All rights reserved. */ /* DESCRIPTION All of the plug-in interfaces must extend this common interface. PRIVATE CLASSES None NOTES None */ package oracle.idm.provisioning.plugin; /** * This is the base interface */ public interface IEventPlugin { /** * The applications can perform the initialization logic in this method. * * @param Object For now it is the provisioning Profile that will be passed. * look at oracle.ldap.odip.engine.ProvProfile for more details. * * * @throws PluginException when an exception occurs. */ public void initialize(Object profile) throws PluginException; /** * The applications can perform the termination logic in this method. * * @param void Provisioning Profile Object will be sent. * refer to oracle.ldap.odip.engine.ProvProfile for more details * @throws PluginException when an exception occurs. */ public void terminate(Object profile) throws PluginException; /** * Set Additional Info. * Since we pass on the complete profile, there is no requirement to set * the additiona * @param addInfo Plugin additional info */ //public void setAddInfo(Object addInfo); } /* $Header: IEventsFromOID.java 09-jun-2005.12:45:53 */ /* Copyright (c) 2004, 2005, Oracle. All rights reserved. */ /* DESCRIPTION Applications interested in receiving changes from OID should implement this interface. PRIVATE CLASSES <None> NOTES */ package oracle.idm.provisioning.plugin; import oracle.idm.provisioning.event.Event; import oracle.idm.provisioning.event.EventStatus; /** * Applications interested in receiving changes from OID should implement this * interface. The applications register with the OID for the changes occurring * at OID. The DIP engine would instantiate an object of this class and invoke * the initialize(), sendEventsToApp(), and truncate() method in the same * sequence. The initialize method would provide the appropriate information * from the profile in the form of a java.util.Hashtable object. * The property names, i.e. the hash table key that could be used by the * interface implementer will be defined as constants in this interface. * * @version $Header: IEventsFromOID.java 09-jun-2005.12:45:53 $ */ public interface IEventsFromOID extends IEventPlugin { /** * Initialize. The application would provide any initialization logic * through method. The DIP engine after instantiating a class that * implements this interface will first invoke this method. * * @param prop A HashMap that would contain necessary information exposed * to the applications * @throws EventInitializationException the applications must throw this * exception in case of error. */ public void initialize(Object provProfile) throws EventPluginInitException; /** * OID Events are deliverd to the application through this method. * * @param evts an array of LDAPEvent objects returned by the DIP engine * @return the application logc must process these events and return the * status of the processed events * @throws EventDeliveryException the applications must throw this exception * in case of any error. */ public EventStatus[] sendEventsToApp(Event [] evts) throws EventDeliveryException; } /* $Header: IEventsToOID.java 09-jun-2005.12:45:53 $ */ /* Copyright (c) 2004, 2005, Oracle. All rights reserved. */ /* DESCRIPTION Applications interested in sending changes to OID should implement this interface. */ package oracle.idm.provisioning.plugin; import oracle.idm.provisioning.event.Event; import oracle.idm.provisioning.event.EventStatus; /** * Applications interested in sending changes to OID should implement this * interface. The applications must register with the OID for the sending * changes at their end to DIP. The DIP engine would instantiate an object * of this class and invoke the initialize(), sendEventsFromApp(), and * truncate() method in the same sequence. The initialize method would * provide the appropriate information from the profile in the form of * a java.util.Hashtable object. The property names, i.e. the hash table key * that could be used by the interface implementer will be defined as * constants in this interface. * */ public interface IEventsToOID extends IEventPlugin { /** * Initialize. The application would provide any initialization logic * through method. The DIP engine after instantiating a class that * implements this interface will first invoke this method. * * @param prop ProvProfile * oracle.ldap.odip.engine.ProvProfile * @throws EventPluginInitException the applications must throw this * exception in case of error. */ public void initialize(Object profile) throws EventPluginInitException; /** * Application Events are deliverd to OID through this method. * * @return an array of Event objects returned to be processed by the * DIP engine. * @throws EventDeliveryException the applications must throw this exception * in case of any error. */ public Event[] receiveEventsFromApp() throws EventDeliveryException; /** * Application can let the DIP engine know whether there are more event to * follow through this method * * @return ture if there are more events to be returned and false otherwise * @throws PluginException the applications must throw this exception * in case of any error. */ public boolean hasMore() throws PluginException; /** * The status of the application events are intimated through this method. * i.e the DIP engine after processing the events calls this method to set * the event status. * * @param an array of Event status objects describing the processed event * status by the DIP engine. * @throws EventDeliveryException the applications must throw this exception * in case of any error. */ public void setAppEventStatus(EventStatus[] evtStatus) throws EventDeliveryException; }
Each of the provisioning plug-ins must return an object of the class oracle.idm.provisioning.plugin.PluginStatus
This object indicates the execution status, which is either success
or failure
. The object can return the user provisioning status as well.
The LDIF template provided here is used in Oracle Internet Directory10g Release 2 (10.1.2) to specify the application plug-in. You must create a directory entry for the application and upload the JAR file that contains the classes that implement the plug-in.
dn: cn=Plugins, cn=APPTYPE, cn=Applications, cn=Provisioning, cn=Directory Integration Platform,cn=Products,cn=OracleContext changetype: add add: orclODIPPluginExecData orclODIPPluginExecData: full_path_name_of_the_JAR_file objectclass: orclODIPPluginContainer
dn: cn=PRE_DATA_ENTRY_CREATE, cn=Plugins, cn=APPTYPE, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: Name_of_the_class_that_implements_the_plug-in orclODIPPluginAddInfo: Pre Data Entry Plugin for CREATE operation
dn: cn=PRE_DATA_ENTRY_MODIFY, cn=Plugins, cn=APPTYPE, cn=Applications,
cn=Provisioning, cn=Directory Integration Platform, cn=Products,
cn=OracleContext
changetype: add
objectClass: orclODIPPlugin
orclStatus: ENABLE
orclODIPPluginExecName: Name_of_the_class_that_implements_the_plug-in
orclODIPPluginAddInfo: Pre Data Entry Plugin for MODIFY operation
dn: cn=POST_DATA_ENTRY_CREATE, cn=Plugins, cn=APPTYPE, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: Name_of_the_class_that_implements_the_plug-in orclODIPPluginAddInfo: Post Data Entry Plugin for CREATE and modify operations
dn: cn=POST_DATA_ENTRY_MODIFY, cn=Plugins, cn=APPTYPE, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: Name_of_the_class_that_implements_the_plug-in orclODIPPluginAddInfo: Post Data Entry Plugin for MODIFY and CREATE operation
dn: cn=DATA_ACCESS, cn=Plugins, cn=APPTYPE, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: Name_of_the_class_that_implements_the_plug-in orclODIPPluginAddInfo: Data Access Plugin dn: cn=EVENT_DELIVERY_OUT, cn=Plugins, cn=APPTYPE, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: Name_of_the_class_that_implements_the_plug-in orclODIPPluginAddInfo: Event Delivery Plugin for Outbound dn: cn=EVENT_DELIVERY_IN, cn=Plugins, cn=APPTYPE, cn=Applications, cn=Provisioning, cn=Directory Integration Platform, cn=Products, cn=OracleContext changetype: add objectClass: orclODIPPlugin orclStatus: ENABLE orclODIPPluginExecName: Name_of_the_class_that_implements_the_plug-in orclODIPPluginAddInfo: Event Delivery Plugin for Inbound
/* Copyright (c) 2004, Oracle. All rights reserved. */ /** DESCRIPTION Sample PRE DATA Entry Plugin for CREATE operation that validates the attribute. PRIVATE CLASSES None. NOTES This class implements the PRE_DATA_ENTRY_CREATE plugin ONLY MODIFIED (MM/DD/YY) 12/15/04 \226 Creation */ package oracle.ldap.idm; import java.util.*; import javax.naming.*; import javax.naming.ldap.*; import javax.naming.directory.*; import oracle.ldap.util.*; import oracle.idm.provisioning.plugin.*; /** * This class implements the PRE_DATA_ENTRY_CREATE plugin ONLY * */ public class SamplePreDataEntryCreatePlugin implements IDataEntryPlugin { public ModPropertySet mpBaseUser = null; public ModPropertySet mpAppUser = null; public PluginStatus process(ApplicationContext appCtx,IdmUser idmuser, ModPropertySet baseUserAttr, ModPropertySet appUserAttr) throws PluginException { PluginStatus retPluginStatus = null; String retProvStatus = null; String retProvStatusMsg = null; LDIFRecord lRec = null; LDIFAttribute lAttr = null; String val = null; if(null == baseUserAttr.getModPropertyValue(\223departmentNumber\224)) { mpBaseUser = new ModPropertySet(); mpBaseUser.addProperty("departmentNumber","ST"); appCtx.log(\223Base user attribute \226 departmentNumber missing\224 + \223Setting default - ST\224); } else if ( baseUserAttr.getModPropertyValue(\223departmentNumber\224) .notIn(\223ST\224, \223APPS\224, \224CRM\224) ) { throw new PluginException(\223Invalid department Number\224); } if((null == appUserAttr) || null == appUserAttr.getModPropertyValue(\223emailQouta\224)) { mpAppUser = new ModPropertySet(); mpAppUser.addProperty("emailQouta","50M"); appCtx.log(\223Application user attribute - email Qouta missing \224 + \223Setting default - 50M\224); } return new PluginStatus(PluginStatus.SUCCESS, null, null); } public ModPropertySet getBaseAttrMods() { return mpBaseUser; } public ModPropertySet getAppAttrMods() { return mpAppUser; } }
/* Copyright (c) 2004, Oracle. All rights reserved. */ /** DESCRIPTION Sample POST DATA Entry Plugin for CREATE operation. Implementing a policy check to provision only those users who belong to \223SALES\224. PRIVATE CLASSES None. NOTES This class implements the POST_DATA_ENTRY_CREATE plugin ONLY MODIFIED (MM/DD/YY) 12/15/04 \226 Creation */ package oracle.ldap.idm; import java.util.*; import javax.naming.*; import javax.naming.ldap.*; import javax.naming.directory.*; import oracle.ldap.util.*; import oracle.idm.provisioning.plugin.*; /** * This class implements the POST_DATA_ENTRY_CREATE plugin ONLY * */ public class SamplePostDataEntryCreatePlugin { public ModPropertySet mpBaseUser = null; public ModPropertySet mpAppUser = null; public PluginStatus process(ApplicationContext appCtx,IdmUser idmuser, ModPropertySet baseUserAttr, ModPropertySet appUserAttr) throws PluginException { PluginStatus retPluginStatus = null; String retProvStatus = null; String retProvStatusMsg = null; if(null == baseUserAttr.getModPropertyValue(\223deptartmentNumber\224)) { mpBaseUser = new ModPropertySet(); mpBaseUser.addProperty("deptartmentNumber ","SALES"); appCtx.log("Base user attribute \221c\222 is missing"); retProvStatus = IdmUser.PROVISION_ REQUIRED; retProvStatusMsg = "Provision policy: Only \221SALES\222\224. } else if (baseUserAttr.getModPropertyValue(\223deptartmentNumber\224) .equals(\223SALES\224)) { retProvStatus = IdmUser.PROVISION_ REQUIRED; retProvStatusMsg = "Provision policy: Only \221SALES\222\224. } else { // do not provision those users who do not belong to SALES. retProvStatus = IdmUser.PROVISION_NOT_REQUIRED; retProvStatusMsg = "Do not provision the person who is not from \221SALES\222"; } return new PluginStatus(PluginStatus. SUCCESS, retProvStatusMsg, retProvStatus); } public ModPropertySet getBaseAttrMods() { return mpBaseUser; } public ModPropertySet getAppAttrMods() { return mpAppUser; } }
/* Copyright (c) 2004, Oracle. All rights reserved. */ /** DESCRIPTION Sample DATA Access Plugin. NOTES This class implements the DATA_ACCESS plugin MODIFIED (MM/DD/YY) 12/15/04 \226 Creation */ package oracle.ldap.idm; import javax.naming.*; import javax.naming.ldap.*; import javax.naming.directory.*; import oracle.ldap.util.*; import oracle.idm.provisioning.plugin.*; /** * This class implements the DATA_ACCESS plugin ONLY * */ public class SampleDataAccessPlugin { public PluginStatus process(ApplicationContext appCtx,IdmUser idmuser, ModPropertySet baseUserAttr,ModPropertySet appUserAttr) throws PluginException { try { DirContext dirCtx = appCtx.getDirCtx(); if ( appCtx.getCallOp().equals(ApplicationContext.OP_CREATE ) { // Use the directory context and create the entry. } elseif ( appCtx.getCallOp().equals(ApplicationContext.OP_MODIFY) { // Use the directory context and modify the entry. } } catch (Exception e) { throw new PluginException(e); } return new PluginStatus(PluginStatus.SUCCESS, null, null); } public PropertySet getAppUserData(ApplicationContext appCtx, IdmUser idmuser, String [] reqAttrs) throws PluginException { VarPropertySet vpSet = null; DirContext dirCtx = appCtx.getDirCtx(); try { Attributes attrs= dirCtx.getAttributes(\223myAppContainer\224); vpSet = new VarPropertySet(); // Populate the VarPropertySet from attrs } catch(Exception ne) { throw new PluginException(e); } return vpSet; } }