Express (Distributed operating systems), v8.0 > Secure applications and their environment > Authenticate users > Select a registry or repository > Manage realms in a federated repository > Virtual member manager > Develop with virtual member manager > Integrate virtual member manager into the application > Sample code
Sample code for creating an extended entity type in a custom namespace
Use the sample code snippet and data graphs to create an entity type, which extends from a built-in entity type, in a custom namespace.
The following steps are covered in this sample code snippet:
- Create the schema in the custom namespace, //publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext for a new entity type, PersonAccountExt, which is extended from the built-in entity type, PersonAccount.
- Create an entity person1 of the PersonAccountExt entity type.
- Add a new property, HomePhone, to the newly created entity type, PersonAccountExt and map the new property, HomePhone to the LDAP attribute, primaryOwnerContact.
- Add HomePhone property with value to person1 entity.
- Verify that HomePhone property is added to the person1 entity.
The nsURI property specifies the custom namespace to which the new property is added. The first time that you use a custom namespace URI, map the namespace URI (nsURI) property to a unique namespace prefix (nsPrefix). If you do not specify a nsURI value, the new property is added to the default namespace. The default namespace is //www.ibm.com/websphere/wim, which is mapped by default, to the wim nsPrefix value.
Prerequisites
Ensure that we have read the information and completed the steps described in the topic, Program prerequisites, including the section, Extend property schema, which has information about propertySchema and extensionPropertySchema data objects and lists the valid syntax for property data types.
Add the following import statement also to your class:
import com.ibm.websphere.wim.exception.SchemaAlreadyExistException;Ensure that an LDAP repository is configured in your federated repositories configuration. See the topic, Configure LDAP in a federated repository in the WAS information center.
Sample code
Add the following code snippet to the application code and replace the variables with the actual values to use.
/** * This method uses the schema extension API to add a new entity * extending from an existing virtual member manager entity. */ public static void testRunTimeAddNewEntity() { // Create schema for new entity type addEntityPersonAccountExt(); // Create entity of new entity type createPersonAccountExt(); // Add a property 'HomePhone' to 'PersonAccountExt' // and map it to 'primaryOwnerContact' attribute in LDAP addPropertyToPersonAccountExt(); // Add 'HomePhone' to 'person1' addHomePhoneForPersonAccountExt(); // Search for the person searchPersonAcctExt(); } /** * Method to create the schema for 'PersonAccountExt' * in the custom namespace, //publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext */ @SuppressWarnings("unchecked") private static void addEntityPersonAccountExt() { try { System.out.println("\nCLIENT: Creating schema for 'PersonAccountExt' . . . "); DataObject root = SDOHelper.createRootDataObject(); // Create a schema object under root DataObject dynaSchemaDO = root.createDataObject(SchemaConstants.DO_SCHEMA); // Create new entity type schema object. This object will hold the schema definition // for the 'PersonAccountExt' entity type that we want to create. DataObject entitySchemaDO = dynaSchemaDO.createDataObject(SchemaConstants.DO_ENTITY_SCHEMA); // Set the namespace for new entity type // As this is a custom namespace, we also need to specify the prefix entitySchemaDO.setString(SchemaConstants.PROP_NS_URI, “//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext”); entitySchemaDO.setString(SchemaConstants.PROP_NS_PREFIX, “yourprefix”); // Set the entity type name entitySchemaDO.set(SchemaConstants.PROP_ENTITY_NAME, "PersonAccountExt"); // Set the parent entity type name. entitySchemaDO.set(SchemaConstants.PROP_PARENT_ENTITY_NAME, Service.DO_PERSON_ACCOUNT); // Create an entity configuration data object // This data object defines repository details DataObject entConfigDO = entitySchemaDO.createDataObject(SchemaConstants.DO_ENTITY_CONFIGURATION); // Set the default parent to the base entry of the configured LDAP. entConfigDO.set(SchemaConstants.PROP_DEFAULT_PARENT, "dc=yourco,dc=com"); // Set the RDN (login) property to uid. entConfigDO.set(SchemaConstants.PROP_RDN_PROPERTY, "uid"); // Set the repository id. DataObject reposConfigInfo1DO = entConfigDO.createDataObject(SchemaConstants.DO_META_DATA); reposConfigInfo1DO.set(SchemaConstants.PROP_NAME, ConfigService.CONFIG_DO_OBJECTCLASSES); reposConfigInfo1DO.set(SchemaConstants.PROP_REPOSITORY_ID, "LDAP1"); // Set the object classes for the added object. These classes are from the LDAP schema. List objReadValues = reposConfigInfo1DO.getList(SchemaConstants.PROP_VALUES); objReadValues.add("inetorgperson"); objReadValues.add("organizationalperson"); objReadValues.add("person"); // Set the RDN property for the repository DataObject reposConfigInfo3DO = entConfigDO.createDataObject(SchemaConstants.DO_META_DATA); reposConfigInfo3DO.set(SchemaConstants.PROP_NAME, ConfigService.CONFIG_DO_RDN_ATTRIBUTES); reposConfigInfo3DO.set(SchemaConstants.PROP_REPOSITORY_ID, "LDAP1"); List values = reposConfigInfo3DO.getList(SchemaConstants.PROP_VALUES); values.add("uid"); System.out.println("Create Schema input datagraph -> " + printDO(root)); // Invoke the create schema API DataObject outRoot = service.createSchema(root); System.out.println("Create Schema output datagraph -> " + printDO(outRoot)); System.out.println("\nCLIENT: new entity type is created."); } catch (SchemaAlreadyExistException e) { System.out.println("CLIENT: entity type already exists.\n\n"); } catch (Exception e) { e.printStackTrace(); } } /** * Method to create an entity of the 'PersonAccountExt' entity type. */ private static void createPersonAccountExt() { //Create Person 1 try { System.out.println("\nCLIENT: Creating Person 1 . . ."); // Gets an empty data graph of Person from WIM Service. DataObject root = SDOHelper.createRootDataObject(); // Create a "PersonAccount" entity type data object under root // This object is in the custom namespace DataObject person = root.createDataObject(SchemaConstants.DO_ENTITIES, "//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext", "PersonAccountExt"); // Set the values for required attributes, uid, cn and sn person.set("uid", "person1"); person.set("cn", "Person 1"); person.set("sn", "Person1LastName"); System.out.println("Create PersonAccountExt input datagraph -> " + printDO(root)); // Invoke the create API to create the person account entity defined above root = service.create(root); System.out.println("Create PersonAccountExt output datagraph -> " + printDO(root)); System.out.println("CLIENT: Person 1 has been created. \n\n"); } catch (Exception e) { e.printStackTrace(); } } /** * Method to add a property 'HomePhone' to 'PersonAccountExt' entity type * and map it to 'primaryOwnerContact' attribute in LDAP */ @SuppressWarnings("unchecked") private static void addPropertyToPersonAccountExt() { try { DataObject root = SDOHelper.createRootDataObject(); // Create a new "schema" object under root // This object will contain the details of the schema modifications that have to be made DataObject schema = root.createDataObject(SchemaConstants.DO_SCHEMA); // Create a property schema data object under the schema object created earlier DataObject propertySchema = schema.createDataObject(SchemaConstants.DO_PROPERTY_SCHEMA); // Set the property name propertySchema.setString(SchemaConstants.PROP_PROPERTY_NAME, "HomePhone"); // Set the property namespace as the custom namespace propertySchema.setString(SchemaConstants.PROP_NS_URI, "//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext"); // Specify that the property is not multi-valued propertySchema.setBoolean(SchemaConstants.PROP_MULTI_VALUED, false); // Specify the data type of the property as String propertySchema.setString(SchemaConstants.PROP_DATA_TYPE, SchemaConstants.DATA_TYPE_STRING); // Specify the applicable entity types for this property // The property will be added for all entity type names specified in the list propertySchema.getList(SchemaConstants.PROP_APPLICABLE_ENTITY_TYPE_NAMES) .add("yourprefix:PersonAccountExt"); System.out.println("Add property input datagraph " + printDO(root)); // Invoke the create schema API root = service.createSchema(root); System.out.println("Add property output datagraph " + printDO(root)); // Map the 'HomePhone' property created above to the 'primaryOwnerContact' LDAP attribute Hashtable configData = new Hashtable(); // Specify the repository for which this property needs to be mapped configData.put(DynamicConfigConstants.DYNA_CONFIG_KEY_REPOS_ID, "LDAP1"); DataObject configProvider = SDOHelper.createConfigProviderDataObject(); // Specify the repository type as "Ldap" DataObject ldapRepos = SDOHelper.createConfigRepositoryDataObject(configProvider, ConfigConstants.CONFIG_DO_LDAP_REPOSITORY_TYPE); // Give the property name and attribute name that need to be mapped to each other DataObject attrConfig = ldapRepos.createDataObject(ConfigConstants.CONFIG_DO_ATTRIBUTE_CONFIGUARTION); DataObject attr = attrConfig.createDataObject(ConfigConstants.CONFIG_DO_ATTRIBUTES); attr.setString(ConfigConstants.CONFIG_PROP_PROPERTY_NAME, "HomePhone"); attr.setString(ConfigConstants.CONFIG_PROP_NAME, "primaryOwnerContact"); configData.put(DynamicConfigConstants.DYNA_CONFIG_KEY_PROP_CONFIG, attr); // Call the dynamic config update // This API updates the mapping for this session only, this mapping is not persistent service.dynamicUpdateConfig(DynamicConfigConstants.DYNA_CONFIG_EVENT_ADD_PROPERTY_CONFIG, configData); } catch(Exception e) { e.printStackTrace(); } } /** * Add 'HomePhone' to 'person1' entity created in LDAP earlier */ private static void addHomePhoneForPersonAccountExt() { try { DataObject root = SDOHelper.createRootDataObject(); DataObject entity = SDOHelper.createEntityDataObject(root, "//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext", "PersonAccountExt"); // Set the unique name for the object to which the 'HomePhone' value needs to be set entity.createDataObject(SchemaConstants.DO_IDENTIFIER).set(SchemaConstants.PROP_UNIQUE_NAME, "uid=person1,dc=yourco,dc=com"); // Specify the value of 'HomePhone' entity.set("HomePhone", "020-2341123"); System.out.println("Set property input datagraph -> " + printDO(root)); // Invoke the VMM update API root = service.update(root); System.out.println("Set property output datagraph -> " + printDO(root)); } catch (Exception e) { e.printStackTrace(); } } /** * Search for 'PersonAccountExt' */ @SuppressWarnings("unchecked") private static void searchPersonAcctExt() { try { DataObject root = SDOHelper.createRootDataObject(); // Create a search control data object DataObject searchCtrl = SDOHelper.createControlDataObject(root, null, SchemaConstants.DO_SEARCH_CONTROL); // Specify the properties that need to be fetched for all matching entries searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("uid"); searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("sn"); searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("cn"); searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("HomePhone"); // Specify the matching criteria as the search expression searchCtrl.setString(SchemaConstants.PROP_SEARCH_EXPRESSION, "@xsi:type='PersonAccountExt'"); // Invoke the search API root = service.search(root); System.out.println("Output datagraph -> " + printDO(root)); // Iterate over the search results printIdentifiers(root); } catch (Exception e) { e.printStackTrace(); } }In the sample code, dynamicUpdateConfig() API is used for adding property configuration for mapping a virtual member manager property to an LDAP attribute. When configuration updates are made at runtime by using dynamicUpdateConfig() API, only the configuration in memory is updated and the configuration file is not updated, so changes are not persisted.
To persist configuration changes, use the addIdMgrLDAPAttr wsadmin command to map LDAP attributes to virtual member manager properties. See the topic IdMgrRepositoryConfig command group for the AdminTask object in the WAS information center. Alternately, you can map LDAP attributes to virtual member manager properties by using the administrative console as described in the following steps:
- In the administrative console, click Global security > Federated repositories > Manage repositories > repository_ID.
- Under Additional properties, click the LDAP attributes link.
- Click Add, and select Supported from the drop-down menu.
- Enter the LDAP attribute name in the Name field, the virtual member manager property name in the Property name field, and the entity type which applies the attribute mapping in the Entity types field. For the above example, enter the following values:
- Name: HomePhone
- Property: primaryOwnerContact
- Entity types: PersonAccountExt
Input and output data graphs
Input data graph for creating new extended entity type:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim"> <wim:Root> <wim:schema> <wim:entitySchema nsPrefix="yourprefix" nsURI="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext" entityName="PersonAccountExt" parentEntityName="PersonAccount"> <wim:entityConfiguration defaultParent="dc=yourco,dc=com" rdnProperty="uid"> <wim:metaData name="objectClasses" repositoryId="LDAP1"> <wim:values>inetorgperson </wim:values> <wim:values>organizationalperson </wim:values> <wim:values>person </wim:values> </wim:metaData> <wim:metaData name="rdnAttributes" repositoryId="LDAP1"> <wim:values>uid </wim:values> </wim:metaData> </wim:entityConfiguration> </wim:entitySchema> </wim:schema> </wim:Root> </sdo:datagraph>Output data graph after creating new extended entity type:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim"> <wim:Root> <wim:schema> <wim:entitySchema nsPrefix="yourprefix" nsURI="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext" entityName="PersonAccountExt" parentEntityName="PersonAccount"> <wim:repositoryIds>LDAP1 </wim:repositoryIds> <wim:entityConfiguration defaultParent="dc=yourco,dc=com" rdnProperty="uid"> <wim:metaData name="objectClasses" repositoryId="LDAP1"> <wim:values>inetorgperson </wim:values> <wim:values>organizationalperson </wim:values> <wim:values>person </wim:values> </wim:metaData> <wim:metaData name="rdnAttributes" repositoryId="LDAP1"> <wim:values>uid </wim:values> </wim:metaData> </wim:entityConfiguration> </wim:entitySchema> </wim:schema> </wim:Root> </sdo:datagraph>Input data graph for creating an entity of the new entity type:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim" xmlns:yourprefix="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext"> <wim:Root> <wim:entities xsi:type="yourprefix:PersonAccountExt"> <wim:uid>person1 </wim:uid> <wim:cn>Person 1 </wim:cn> <wim:sn>Person1LastName </wim:sn> </wim:entities> </wim:Root> </sdo:datagraph>Output data graph after creating an entity of the new entity type:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim" xmlns:yourprefix="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext"> <wim:Root> <wim:entities xsi:type="yourprefix:PersonAccountExt"> <wim:identifier externalName="uid=person1,dc=yourco,dc=com" repositoryId="LDAP1" uniqueId="cb1ea321-8673-4012-9750-c917d4e7f2f6" uniqueName="uid=person1,dc=yourco,dc=com"/> </wim:entities> </wim:Root> </sdo:datagraph>Input data graph for creating a new property for the new entity type:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim"> <wim:Root> <wim:schema> <wim:propertySchema nsURI="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext" dataType="String" multiValued="false" propertyName="HomePhone"> <wim:applicableEntityTypeNames>yourprefix:PersonAccountExt </wim:applicableEntityTypeNames> </wim:propertySchema> </wim:schema> </wim:Root> </sdo:datagraph>Output data graph after creating a property for the new entity type:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim"> <wim:Root> <wim:schema> <wim:propertySchema nsURI="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext" dataType="String" multiValued="false" propertyName="HomePhone"> <wim:repositoryIds>LDAP1 </wim:repositoryIds> <wim:applicableEntityTypeNames>yourprefix:PersonAccountExt </wim:applicableEntityTypeNames> </wim:propertySchema> </wim:schema> </wim:Root> </sdo:datagraph>Input data graph for adding property with a value to the entity:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim" xmlns:yourprefix="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext"> <wim:Root> <wim:entities xsi:type="yourprefix:PersonAccountExt"> <wim:identifier uniqueName="uid=person1,dc=yourco,dc=com"/> <yourprefix:HomePhone>020-2341123 </yourprefix:HomePhone> </wim:entities> </wim:Root> </sdo:datagraph>Output data graph after adding property with a value to the entity:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim" xmlns:yourprefix="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext"> <wim:Root> <wim:entities xsi:type="yourprefix:PersonAccountExt"> <wim:identifier externalName="uid=person1,dc=yourco,dc=com" repositoryId="LDAP1" uniqueId="cb1ea321-8673-4012-9750-c917d4e7f2f6" uniqueName="uid=person1,dc=yourco,dc=com"/> <yourprefix:HomePhone>020-2341123 </yourprefix:HomePhone> </wim:entities> </wim:Root> </sdo:datagraph>Input data graph for searching for extended property:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim"> <wim:Root> <wim:controls xsi:type="wim:SearchControl" expression="@xsi:type='yourprefix:PersonAccountExt'"> <wim:properties>uid </wim:properties> <wim:properties>sn </wim:properties> <wim:properties>cn </wim:properties> <wim:properties>yourprefix:HomePhone </wim:properties> </wim:controls> </wim:Root> </sdo:datagraph>Output data graph after searching for extended property:
<?xml version="1.0" encoding="UTF-8"?> <sdo:datagraph xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:sdo="commonj.sdo" xmlns:wim="//www.ibm.com/websphere/wim" xmlns:yourprefix="//publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ ://www.yourco.com/wim/yourext"> <wim:Root> <wim:entities xsi:type="yourprefix:PersonAccountExt"> <wim:identifier externalName="uid=person1,dc=yourco,dc=com" repositoryId="LDAP1" uniqueId="cb1ea321-8673-4012-9750-c917d4e7f2f6" uniqueName="uid=person1,dc=yourco,dc=com"/> <wim:uid>person1 </wim:uid> <wim:cn>Person 1 </wim:cn> <wim:sn>Person1LastName </wim:sn> <yourprefix:HomePhone>020-2341123 </yourprefix:HomePhone> </wim:entities> </wim:Root> </sdo:datagraph>
Parent topic: Sample code