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 extending schema across multiple security domains

The configuration steps, commands, sample code, and data graphs for extending property schema across multiple security domains are provided here.

The following steps are covered in the configuration commands and sample code snippets:

  1. Create multiple security domains.
  2. Map the security domains to specific application servers.

  3. Install the prerequisite system applications.

  4. Add new properties to each server instance.
  5. Perform search operations by using properties extended on different instances.


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.

We must complete the following configuration steps before using the sample code in the application. Start wsadmin.sh and execute the following commands. Replace the variables with the actual values to use.

  1. Create a base profile by using the WAS Profile Management Tool. Ensure that the Admin Security is enabled. A new application server is created, for example, server1.

  2. Add another server, for example, server2.
    $AdminTask createApplicationServer nodeName {-name server2}
    

  3. Create a security domain.
    $AdminTask copySecurityDomainFromGlobalSecurity {-securityDomainName domain1}
    
  4. Map this domain to the server2 created in step 2.
    $AdminTask mapResourceToSecurityDomain { -securityDomainName domain1 -resourceName Cell=:Node=nodeName:Server=server2}
    

  5. In a multiple security domain environment, you can set the useGlobalSchema property to use the global schema instead of the domain-specific schema. Global schema refers to the schema of the admin domain. Application domains that are set to use global schema share the same schema of the admin domain. Hence, if you extend the schema for an application in one domain, consider how that might affect applications of other domains as they are also bound by the same schema. For example, adding a mandatory property for one application might cause other applications to fail.

    To use global schema, complete this step. If to use the domain-specific schema, then skip this step.

    $AdminTask setIdMgrUseGlobalSchemaForModel { -useGlobalSchema true -securityDomainName domain1 }
    

  6. Install wim.ear as a system application on server1.
    $AdminApp install
    WAS_HOME/systemApps/wim.ear { -appname wim -server server1 -systemApp}
    

  7. Install wimperdomain.ear as a normal application on server2. In a multiple security domain environment, deploy virtual member manager EJB on each target server, where the server scope is associated with that security domain, to get a reference to the virtual member manager instance in that domain. This procedure enables you to call virtual member manager APIs through EJB for a specific domain. Only users with the required access roles for virtual member manager APIs or superusers in that domain can call the respective APIs.
    $AdminApp install
    WAS_HOME/installableApps/wimperdomain.ear {
         -appname wimperdomain1
         -BindJndiForEJBNonMessageBinding {{ wim.ejb WIMService wimejb.jar,
              META-INF/ejb-jar.xml ejbd1/com/ibm/websphere/wim/ejb/WIMServiceHome}}
         -MapModulesToServers {{ wim.ejb wimejb.jar,META-INF/ejb-jar.xml
              WebSphere:cell=cellName,node=nodeName,server=server2 }}}
    

  8. Save the configuration.
    $AdminConfig save 


Sample code

Add the following sample code to the application code as described in the following steps. Replace the variables with the actual values that you want to use.

  1. The following variable declarations are required for using the methods in the sample code snippets given in the next steps. We can add these declarations to the application code and replace the variables with the actual values to use.
    //The service object that holds the virtual member manager ejb service reference for server1.
     private static Service service1 = null;
    
    //The service object that holds the virtual member manager ejb service reference for server2.
     private static Service service2 = null;
    
    //A string constant for the new property name to be added for server1.
     private static final String server1PropName = "postOfficeBox";
    
    //A string constant for the new property name to be added for server2.
     private static final String server2PropName = "age";
    

  2. Start server1 using the startServer command.

  3. Use the following locateServices() method to locate virtual member manager services running on WAS on the local host. Ensure that the bootstrap port is correctly specified in the locateServices() method.
    /**
     *  This method locates the virtual member manager services running on
     *  WebSphere Application Sever on the localhost
     */
    private static void locateServices()
    {
        // Remote access WIM Service EJB     try
        {
            Hashtable
    <String, String> environment = new Hashtable
    <String, String>();
            environment.put(LocalServiceProvider.PROVIDER_URL, "corbaloc:iiop:localhost:2814");
     
            service1 = new LocalServiceProvider(environment);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    
        try
        {
            Hashtable
    <String, String> environment = new Hashtable
    <String, String>();
            environment.put(LocalServiceProvider.EJB_JNDI_NAME,
                    "ejbd1/com/ibm/websphere/wim/ejb/WIMServiceHome");
            environment.put(LocalServiceProvider.PROVIDER_URL, "corbaloc:iiop:localhost:2815");
     
            service2 = new LocalServiceProvider(environment);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    

  4. Use the following createPropertyOnServer1() method to add a new property to the server1 instance.
    /**
     *  This method adds the "postOfficeBox" property to "PersonAccount" entity type.
     */
    private static void createPropertyOnServer1()
    {
        try
        {
            System.out.println("\nCreating new property type postOfficeBox
                    and add it to existing entity type PersonAccount");
     
            DataObject root = service1.createRootDataObject();
            DataObject dynaSchemaDO = root.createDataObject(SchemaConstants.DO_SCHEMA);
     
            // Create new property schema data object
    DataObject propSchemaDO = dynaSchemaDO.createDataObject(SchemaConstants.DO_PROPERTY_SCHEMA);
            // Set the values for the property, such as, namespace URI, namespace prefix, property name
    propSchemaDO.set(SchemaConstants.PROP_NS_URI, SchemaConstants.WIM_NS_URI);
            propSchemaDO.set(SchemaConstants.PROP_PROPERTY_NAME, server1PropName);
            propSchemaDO.setBoolean(SchemaConstants.PROP_MULTI_VALUED, false);
            propSchemaDO.set(SchemaConstants.PROP_DATA_TYPE, SchemaConstants.DATA_TYPE_STRING);
            List applicableEntityTypes = propSchemaDO.getList(SchemaConstants.PROP_APPLICABLE_ENTITY_TYPE_NAMES);
            applicableEntityTypes.add(Service.DO_PERSON_ACCOUNT);
     
            System.out.println("Input datagraph -> " + printDO(root));
            // Invoke the create schema API
            root = service1.createSchema(root);
            System.out.println("Output datagraph -> " + printDO(root));
            System.out.println("\nCLIENT: new property type is created.");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
  5. Stop server1 using the stopServer command.

  6. Start server2 using the startServer command.

  7. Use the following createPropertyOnServer2() method to add a new property to the server2 instance.
    /**
     *  This method adds the "age" property to "PersonAccount" entity type.
     */
    private static void createPropertyOnServer2()
    {
        try
        {
            System.out.println("\nCreating new property type age and
                    add it to existing entity type Person");
     
            DataObject root = service2.createRootDataObject();
            DataObject dynaSchemaDO = root.createDataObject(SchemaConstants.DO_SCHEMA);
     
            // Create new property schema data object
    DataObject propSchemaDO = dynaSchemaDO.createDataObject(SchemaConstants.DO_PROPERTY_SCHEMA);
            // Set the values for the property, such as, namespace URI, namespace prefix, property name
    propSchemaDO.set(SchemaConstants.PROP_NS_URI, SchemaConstants.WIM_NS_URI);
            propSchemaDO.set(SchemaConstants.PROP_PROPERTY_NAME, server2PropName);
            propSchemaDO.setBoolean(SchemaConstants.PROP_MULTI_VALUED, false);
            propSchemaDO.set(SchemaConstants.PROP_DATA_TYPE, SchemaConstants.DATA_TYPE_INT);
            List applicableEntityTypes = propSchemaDO.getList(SchemaConstants.PROP_APPLICABLE_ENTITY_TYPE_NAMES);
            applicableEntityTypes.add(Service.DO_PERSON_ACCOUNT);
     
            SDOUtils.printDataGraph("Input datagraph", root);
            System.out.println("Input datagraph -> " + printDO(root));
            // Invoke the create Schema API
            root = service2.createSchema(root);
            System.out.println("Output datagraph -> " + printDO(root));
            System.out.println("New property type is created.");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
  8. Stop server2 using the stopServer command.

  9. Start server2 and server1.

  10. Create entities with the new properties added in steps 4 and 7. For sample code to add new properties, see the topic Sample code for extending schema in the file repository.

  11. Use the following testSearchProperties() method to perform search operations by using properties extended on different instances.
    /**
      *  Method that runs different searches on different servers.
      */
    private static void testSearchProperties()
    {
        // Search using the server1 property but using service1
        System.out.println("Searching property '" + server1PropName + "' on server1");
        searchserver1PropName(service1);
    
        // Utility stop to synchronize output
        pause();
    
        // Search using the server1 property but using service2
        System.out.println("Searching property '" + server1PropName + "' on server2");
        searchserver1PropName(service2);
    
        // Utility stop to synchronize output
        pause();
    
        // Search using the server2 property but using service2
        System.out.println("Searching property '" + server2PropName + "' on server2");
        searchserver2PropName(service2);
    
        // Utility stop to synchronize output
        pause();
    
        // Search using the server2 property but using service1
        System.out.println("Searching property '" + server2PropName + "' on server1");
        searchserver2PropName(service1);
    }
    
    /**
     *  A utility method added to ensure that the exception is flushed to the console
     *  before starting with the next operation.
     */
    private static void pause()
    {
        try
        {
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
        }
    }
    
    /**
     * Method to search on 'age'
     * @param service  */
    @SuppressWarnings("unchecked")
    private static void searchserver2PropName(Service service)
    {
        try
        {
            //Search
            DataObject root = SDOHelper.createRootDataObject();
            DataObject searchCtrl = SDOHelper.createControlDataObject(root, null,
                    SchemaConstants.DO_SEARCH_CONTROL);
            searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("uid");
            searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("sn");
            searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("cn");
            searchCtrl.setString(SchemaConstants.PROP_SEARCH_EXPRESSION,
                    "@xsi:type='PersonAccount' and " + server2PropName + " > 4");
            root = service.search(root);
            System.out.println("Output datagraph -> " + printDO(root));
            List searchResults = root.getList(SchemaConstants.DO_ENTITIES);
            for (int i = 0; i
    < searchResults.size(); i++) {
                DataObject ent = (DataObject) searchResults.get(i);
                DataObject id = ent.getDataObject(SchemaConstants.DO_IDENTIFIER);
                if (id != null) {
                    String uniqueName = id.getString(SchemaConstants.PROP_UNIQUE_NAME);
                    if (uniqueName != null) {
                        System.out.println("Found -> " + ent.getString("cn") + "(" + uniqueName + ")");
                    }
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
     }
    
    /**
     *  Method to search on 'postOfficeBox'
     *  @param service  */
    @SuppressWarnings("unchecked")
    private static void searchserver1PropName(Service service)
    {
        try
        {
            //Search
            DataObject root = SDOHelper.createRootDataObject();
            DataObject searchCtrl = SDOHelper.createControlDataObject(root, null,
                    SchemaConstants.DO_SEARCH_CONTROL);
            searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("uid");
            searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("sn");
            searchCtrl.getList(SchemaConstants.PROP_PROPERTIES).add("cn");
            searchCtrl.setString(SchemaConstants.PROP_SEARCH_EXPRESSION,
                    "@xsi:type='PersonAccount' and " + server1PropName + "='4-23'");
            root = service.search(root);
            System.out.println("Output datagraph -> " + printDO(root));
            List searchResults = root.getList(SchemaConstants.DO_ENTITIES);
            for (int i = 0; i
    < searchResults.size(); i++) {
                DataObject ent = (DataObject) searchResults.get(i);
                DataObject id = ent.getDataObject(SchemaConstants.DO_IDENTIFIER);
                if (id != null) {
                    String uniqueName = id.getString(SchemaConstants.PROP_UNIQUE_NAME);
                    if (uniqueName != null) {
                        System.out.println("Found -> " + ent.getString("cn") + "(" + uniqueName + ")");
                    }
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    


Results

If you set the useGlobalSchema property to use the global schema as described in step 5 of the Prerequisites section, then all of the properties extended on all instances can be used when performing search operations across domains. If you do not set the useGlobalSchema, then only the domain-specific schema is extended and search operations are based only on the properties extended in the current instance.

Parent topic: Sample code



+

Search Tips   |   Advanced Search