Solaris WBEM Developer's Guide

Chapter 4 Writing a Client Program

This chapter explains how to use the Solaris WBEM SDK client API (javax.wbem.client) to write client programs. This chapter includes the following topics:


Note –

For detailed information on the WBEM client APIs (javax.wbem.client), see file:/usr/sadm/lib/wbem/doc/index.html.


Client API Overview

WBEM client applications use the javax.wbem.client APIs to manipulate Common Information Model (CIM) objects. A client application uses the CIM API to construct an object and then to create an instance of that object. Examples of such an object include a class, an instance, or a name space. The application uses the client APIs to pass the object to the CIM Object Manager and request a WBEM operation. Examples of such an operation are creating a CIM class, creating an instance, or creating a name space.

Sequence of a Client Application

Client applications typically follow this sequence:

  1. Connect to the CIMOM using CIMClient. A client application connects to the CIMOM each time the client needs to perform a WBEM operation. These operations might include creating a CIM class and updating a CIM instance. See Opening and Closing a Client Connection.

  2. Use the client APIs to request operations and to perform programming tasks. The application's feature set determines which operations it needs to request. The tasks that most programs perform include:

    • Create, delete and update instances

    • Enumerate objects

    • Call methods

    • Retrieve class definitions

    • Handle errors

    Client programs can also create and delete classes, create and delete name spaces, and use qualifiers. See Performing Basic Client Operations.

  3. Close the client connection to the CIM Object Manager using CIMClient, to free the server resources used by the client session. See Opening and Closing a Client Connection.

Opening and Closing a Client Connection

A client application must first establish a connection with the CIMOM before the client can perform WBEM operations. These operations might include adding, modifying, or deleting a CIM class, CIM instance, or CIM qualifier type. The client application and CIM Object Manager can run on the same host or on different hosts. In addition, multiple clients can establish connections to the same CIM Object Manager.

About Name Spaces

When an application connects to the CIMOM, the application must also connect to a name space, where all subsequent operations occur. A name space is a directory-like structure that contains classes, instances, and qualifier types. The names of all objects within a name space must be unique. When you install the Solaris WBEM SDK, four name spaces are created:

Opening a Client Connection

To open a client connection, you use the CIMClient class to connect to the CIM Object Manager. The CIMClient class takes four arguments:


Example 4–1 Connecting to the Root Account

In this example, the application connects to the CIM Object Manager running on the local host in the default name space. The application creates a UserPrincipal object for the root account, which has read and write access to all CIM objects in the default name space.

{
   ...

   /* Create a name space object initialized with two null strings
   that specify the default host (the local host) and the default 
   name space (root\cimv2).*/
 
   CIMNameSpace cns = new CIMNameSpace("", "");

   UserPrincipal up = new UserPrincipal("root");
   PasswordCredential pc = new PasswordCredential("root-password"); 
   /* Connect to the name space as root with the root password. */
 
   CIMClient cc = new CIMClient(cns, up, pc);
   ...
}


Example 4–2 Connecting to a User Account

In this example, the application first creates an instance of a CIMNameSpace, UserPrincipal, and PasswordCredential object. Then, the application uses the CIMClient class to pass the host name, name space, user name, and password credential in order to create a connection to the CIMOM.

{
    ...
    /* Create a name space object initialized with A 
    (name of name space) on host happy.*/
    CIMNameSpace cns = new CIMNameSpace("happy", "A");
    UserPrincipal up = new UserPrincipal("Mary");
    PasswordCredential pc = new PasswordCredential("marys-password");
    CIMClient cc = new CIMClient(cns, up, pc);
    ...
} 


Example 4–3 Authenticating as an RBAC Role Identity

You use the SolarisUserPrincipal and SolarisPasswordCredential classes to authenticate a user's role identity. This example authenticates as Mary and assumes the role Admin.

{
...
CIMNameSpaceRole cns = new CIMNameSpace("happy", "A");
SolarisUserPrincipal sup = new SolarisUserRolePrincipal("Mary", "Admin");
SolarisPswdCredential spc = new
        SolarisPswdCredential("marys-password", "admins-password");
CIMClient cc = new CIMClient(cns, sup, spc);

Closing a Client Connection

Use the close method of the CIMClient class to close a client connection and free the server resources used by the session.


Example 4–4 Closing a Client Connection

This example closes a client connection. The instance variable cc represents the client connection.

...
cc.close();
...

Performing Basic Client Operations

This section describes how to use the javax.wbem.client APIs to request operations and to perform common programming tasks.

Creating an Instance

Use the newInstance method to create an instance of an existing class. If the existing class has a key property, the application must set the key property to a unique value. As an option, an instance can define additional qualifiers that are not defined for the class. These qualifiers can be defined for the instance or for a particular property of the instance. The qualifiers do not need to appear in the class declaration.

Applications can use the getQualifiers method to get the set of qualifiers that are defined for a class.


Example 4–5 Creating an Instance

This example uses the newInstance method to create a Java class representing a CIM instance, for example, a Solaris software package, from the Solaris_Package class.

...
{ 
/*Connect to the CIM Object Manager in the root\cimv2 
name space on the local host. Specify the username and password of an 
account that has write permission to the objects in the 
root\cimv2 name space. */
 
 UserPrincipal up = new UserPrincipal("root");
 PasswordCredential pc = new PasswordCredential("root-password"); 
 /* Connect to the name space as root with the root password. */
 
 CIMClient cc = new CIMClient(cns, up, pc);
 ...
 
 // Get the Solaris_Package class
 cimclass = cc.getClass(new CIMObjectPath("Solaris_Package"),  
                                          true, true, true, null);
 
 /* Create a new instance of the Solaris_Package 
 class populated with the default values for properties. If the provider
 for the class does not specify default values, the values of the 
 properties will be null and must be explicitly set. */
 
 CIMInstance ci = cc.createInstance (new CIMObjectPath("Solaris_Package"), 
 ci);
 }
 ... 

Deleting an Instance

Use the deleteInstance method to delete an instance.


Example 4–6 Deleting Instances

The example does the following:

 
import java.rmi.*;
import java.util.Enumeration;

import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import javax.wbem.cim.CIMInstance;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;

import javax.wbem.client.CIMClient;
import javax.wbem.client.PasswordCredential;
import javax.wbem.client.UserPrincipal;

/** 
 * Returns all instances of the specified class.
 * This example takes five arguments: hostname (args[0]), username
 * (args[1]), password (args[2]) name space (args[3] and classname (args[4])
 * It will delete all instances of the specified classname.  The specified 
 * username must have write permissions to the specified name space  
 */
public class DeleteInstances {
    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        // if not five arguments, show usage and exit
        if (args.length != 5) {
           System.out.println("Usage: DeleteInstances host username " +
                              "password namespace classname ");
           System.exit(1);
        }
        try {
            // args[0] contains the hostname and args[3] contains the 
            // name space.  We create a CIMNameSpace (cns) pointing to 
            // the specified name space on the specified host
            CIMNameSpace cns = new CIMNameSpace(args[0], args[3]);

            // args[1] and args[2] contain the username and password.
            // We create a UserPrincipal (up) using the username and
            // a PasswordCredential using the password.
            UserPrincipal up = new UserPrincipal(args[1]);
            PasswordCredential pc = new PasswordCredential(args[2]);

            // Connect to the CIM Object Manager and pass it the
            // CIMNameSpace, UserPrincipal and PasswordCredential objects
            // we created. 
            cc = new CIMClient(cns, up, pc);

            // Get the class name (args[4]) and create a CIMObjectPath
            CIMObjectPath cop = new CIMObjectPath(args[4]);

            // Get an enumeration of all the instance object paths of the
            // class and all subclasses of the class.  An instance object 
            // path is a reference used by the CIM object manager to 
            // locate the instance
            Enumeration e = cc.enumerateInstanceNames(cop);

            // Iterate through the instance object paths in the enumeration.
            // Construct an object to store the object path of each 
            // enumerated instance, print the instance and then delete it 
            while (e.hasMoreElements()) {
                CIMObjectPath  op = (CIMObjectPath)e.nextElement();
                System.out.println(op);
                cc.deleteInstance(op);
            } // end while 
        } catch (Exception e) {
        // if we have an exception, catch it and print it out.
        System.out.println("Exception: "+e);
        } // end catch

        // close session.
        if (cc != null) {
            cc.close();
        }
    }
}

Getting and Setting Instances

Client applications commonly use the getInstance method to retrieve CIM instances from the CIMOM. When an instance of a class is created, the class inherits the properties of all the parent classes in its class hierarchy. The getInstance method takes the Boolean argument localOnly.

Use the setInstance method to update an existing instance.


Example 4–7 Getting and Setting Instances

This example does the following:

...
{
    // Create an object path, an object that contains the CIM name for 
    // "myclass"
    CIMObjectPath cop = new CIMObjectPath("myclass"); 

    /* Get instances for each instance object path in an enumeration, 
    update the property value of b to 10 in each instance, and pass the 
    updated instance to the CIM Object Manager. */
    
    while(e.hasMoreElements()) {
        CIMInstance ci = cc.getInstance((CIMObjectPath)
                         (e.nextElement()),true, true, true, null);
        ci.setProperty("b", new CIMValue(new Integer(10)));
        cc.setInstance(new CIMObjectPath(),ci);
    }
}
...

Getting and Setting Properties

A CIM property is a value that describes the characteristic of a CIM class. Properties can be thought of as a pair of functions. One function gets the property value and one function sets the property value.


Example 4–8 Getting a Property

The following example uses enumerateInstanceNames to return the names of all instances of the Solaris platform processor. This example uses getProperty to get the value of the current clock speed for each instance, and println to print the current clockspeed values.

...
{
/* Create an object (CIMObjectPath) to store the name of the
Solaris_Processor class. */ 
 
CIMObjectPath cop = new CIMObjectPath("Solaris_Processor"); 
 
/* The CIM Object Manager returns an enumeration containing the names 
of instances of the Solaris_Processor class. */
 
Enumeration e = cc.enumerateInstanceNames(cop); 
 
/* Iterate through the enumeration of instance object paths.
Use the getProperty method to get the current clockspeed
value for each Solaris processor. */
 
while(e.hasMoreElements()) {
    CIMValue cv = cc.getProperty(e.nextElement(CIMObjectPath), 
                                         "CurrentClockSpeed");
    System.out.println(cv);
}
...
}
 


Example 4–9 Setting a Property

The following example sets the initial shell value for all Solaris_UserTemplate instances. This code segment uses enumerateInstanceNames to get the names of all instances of the Solaris_User Template. This code segment uses setProperty to set the value of the initial shell for each instance.

...
{
    /* Create an object (CIMObjectPath) to store the name of the
    Solaris_Processor class. */ 
 
    CIMObjectPath cop = new CIMObjectPath("Solaris_UserTemplate"); 
 
    /* The CIM Object Manager returns an enumeration containing the names 
    of instances of the Solaris_UserTemplate class and
    all its subclasses. */
 
    Enumeration e = cc.enumerateInstanceNames(cop); 
 
    /* Iterate through the enumeration of instance object paths.
    Use the setProperty method to set the initial shell
    value to /usr/bin/sh for each Solaris_UserTemplate instance. */
 
    for (; e.hasMoreElements(); cc.setProperty(e.nextElement(), 
         "/usr/bin/sh", new CIMValue(new Integer(500))));
}

Enumerating Objects

An enumeration is a collection of objects that can be retrieved one object at a time. You can enumerate classes, class names, instances, instance names, and name spaces. The results of an enumeration depend on the method and the arguments used, as shown in the following table.

Enumerating Objects

Table 4–1 Enumerating Objects

Method 

No args 

deep

localOnly

enumerateClasses

Returns the contents of the class specified in path.

If true: Returns the contents of the subclasses of the specified class, but does not return the class.

If true: Returns only noninherited properties and methods of the specified class.

   

If false: Returns the contents of the direct subclasses of the specified class.

If false: Returns all properties of the specified class.

enumerateInstances

Returns the instances of the class specified in path.

If true: Returns the instances of the specified class and its subclasseses.

If true: Returns only noninherited properties of the instances of the specified class.

   

If false: Returns the instances of the specified class and its subclasses. The properties of the subclasses are filtered out.

If false: Returns all properties of the instances of the specified class.

enumerateClassNames

Returns the names of the class specified in path.

If true: Returns the names of all classes derived from the specified class.

N/A 

   

If false: Returns only the names of the first-level children of the specified class.

N/A 

enumerateInstanceNames

Returns the names of the instances of the class specified in path.

N/A 

N/A 

       

enumNameSpace

Returns a list of the name spaces within the name space specified in path.

If true: Returns the entire hierarchy of name spaces under the specified name space.

N/A 

   

If false: Returns only the first level children of the specified name space.

N/A 


Example 4–10 Enumerating Classes

The following example program returns the contents of a class and its subclasses.

...
{
    /* Creates a CIMObjectPath object and initializes it 
    with the name of the CIM class to be enumerated (myclass). */
     
    CIMObjectPath cop = new CIMObjectPath(myclass); 
     
    /* This enumeration contains the classes and subclasses
    in the enumerated class (deep=true). This enumeration
    returns only the noninherited methods and properties 
    for each class and subclass (localOnly is true).*/
 
    Enumeration e = cc.enumerateClasses(cop, true, true);  
}
...


Example 4–11 Enumerating Classes and Instances

The following example program performs a deep and shallow (deep=false) enumeration of classes and instances. The localOnly flag returns the contents of the classes and instances instead of the names of the classes and instances.

import java.rmi.*;
import java.util.Enumeration;

import javax.wbem.client.CIMClient;
import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import javax.wbem.cim.CIMInstance;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;

import javax.wbem.client.UserPrincipal;
import javax.wbem.client.PasswordCredential;


/** 
 * This example enumerates classes and instances. It does deep and 
 * shallow enumerations on a class that is passed from the command line
 */
public class ClientEnum {

    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        CIMObjectPath cop = null;
        if (args.length < 4) {
            System.out.println("Usage: ClientEnum host user passwd " + 
                               "classname");
            System.exit(1);
        }
       try {
           CIMNameSpace cns = new CIMNameSpace(args[0]);
           UserPrincipal up = new UserPrincipal(args[1]);
           PasswordCredential pc = new PasswordCredential(args[2]);
           cc = new CIMClient(cns, up, pc);

           // Get the class name from the command line    
           cop = new CIMObjectPath(args[3]);    
           // Do a deep enumeration of the class
           Enumeration e = cc.enumerateClasses(cop, true, true, true, 
                                               true);
           // Will print out all the subclasses of the class.
           while (e.hasMoreElements()) {
               System.out.println(e.nextElement());
           }
           System.out.println("+++++");
           // Do a shallow enumeration of the class
           e = cc.enumerateClasses(cop, false, true, true, true);
           // Will print out the first-level subclasses.
           while (e.hasMoreElements()) {
               System.out.println(e.nextElement());
           }
           System.out.println("+++++");
           // Do a deep enumeration of the instances of the class
           e = cc.enumerateInstances(cop, false, true, true, true, null);
           // Will print out all the instances of the class and its 
           // subclasses.
           while (e.hasMoreElements()) {
               System.out.println(e.nextElement());
           }
           System.out.println("+++++");
           // Do a shallow enumeration of the instances of the class
           e = cc.enumerateInstances(cop, false, false, true, true, null);
           // Will print out all the instances of the class.
           while (e.hasMoreElements()) {
               System.out.println(e.nextElement());
           }
           System.out.println("+++++");
           e = cc.enumerateInstanceNames(cop);
           while (e.hasMoreElements()) {
               System.out.println(e.nextElement());
            }
           System.out.println("+++++");
           e = cc.enumerateInstanceNames(cop);
           while (e.hasMoreElements()) {
               CIMObjectPath opInstance = (CIMObjectPath)e.nextElement();
               CIMInstance ci = cc.getInstance(opInstance, false, 
                                                true, true, null);
               System.out.println(ci); 
           }
           System.out.println("+++++");
       }
       catch (Exception e) {
           System.out.println("Exception: "+e);
       }
       // close session.
       if (cc != null) {
           cc.close();
       }
    }
}


Example 4–12 Enumerating Class Names

The following example program returns a list of class names and subclass names.

...
{
    /* Creates a CIMObjectPath object and initializes it 
    with the name of the CIM class to be enumerated (myclass). */
    CIMObjectPath cop = new CIMObjectPath(myclass); 
    
    /* This enumeration contains the names of the classes and subclasses
    in the enumerated class. */
    Enumeration e = cc.enumerateClassNames(cop, true);
}
... 


Example 4–13 Enumerating Name Spaces

This example program uses the enumNameSpace method in the CIMClient class to print the name of the name space and all the name spaces contained within the name space.

 
import java.rmi.*;
import java.util.Enumeration;

import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import javax.wbem.cim.CIMInstance;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;

import javax.wbem.client.CIMClient;
import javax.wbem.client.PasswordCredential;
import javax.wbem.client.UserPrincipal;


/** 
 *
 */
public class EnumNameSpace {
    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        // if not four arguments, show usage and exit
        if (args.length < 4) {
            System.out.println("Usage: EnumNameSpace host username " +
                               "password namespace");
            System.exit(1);
        }
        try {
            // args[0] contains the hostname. We create a CIMNameSpace 
            // (cns) pointing to the specified name space on the 
            // specified host
            CIMNameSpace cns = new CIMNameSpace(args[0], "");

            // args[1] and args[2] contain the username and password.
            // We create a UserPrincipal (up) using the username and
            // a PasswordCredential using the password.
            UserPrincipal up = new UserPrincipal(args[1]);
            PasswordCredential pc = new PasswordCredential(args[2]);

            // Connect to the CIM Object Manager and pass it the
            // CIMNameSpace, UserPrincipal and PasswordCredential objects
            // we created. 
            cc = new CIMClient(cns, up, pc);

            // Use the name space (args[3]) to create a CIMObjectPath
            CIMObjectPath cop = new CIMObjectPath("", args[3]);

            // Enumerate the name space
            Enumeration e = cc.enumNameSpace(cop);
            while (e.hasMoreElements()) {
                System.out.println((CIMObjectPath)e.nextElement());
            } // end while 

        } catch (Exception e) {
              // is we have an exception, catch it and print it out.
              System.out.println("Exception: "+ e);
        } // end catch

        // close session.
        if (cc != null) {
            cc.close();
        }
    }
}

Creating Associations

An association describes a relationship between two or more managed resources such as a computer and its hard disk. This relationship is abstracted in an association class, which is a special type of class that contains an association qualifier. You can add or change an association class without affecting the actual objects.

Figure 4–1 TeacherStudent Association 1

Diagram shows that in TeacherStudent Association 1, the Teacher
Teaches the Student and that the Student is Taught By the Teacher.

The preceding figure shows two classes, Teacher and Student. Both classes are linked by the TeacherStudent association. The TeacherStudent association has two references:

About the Association Methods

The association methods in CIMClient return information about the relationships between classes and instances. These methods are described in the following table.

Table 4–2 Association Methods

Method 

Description 

associators

Gets the CIM classes or instances that are associated with the specified CIM class or instance 

associatorNames

Gets the names of the CIM classes or instances that are associated with the specified CIM class or instance 

references

Gets the association classes or instances that refer to the specified CIM class or instance, respectively 

referenceNames

Gets the names of the association classes or instances that refer to the specified CIM classes or instances, respectively 

These methods take a single required argument, CIMObjectPath. CIMObjectPath is the name of a source CIM class or CIM instance whose associations, associated classes, or instances you want to return. If the CIMOM does not find any associations, associated classes, or instances, the CIMOM does not return anything.

Figure 4–2 TeacherStudent Association 2

Diagram shows that Math Teacher and Art Teacher are subclasses
of Teacher, and that Teacher 1, Teacher 2, and Student 1 are class instances.

In the preceding figure, the associators and associatorNames methods return information about the classes associated with the Teacher and Student classes. The references and referenceNames methods return information about the associations between the Teacher and Student classes.

Table 4–3 TeacherStudent Methods

Example 

Output 

Description 

associators(Teacher, null, null, null, null, false, false, null)

Student class

Returns associated classes. Student is linked to Teacher by the TeacherStudentassociation

associators(MathTeacher, null, null, null, null,false, false, null)

Student

Returns associated classes. Teacher is linked to Student by the TeacherStudentassociation. MathTeacher and ArtTeacher inherit the TeacherStudentassociation from Teacher

associatorNames(Teacher, null, null, null, null)

Name of the Student class

Returns the names of the associated classes. Student is linked to Teacher by the TeacherStudent association

references(Student, null, null, false, false, null)

TeacherStudent

Returns the associations in which Student participates

references(Teacher, null, null, false, false, null)

TeacherStudent

Returns the associations in which Teacher participates

references(Teacher, null, null, false, false, null)

TeacherStudent

Returns the associations in which Teacher participates

referenceNames(Teacher, null, null)

Name of the TeacherStudent class

Returns the names of the associations in which Teacher participates

referenceNames(Teacher, null, null)

Name of the TeacherStudent class

Returns the names of the associations in which Teacher participates


Note –

The associatorNames and referenceNames methods do not take the arguments includeQualifiers, includeClassOrigin, and propertyList. These arguments are irrelevant to a method that returns only the names of instances or classes, not their entire contents.


Passing a Class to the Association Methods

To specify the name of a class, you specify its model path. The model path includes the class's name space, class name, and keys. A key is a property or set of properties that uniquely identify managed resource. Key properties are marked with the key qualifier. The following example shows a sample model path:

\\myserver\\root\cimv2\Solaris_ComputerSystem.Name=
mycomputer: CreationClassName=Solaris_ComputerSystem

This model path specifies the following values:

Passing Instances to the Association Methods

You use the enumerateInstances method to return all instances of a given class, and a loop structure to iterate through the instances. In the loop, you can pass each instance to an association method.


Example 4–14 Passing Instances

This example enumerates the instances in the op class and its subclasses. The example uses a while loop to cast each instance to a CIMObjectPath (op), and to pass each instance as the first argument to the associators method.

 {
    ...
    Enumeration e = cc.enumerateInstances(op, true);
    while (e.hasMoreElements()) {
        op = (CIMObjectPath)e.nextElement();
        Enumeration e1 = cc.associators(op, null, null, 
                null, null, false, false, null);
    ...
    }           

Using Optional Arguments With the Association Methods

You can use the optional arguments with the association methods to filter the classes and instances that are returned. Each optional parameter value passes its results to the next parameter for filtering until all parameters have been processed.

You can pass values for any one or a combination of the optional parameters. You must enter a value or null for each parameter. The first four parameters are used to filter the classes and instances that are returned:

Only the classes and instances that match the values specified for these parameters are returned. The includeQualifiers, includeClassOrigin, and propertyList parameters filter the information that is included in the classes and instances that are returned.

Calling Methods

You use the invokeMethod interface to call a method in a class supported by a provider. To retrieve the signature of a method, an application must first get the definition of the class to which the method belongs. The invokeMethod method returns a CIMValue. The return value is null when the method that you invoke does not define a return value.

The invokeMethod interface takes four arguments, as described in the following table.

Table 4–4 invokeMethod Parameters

Parameter 

Data Type 

Description 

name

CIMObjectPath 

The name of the instance on which the method must be invoked 

methodName

String 

The name of the method to call 

inParams

Vector 

Input parameters to pass to the method 

outParams

Vector 

Output parameters to get from the method 


Example 4–15 Calling a Method

This example gets the instances of the CIM_Service class, which represent services that manage device or software features. The example uses the invokeMethod method to stop each service.

{
    ...
    /* Pass the CIM Object Path of the CIM_Service class 
    to the CIM Object Manager. We want to invoke a method defined in
    this class. */ 
     
    CIMObjectPath op = new CIMObjectPath("CIM_Service"); 
     
    /* The CIM Object Manager returns an enumeration of instance
    object paths, the names of instances of the CIM_Service 
    class. */
     
    Enumeration e = cc.enumerateInstanceNames (op, true); 
     
    /* Iterate through the enumeration of instance object paths */
     
    while(e.hasMoreElements()) {
                // Get the instance
                CIMObjectPath op = (CIMObjectPath) e.nextElement();
                //Invoke the Stop Service method to stop the CIM services.
                cc.invokeMethod("StopService", null, null);
              }
}
 

Retrieving Class Definitions

The getClass method gets a CIM class. When a class is created, the class inherits the methods and properties of all parent classes in the class hierarchy. The getClass method takes the localOnly Boolean argument.


Example 4–16 Retrieving a Class Definition

This example uses the following methods to retrieve a class definition:

import java.rmi.*;
import javax.wbem.client.CIMClient;
import javax.wbem.cim.CIMInstance;
import javax.wbem.cim.CIMValue;
import javax.wbem.cim.CIMProperty;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;
import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import java.util.Enumeration;
/**
 * Gets the class specified in the command line. Works in the default
 * name space root\cimv2.
 */
public class GetClass {
    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        try {
           CIMNameSpace cns = new CIMNameSpace(args[0]);
           UserPrincipal up = new UserPrincipal("root");
           PasswordCredential pc = new PasswordCredential("root_password");
           cc = new CIMClient(cns);
           CIMObjectPath cop = new CIMObjectPath(args[1]);
           // Returns only the methods and properties that 
           // are local to the specified class (localOnly is true).
           cc.getClass(cop, true);
        } catch (Exception e) {
            System.out.println("Exception: "+e);
        }
        if(cc != null) {
            cc.close();
        }
    }
}

Handling Exceptions

Each CIMClient method throws a CIMException, or error condition. The CIMOM creates a hierarchy of WBEM-specific exceptions by using Java exception handling. The CIMException class is the base class for CIM exceptions. All other CIM exception classes extend from the CIMException class.

Each class of CIM exceptions defines a particular type of error condition that the API code handles. CIMException has methods to retrieve error codes and parameters that relate to the exception. Refer to file:/usr/sadm/lib/wbem/doc/index.html for more information on the CIMException class.

Creating a Name Space

The Solaris OS installation compiles the standard CIM Managed Object Format (MOF) files into the default name space. If you create a new name space, you must compile the appropriate CIM .mof files into the new name space before you create objects in that name space. For example, if you plan to create classes that use the standard CIM elements, compile the CIM Core schema into the name space. If you plan to create classes that extend the CIM Application schema, compile the CIM Application into the name space.


Example 4–17 Creating a Name Space

This example uses a two-step process to create a name space within an existing name space:

  1. When the name space is created, the CIMNameSpace method constructs a name space object that contains the parameters to be passed to the CIM Object Manager.

  2. The CIMClient class connects to the CIM Object Manager and passes the name space object. The CIM Object Manager creates the name space, using the parameters contained in the name space object.

{
    ...
    /* Creates a name space object on the client, which stores parameters 
    passed to it from the command line. args[0] contains the host 
    name (for example, myhost); args[1] contains the 
    parent name space (for example, the toplevel directory.) */
     
    CIMNameSpace cns = new CIMNameSpace (args[0], args[1]); 

    UserPrincipal up = new UserPrincipal("root");
    PasswordCredential pc = new PasswordCredential("root_password"); 
     
    /* Connects to the CIM Object Manager and passes it three parameters:
    the name space object (cns), which contains the host name (args[0]) and
    parent name space name (args[1]), a user name string (args[3]), and a
    password string (args[4]). */
     
    CIMClient cc = new CIMClient (cns, up, pc);
     
    /* Passes to the CIM Object Manager another name space object that 
    contains a null string (host name) and args[2], the name of a 
    child name space (for example, secondlevel). */
     
    CIMNameSpace cop = new CIMNameSpace("", args[2]);
    
    /* Creates a new name space by the name passed in as args[2] under the
    toplevel name space on myhost./*
     
    cc.createNameSpace(cop);
    ...
} 

Deleting a Name Space

Use the deleteNameSpace method to delete a name space.

Creating a Base Class


Note –

You can also create a base class using the MOF language. If you are familiar with MOF syntax, use a text editor to create a MOF file. Then use the MOF compiler to compile the file into Java classes. See Chapter 7, Creating JavaBeans Components Using the MOF Compiler.


Use the CIMClass class to create a Java class representing a CIM class. To declare the most basic class, you need only specify the class name and a key property or an abstract qualifier. However, most classes include properties that describe the data of the class. To declare a property, include the property's data type, name, and an optional default value. The property data type must be an instance of CIMDataType.

A property can have a key qualifier, which identifies the property as a key property. A key property uniquely defines the instances of the class. Only keyed classes can have instances. Therefore, if you do not define a key property in a class, the class can only be used as an abstract class. If you define a key property in a class in a new name space, you must first compile the core MOF files into the name space. The core MOF files contain the declarations of the standard CIM qualifiers, such as the key qualifier.

Class definitions can be more complicated, including such features as aliases, qualifiers, and qualifier flavors.

Deleting a Class

Use the CIMClient method, deleteClass, to delete a class. This method removes the class and throws a CIMException.


Note –

You must first remove any existing subclasses or instances before deleting a base class.



Example 4–18 Deleting a Class

This example uses the deleteClass method to delete a class in the default name space root\cimv2. This program takes four required string arguments:

The user running this program must specify the username and the password for an account, which has write permission to the root\cimv2 name space.

 
import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;
import javax.wbem.client.CIMClient;
import javax.wbem.client.UserPrincipal;
import javax.wbem.client.PasswordCredential;

import java.rmi.*;
import java.util.Enumeration;

/**
 * Deletes the class specified in the command line. Works in the default
 * name space root\cimv2.
 */
public class DeleteClass {
    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        // if not four arguments, show usage and exit
        if (args.length != 4) {
            System.out.println("Usage: DeleteClass host className " +
                              "username password"); 
            System.exit(1);
        }
        try {
            // args[0] contains the hostname. We create a CIMNameSpace
            // pointing to the default name space on the specified host
            CIMNameSpace cns = new CIMNameSpace(args[0]);

            // args[2] and args[3] contain the username and password.
            // We create a UserPrincipal (up) using the username and
            // a PasswordCredential using the password.
            UserPrincipal up = new UserPrincipal(args[2]);
            PasswordCredential pc = new PasswordCredential(args[3]);

            cc = new CIMClient(cns, up, pc);

            // Get the class name (args[4]) and create a CIMObjectPath
            CIMObjectPath cop = new CIMObjectPath(args[1]);
            // delete the class
            cc.deleteClass(cop);
        }
        catch (Exception e) {
            System.out.println("Exception: "+e);
        }
        if (cc != null) {
            cc.close();
        }
    }
}

Setting Access Control

You can set access control on a per-user basis or name space basis. The following access control classes are stored in the root\security name space:

You can set access control for individual users to CIM objects within a name space. Create an instance of the Solaris_UserACL class and then change the access rights for that instance. Similarly, you can set access control for a name space by creating an instance of the Solaris_NameSpaceACL class and then using the createInstance method to set the access rights for that instance.

Combine the use of these two classes by using the Solaris_NameSpaceACL class to first restrict access for all users to the objects in a name space. Then, you can use the Solaris_UserACL class to grant selected users access to the name space.

Solaris_UserAcl Class

The Solaris_UserAcl class extends the Solaris_Acl base class, from which it inherits the string property capability with a default value of r (read only). You can set the capability property to any one of the values for access privileges shown in the following table.

Access Right 

Description 

r

Read 

rw

Read and Write 

w

Write 

none 

No access 

The Solaris_UserAcl class defines the key properties that are shown in the following table. Only one instance of the name space and user name ACL pair can exist in a name space.

Property 

Data Type 

Purpose 

nspace

string

Identifies the name space to which the ACL applies

username

string

Identifies the user to which the ACL applies

ProcedureTo Set Access Control for a User

Steps
  1. Create an instance of the Solaris_UserAcl class.

    ...
    /* Create a name space object initialized with root\security
    (name of name space) on the local host. */
    
    CIMNameSpace cns = new CIMNameSpace("", "root\security");
    
    // Connect to the root\security name space as root. 
    cc = new CIMClient(cns, user, user_passwd);
    
    // Get the Solaris_UserAcl class 
    cimclass = cc.getClass(new CIMObjectPath("Solaris_UserAcl");
    
    // Create a new instance of the Solaris_UserAcl
    class ci = cimclass.newInstance();
    ...
  2. Set the capability property to the desired access rights.

    ...
    /* Change the access rights (capability) to read/write for user Guest
    on objects in the root\molly name space.*/
    ci.setProperty("capability", new CIMValue(new String("rw")); 
    ci.setProperty("nspace", new CIMValue(new String("root\molly")); 
    ci.setProperty("username", new CIMValue(new String("guest"));
    ...
  3. Update the instance.

    ...
    // Pass the updated instance to the CIM Object Manager 
    cc.createInstance(new CIMObjectPath(), ci);
    ...  

Solaris_NamespaceAcl Class

The Solaris_NamespaceAcl extends the Solaris_Acl base class and inherits the string property capability with a default value r (read-only for all users). The Solaris_NamespaceAcl class defines this key property.

Property 

Data Type 

Purpose 

nspace

string

Identifies the name space to which the access control list applies. Only one instance of the name space ACL can exist in a name space.

ProcedureTo Set Access Control for a Name Space

Steps
  1. Create an instance of the Solaris_namespaceAcl class.

    ...
    /* Create a name space object initialized with root\security  
    (name of name space) on the local host. */   
    CIMNameSpace cns = new CIMNameSpace("", "root\security"); 
    
    // Connect to the root\security name space as root. 
    cc = new CIMClient(cns, user, user_passwd);
    
    // Get the Solaris_namespaceAcl class 
    cimclass = cc.getClass(new CIMObjectPath("Solaris_namespaceAcl");
    
    // Create a new instance of the Solaris_namespaceAcl 
    class ci = cimclass.newInstance();
    ...
  2. Set the capability property to the desired access rights.

    ...
    /* Change the access rights (capability) to read/write 
    to the root\molly name space. */
    ci.setProperty("capability", new CIMValue(new String("rw")); 
    ci.setProperty("nspace", new CIMValue(new String("root\molly"));
    ...
  3. Update the instance.

    // Pass the updated instance to the CIM Object Manager 
    cc.createInstance(new CIMObjectPath(), ci);  

Working With Qualifiers and Qualifier Types

A CIM qualifier is an element that characterizes one of the following: CIM class, instance, property, method, or parameter. Qualifiers have the following attributes:

In MOF syntax, each CIM qualifier must have a CIM qualifier type defined. Qualifiers do not have a scope attribute, which indicates the CIM elements that can use the qualifier. You can only define scope in the qualifier type declaration. You cannot change scope in a qualifier.

The following sample code shows the MOF syntax for a CIM qualifier type declaration. This statement defines a Boolean qualifier type which is named key, whose default value is false. This qualifier can describe only a property and a reference to an object. The DisableOverride flavor means that key qualifiers cannot change their value.

Qualifier Key : boolean = false, Scope(property, reference), 
                    Flavor(DisableOverride);

The following sample code shows the MOF syntax for a CIM qualifier. In this sample MOF file, key and description are qualifiers for the property a. The property data type is an integer with the property name a.

{
[key, Description("test")]
int a;
};

Getting and Setting CIM Qualifiers

A qualifier flavor is a flag that governs the use of a qualifier. Flavors describe rules that specify whether a qualifier can be propagated to derived classes and instances. Rules also determine whether a derived class or instance can override the qualifier's original value.


Example 4–19 Setting CIM Qualifiers

This example sets a list of CIM qualifiers for a new class to the qualifiers in its superclass.

{

 try {
     cimSuperClass = cimClient.getClass(new CIMObjectPath(scName));
     Vector v = new Vector();
     for (Enumeration e = cimSuperClass.getQualifiers().elements();
                          e.hasMoreElements();) { 
         CIMQualifier qual = (CIMQualifier)
                             ((CIMQualifier)e.nextElement()).clone();
         v.addElement(qual);
     }
     cimClass.setQualifiers(v); 
 } catch (CIMException exc) {
      return;
 }
}
...

Batching Client Requests

You can batch multiple CIMClient API calls into a single remote call to reduce the delay introduced by multiple remote message exchanges. You use an instance of the BatchCIMClient class to build the list of operations that you want to execute in a batch request. Then use the performBatchOperations method of the CIMClient class to send the list of operations to the CIM Object Manager.


Note –

A batch operation does not imply a single transaction. Each operation is independent of the other operations in the batch. The operations have no dependencies on the success or failure of the preceding operations.


The BatchCIMClient class contains methods that enable you to perform the same CIM operations as in non-batch mode. These methods are similar to CIMClient methods except that the BatchCIMClient methods do not return the same types as their equivalents in the CIMClient class. The types are different because the values are returned as a list after the batch operation is complete. The methods return an integer operation ID that you can use to get the result of the operation later. As methods of BatchCIMClient are invoked, the BatchCIMClient object builds a list of CIMOperation objects that will be executed later.

The client executes the batch operation list by invoking the performBatchOperations method of CIMClient. The results of the batch operation are returned in a BatchResult object. Clients can then pass the operation ID to the getResult method of the BatchResult class to get the results of the operations. If an operation on the list generates an exception, an exception object is embedded in the BatchResult object. When you invoke the getResult method with the ID of the operation that failed, the exception is thrown by the getResult method.


Example 4–20 Batching Example

The following example shows how you can use the batching API to perform multiple operations in one remote call. In this example, three operations are performed as a single batch operation. The operations are enumerateInstanceNames, getClass, and enumerateInstances.

import java.util.Enumeration;
import java.util.ArrayList;
import java.util.Vector;
import java.lang.String;

import javax.wbem.cim.*;
import javax.wbem.client.*;
import javax.wbem.client.UserPrincipal;
import javax.wbem.client.PasswordCredential;


public class TestBatch {
    public static void main(String args[]) throws CIMException {
	       CIMClient cc = null;
	       CIMObjectPath cop = null;
	       String protocol = CIMClient.CIM_RMI;
	       if (args.length < 4) {
	           System.out.println("Usage: TestBatch host user passwd 
                                classname " + "[rmi|http]");
	           System.exit(1);
	       }
	       try {
	           CIMNameSpace cns = new CIMNameSpace(args[0]);

	           UserPrincipal up = new UserPrincipal(args[1]);
	           PasswordCredential pc = new PasswordCredential(args[2]);
	           if (args.length == 5 && args[4].equalsIgnoreCase("http")) {
	    	           protocol = CIMClient.CIM_XML;
	           }
	           cc = new CIMClient(cns, up, pc, protocol);

	           CIMObjectPath op = new CIMObjectPath(args[3]);

	           BatchCIMClient bc = new BatchCIMClient();
	           int[] ids = new int[3];

	           ids[0] = bc.enumerateInstanceNames(op);
	           ids[1] = bc.getClass(op, false, true, true, null);
	           ids[2] = bc.enumerateInstances(op, true, false, false, 
                                           false, null);

	           BatchResult br = cc.performBatchOperations(bc);

             Enumeration instanceNames = (Enumeration)br.getResult
                                        (ids[0]);
	           CIMClass cl = (CIMClass)br.getResult(ids[1]);
	           Enumeration instances = (Enumeration)br.getResult(ids[2]);

	           while (instanceNames.hasMoreElements()) {
	               System.out.println((CIMObjectPath)instanceNames.
                                    nextElement());
	           }

	           System.out.println(cl.toMOF());

	           while (instances.hasMoreElements()) {
	               System.out.println((CIMInstance)instances.
                                    nextElement());
	           }

	      }
	      catch (Exception e) {
	          e.printStackTrace();
	          System.out.println("Exception: "+e);
	      }

	      // close session.
	      if (cc != null) {
	          cc.close();
	      }
    }
}

Handling CIM Events


Note –

For in-depth information on CIM indications and how indications are used to communicate occurrences of events, see the Distributed Management Task Force (DMTF) Event white paper at http://www.dmtf.org/education/whitepapers.php.


An event is a real world occurrence. An indication is an object that communicates the occurrence of an event. In the Common Information Model, indications are published, not events. Providers generate an indication when an event takes place.

An indication may have zero or more triggers, which are recognitions of changes in state. WBEM does not have an explicit object representing a trigger. Instead, a trigger is implied by the following actions:

For example, when a trigger is engaged due to service termination, this event results in an indication that serves as notification that the service has terminated.

You can view the related CIM event classes in the Solaris WBEM Services schema at file:/usr/sadm/lib/wbem/doc/mofhtml/index.html. The class is structured as shown in the following table.

Table 4–5 CIM_Indication Class Structure

Root Class 

Superclass 

Subclass 

CIM_Indication

CIM_ClassIndication

CIM_ClassCreation, CIM_ClassDeletion, CIM_ClassModification

 

CIM_InstIndication

CIM_InstCreation, CIM_InstDeletion, CIM_InstMethodCall, CIM_InstModification, CIM_InstRead

 

CIM_ProcessIndication

CIM_AlertIndication, CIM_AlertInstIndication, CIM_ThresholdIndication, CIM_SNMPTrapIndication

About Indications

CIM events can be classified as either life cycle or process. A life cycle event is a built-in CIM event that occurs in response to a change to a particular change in data. The types of changes that trigger a life cycle event are:

A process event is a user-defined event that is not described by a life cycle event.

Event providers generate indications in response to requests made by the CIMOM. The CIMOM analyzes subscription requests. The CIMOM uses the EventProvider or the CIMIndicationProvider interface to contact the provider, requesting the provider to generate the appropriate indications. When the provider generates the indication, the CIMOM routes the indication to the destinations specified by the CIM_IndicationHandler instances. These instances are created by the subscribers.

Event providers are located in the same manner as instance providers. There is a sequence of steps that the CIMOM follows in the case of subscriptions pertaining to instance life cycle indication, such as subclasses of CIM_InstIndication. Once the CIMOM determines the classes covered by the subscription, the CIMOM contacts the instance providers for those classes. For process indications, the CIMOM contacts the appropriate provider using the Provider qualifier.

The CIM Object Manager and the CIM Object Manager Repository handle indications under the following circumstances:

In these cases, the provider does not generate indications or implement the EventProvider interface. In addition, the provider can delegate event generation responsibilities to the CIM Object Manager. The CIM Object Manager invokes enumerateInstances on the providers. The CIMOM compares snapshots of previous states to current states to determine whether instances have been created, modified, or deleted.


Note –

In most cases, providers should handle their own indications because polling carries a high overhead. In order to generate indications, the provider must poll. In this case, the provider can delegate the task to the CIMOM.


If a provider implements the EventProvider interface, the CIMOM invokes the methods in the interface and takes actions according to the responses. When the CIMOM determines that a particular provider must participate in a subscription request, the methods are invoked in the following order:

  1. mustPoll– Invoked by the CIM Object Manager for CIM_InstCreation, CIM_InstDeletion, and CIM_InstModification to determine whether the provider wants the CIM Object Manager to poll. If the provider does not implement the EventProvider interface, the CIM Object Manager assumes polling by default.

  2. authorizeFilter– If the provider implements the Authorizable interface, this method is invoked by the CIMOM to determine whether the subscription is authorized. The provider can make the determination based on either the user ID of: the owner of the indication handler, which is the user who receives the indications, or the user who created the subscription.

    If the provider does not implement the Authorizable interface, the CIM Object Manager performs the default read authorization check for the name space.

    If the provider does not implement the EventProvider interface and the CIMOM tries to poll, the authorization succeeds if enumerateInstances succeeds on the provider.

  3. activateFilter– Invoked by the CIMOM when the authorization succeeds and the provider does not want to be polled.

  4. deActivateFilter– Called when a subscription is removed either by the subscriber or the CIMOM. For example, if the destination handler malfunctions.

About Subscriptions

A client application can subscribe to be notified of CIM events. A subscription is a declaration of interest in one or more streams of indications. Currently, providers cannot subscribe for event indications.

An application that subscribes for indications of CIM events provides the following information:

The occurrence of an event is represented as an instance of one of the subclasses of the CIM_Indication class. An indication is generated only when a client subscribes to the event.

ProcedureTo Create a Subscription

An application can create one or more event filters with one or more event handlers. Event indications are not delivered until the application creates the event subscription.

Steps
  1. Create an instance of CIM_Listener. See Adding a CIM Listener.

  2. Create an instance of CIM_IndicationFilter. See Creating an Event Filter.

  3. Create an instance of CIM_IndicationHandler. See Creating an Event Handler.

  4. Bind the CIM_IndicationFilter to the CIM_IndicationHandler. See Binding an Event Filter to an Event Handler.

Adding a CIM Listener

To receive indications of CIM events, first add an instance of CIMListener to CIMClient, by invoking the addCIMListener method on CIMClient.


Note –

The CIMListener interface must implement the indicationOccured method, which takes the argument CIMEvent. This method is invoked when an indication is available for delivery.



Example 4–21 Adding a CIM Listener

// Connect to the CIM Object Manager
cc = new CIMClient();

// Register the CIM Listener
cc.addCIMListener(
new CIMListener() {
    public void indicationOccured(CIMEvent e) {
    }
});

Creating an Event Filter

Event filters describe the types of events to be delivered and the conditions under which they are delivered. To create an event filter, create an instance of the CIM_IndicationFilter class and define values for its properties. Each event filter works only on events that belong to the name space to which the filter belongs.

The CIM_IndicationFilter class has string properties. These properties can be set to uniquely identify the filter, specify a query string, and specify the query language that parses the query string. Currently, only the WBEM Query Language (WQL) is supported.

Table 4–6 CIM_IndicationFilter Properties

Property 

Description 

Required/Optional 

SystemCreationClassName

The name of the system on which the creation class for the filter resides or to which it applies. 

Optional. The value is decided by the CIM Object Manager. 

SystemName

The name of the system on which the filter resides or to which it applies. 

Optional. The default for this key property is the name of the system on which the CIM Object Manager is running. 

CreationClassName

The name of the class or subclass used to create the filter.  

Optional. The CIM Object Manager assigns CIM_IndicationFilteras the default for this key property.

Name

The unique name of the filter. 

Optional. The CIM Object Manager assigns a unique name. 

SourceNamespace

The path to a local name space where the CIM indications originate. 

Optional. The default is null. 

Query

A query expression that defines the conditions under which indications are generated. Currently, only Level 1 WBEM Query Language (WQL) expressions are supported. To learn more about WQL query expressions, see Chapter 5, Writing WBEM Queries.

Required. 

QueryLanguage

The language in which the query is expressed. 

Required. The default is WQL (WBEM Query Language). 

ProcedureTo Create an Event Filter

Steps
  1. Create an instance of the CIM_IndicationFilter class

    CIMClass cimfilter = cc.getClass
            (new CIMObjectPath "CIM_IndicationFilter"),
             true, true, true, null);
    CIMInstance ci = cimfilter.newInstance();
  2. Specify the name of the event filter

    Name = "filter_all_new_solarisdiskdrive"
  3. Create a WQL string identifying event indications to return

    String filterString = "SELECT * 
            FROM CIM_InstCreation WHERE sourceInstance 
            ISA Solaris_DiskDrive";
  4. Set property values in the cimfilter instance to identify the following information:

    • Name of the filter

    • Filter string to select CIM events

    • Query language (WQL) to parse the query string

    ci.setProperty("Name", new 
            CIMValue("filter_all_new_solarisdiskdrives"));
    ci.setProperty("Query", new CIMValue(filterString));
    ci.setProperty("QueryLanguage", new CIMValue("WQL");)
  5. Create a cimfilter instance that is called filter. Store the instance in the CIM Object Manager Repository

    CIMObjectPath filter = 
                             cc.createInstance(new CIMObjectPath(), 
                                                               ci);

Example 4–22 Creating an Event Filter

CIMClass cimfilter = cc.getClass(new CIMObjectPath
                                ("CIM_IndicationFilter"), true);
CIMInstance ci = cimfilter.newInstance();
//Assuming that the test_a class exists in the name space
String filterString = "select * from CIM_InstCreation where 
                       sourceInstance isa test_a"

ci.setProperty("query", new CIMValue(filterString));
CIMObjectPath filter = cc.createInstance(newCIMObjectPath(), ci);

Creating an Event Handler

An event handler is an instance of a CIM_IndicationHandler class. You set the properties in an instance of the CIM_IndicationHandler class to uniquely name the handler and to identify the UID of its owner. The CIM Event MOF defines a CIM_IndicationHandlerCIMXML class for describing the destination for indications to be delivered to client applications that use the HTTP protocol. The Solaris_Event.mof extends the CIM_IndicationHandler class by creating the Solaris_JAVAXRMIDelivery class. This subclass handles delivery of indications of CIM events to client applications that use the RMI protocol. RMI clients must instantiate the Solaris_JAVAXRMIDelivery class to set up an RMI delivery location.

Table 4–7 CIM_IndicationHandler Properties

Property 

Description 

Required or Optional 

SystemCreationClassName

The name of the system on which the creation class for the handler resides or to which it applies. 

Optional. Completed by the CIM Object Manager. 

SystemName

The name of the system on which the handler resides or to which it applies. 

Optional. The default value for this key property is the name of the system on which the CIM Object Manager is running. 

CreationClassName

The class or subclass used to create the handler. 

Optional. The CIM Object Manager assigns the appropriate class name as the default for this key property. 

Name

The unique name of the handler. 

Optional. The client application must assign a unique name. 

Owner

The name of the entity that created or maintains this handler. The provider can check this value to determine whether to authorize a handler to receive an indication. 

Optional. The default value is the Solaris OS user name of the user who creates the instance. 


Example 4–23 Creating an Event Handler

// Create an instance of the Solaris_JAVAXRMIDelivery class or get
// the appropriate instance of the handler.
CIMInstance ci = cc.getIndicationHandler(null);

//Create a new instance (delivery) from
//the rmidelivery instance.
CIMObjectPath delivery = cc.createInstance(new CIMObjectPath(), ci);

Binding an Event Filter to an Event Handler

You bind an event filter to an event handler by creating an instance of the CIM_IndicationSubscription class. When you create an indication of this class, indications for the events specified by the event filter are delivered.

The following example creates a subscription (filterdelivery) and defines the filter property to the filter object path created in To Create an Event Filter. The example also defines the handler property to the delivery object path that is created in Example 4–23.


Example 4–24 Binding an Event Filter to an Event Handler

CIMClass filterdelivery = cc.getClass(new 
        CIMObjectPath("CIM_IndicationSubscription"), 
        true, true, true, null);
ci = filterdelivery.newInstance():

//Create a property called filter that refers to the filter instance.
ci.setProperty("filter", new CIMValue(filter));

//Create a property called handler that refers to the delivery instance.
ci.setProperty("handler", new CIMValue(delivery));

CIMObjectPath indsub = cc.createInstance(new CIMObjectPath(), ci);

Reading and Writing Log Messages

The Solaris platform MOF files include logging classes. Clients can create and read log records using these classes to record errors, warnings, and informational messages. For example, a log message can indicate one of the following conditions:

The underlying providers for the logging classes can forward logging requests to the syslog daemon, the default logging system in the Solaris OS. See thesyslogd(1M) man page for more information.

About Log Files

WBEM log messages are stored in individual log files in the /var/sadm/wbem/log directory. Properties that you manipulate with the singleton instance of the Solaris_LogServiceProperties class:

The format of each log entry is defined by the Solaris_LogEntry class, which is a subclass of CIM_LogRecord. You can find Solaris_LogEntry in Solaris_Device.mof, and CIM_LogRecord in CIM_Device26.mof.

A log message includes the following elements:

Table 4–8 Log Message Elements

Element 

Description 

Category

Type of message – application, system, or security 

Severity

Severity of the condition – warning or error 

Application

Name of the application or the provider that is writing the log message 

User

Name of the user who was using the application when the log message was generated 

Client Machine

Name and IP address of the system that the user was on when the log message was generated 

Server Machine

Name of the system on which the incident that generated the log message occurred 

Summary Message

Descriptive summary of the incident 

Detailed Message

Detailed description of the incident 

Data

Contextual information that provides a better understanding of the incident 

SyslogFlag

Boolean flag that specifies whether to send the message to syslogd(1M)

The following examples show how to create a log and how to display the contents of a log.


Example 4–25 Creating an Instance of Solaris_LogEntry

This example creates an instance of Solaris_LogEntry and sets the instance.

public class CreateLog {
    public static void main(String args[]) throws CIMException {

        // Display usage statement if insufficient command line
        // arguments are passed.
        if (args.length < 3) {
            System.out.println("Usage: CreateLog host username password 
                               " + "[rmi|http]"); 
            System.exit(1);
        }

        String protocol = CIMClient.CIM_RMI;
        CIMClient cc = null;
        CIMObjectPath cop = null;
        BufferedReader d = new BufferedReader(new InputStreamReader
                                             (System.in));

        String input_line = "";

        // Query user for number of records that need to be created.
        System.out.print("How many log records do you want to write? ");
        int num_recs = 0;

        try {
                num_recs = Integer.parseInt(d.readLine());
        } catch (Exception ex) {
                ex.printStackTrace();
                System.exit(1);
        }

        // Over-arching try-catch block
        try {
            CIMNameSpace cns = new CIMNameSpace(args[0]);
            UserPrincipal up = new UserPrincipal(args[1]);
            PasswordCredential pc = new PasswordCredential(args[2]);

            // Set up the transport protocol - set by default to RMI.
            if (args.length == 4 && args[3].equalsIgnoreCase("http")) {
                protocol = CIMClient.CIM_XML;
            }

            cc = new CIMClient(cns, up, pc, protocol);

                Vector keys = new Vector();
                CIMProperty logsvcKey = null;


                // Prompt user for relevant info needed to create the
                // log record.

                System.out.println("Please enter the record Category: ");
                System.out.println("\t(0)application, (1)security, 
                                                      (2)system");
                logsvcKey = new CIMProperty("category");
                input_line = d.readLine();
                logsvcKey.setValue(new CIMValue(Integer.valueOf
                                               (input_line)));
                keys.addElement(logsvcKey);
                System.out.println("Please enter the record Severity:");
                System.out.println("\t(0)Informational, (1)Warning, 
                                                        (2)Error");
                logsvcKey = new CIMProperty("severity");
                input_line = d.readLine();
                logsvcKey.setValue(new CIMValue(Integer.valueOf
                                  (input_line)));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("Source");
                System.out.println("Please enter Application Name:");
                logsvcKey.setValue(new CIMValue(d.readLine()));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("SummaryMessage");
                System.out.println("Please enter a summary message:");
                logsvcKey.setValue(new CIMValue(d.readLine()));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("DetailedMessage");
                System.out.println("Please enter a detailed message:");
                logsvcKey.setValue(new CIMValue(d.readLine()));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("RecordData");
                logsvcKey.setValue(
                        new CIMValue("0xfe 0x45 0xae 0xda random data"));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("SyslogFlag");
                logsvcKey.setValue(new CIMValue(new Boolean(true)));
                keys.addElement(logsvcKey);
                CIMObjectPath logreccop = 
                        new CIMObjectPath("Solaris_LogEntry", keys);
                CIMClass logClass = cc.getClass(logreccop);
                CIMInstance ci = logClass.newInstance();
                ci.setClassName("Solaris_LogEntry");
                ci.setProperties(keys);
                // System.out.println(ci.toString());

                // Create as many instances of the record as requested.
                for (int i = 0; i < num_recs; i++) {
                        cc.createInstance(logreccop, ci);
                }
        } catch (Exception e) {
            System.out.println("Exception: "+e);
                e.printStackTrace();
        }

        // close session.
        if (cc != null) {
            cc.close();
        }
    }
}


Example 4–26 Displaying a List of Log Records

This example displays a list of log records.

 public class ReadLog {
    public static void main(String args[]) throws CIMException {

        String protocol = CIMClient.CIM_RMI;

        // Display usage statement if insufficient command line
        // arguments are passed.
        if (args.length < 3) {
            System.out.println("Usage: ReadLog host username password " +
                               "[rmi|http]"); 
            System.exit(1);
        }

        CIMClient cc = null;
        CIMObjectPath cop = null;
        CIMObjectPath serviceObjPath = null;
        Vector inVec = new Vector();
        Vector outVec = new Vector();

        // Over-arching try-catch block
        try {
            CIMNameSpace cns = new CIMNameSpace(args[0]);
            UserPrincipal up = new UserPrincipal(args[1]);
            PasswordCredential pc = new PasswordCredential(args[2]);

            // Set up the transport protocol - set by default to RMI.
            if (args.length == 4 && args[3].equalsIgnoreCase("http")) {
                protocol = CIMClient.CIM_XML;
            }

            cc = new CIMClient(cns, up, pc, protocol);

            cop = new CIMObjectPath("Solaris_LogEntry");

            // Enumerate the list of instances of class Solaris_LogEntry
            Enumeration e = cc.enumerateInstances(cop, true, false,
                                                false, false, null);

            // iterate over the list and print out each property.
            for (; e.hasMoreElements(); ) {
                System.out.println("---------------------------------");
                CIMInstance ci = (CIMInstance)e.nextElement();
                System.out.println("Log filename : " + 
                    ((String)ci.getProperty("LogName").getValue().
                                                       getValue()));
                int categ = 
    (((Integer)ci.getProperty("Category").getValue().getValue()).
       intValue());
                if (categ == 0)
                    System.out.println("Category : Application Log");
                else if (categ == 1)
                    System.out.println("Category : Security Log");
                else if (categ == 2)
                    System.out.println("Category : System Log");
                int severity = 
    (((Integer)ci.getProperty("Severity").getValue().getValue()).
       intValue());
                if (severity == 0)
                    System.out.println("Severity : Informational");
                else if (severity == 1)
                    System.out.println("Severity : Warning Log!");
                else if (severity == 2)
                    System.out.println("Severity : Error!!");
                System.out.println("Log Record written by :" + 
    ((String)ci.getProperty("Source").getValue().getValue()));
                System.out.println("User : " + 
    ((String)ci.getProperty("UserName").getValue().getValue()));
                System.out.println("Client Machine : " + 
    ((String)ci.getProperty("ClientMachineName").getValue().getValue()));
                System.out.println("Server Machine : " + 
    ((String)ci.getProperty("ServerMachineName").getValue().getValue()));
                System.out.println("Summary Message : " + 
    ((String)ci.getProperty("SummaryMessage").getValue().getValue()));
                System.out.println("Detailed Message : " + 
    ((String)ci.getProperty("DetailedMessage").getValue().getValue()));
                System.out.println("Additional data : " + 
    ((String)ci.getProperty("RecordData").getValue().getValue()));
                boolean syslogflag =
    ((Boolean)ci.getProperty("SyslogFlag").getValue().getValue()).
booleanValue();
                if (syslogflag == true) {
                    System.out.println("Record was written to syslog");
                } else {
                    System.out.println("Record was not written to syslog");
                }
                System.out.println("---------------------------------");
            }
        } catch (Exception e) {
            System.out.println("Exception: "+e);
            e.printStackTrace();
        }

        // close session.
        if (cc != null) {
            cc.close();
        }
    }
}