This chapter explains how to use the Solaris WBEM SDK client APIs (javax.wbem.client) to write client programs, and includes the following topics:
For detailed information on the WBEM client APIs (javax.wbem.client), see file:/usr/sadm/lib/wbem/doc/index.html.
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 (for example, a class, instance, or namespace) and then initializes, or instantiates, that object. The application uses the client APIs to pass the object to the CIM Object Manager and request a WBEM operation, such as creating a CIM class, instance, or namespace.
Client applications typically follow this sequence:
Connect to the CIM Object Manager using CIMClient. A client application connects to the CIM Object Manager each time it needs to perform a WBEM operation, such as creating a CIM class or updating a CIM instance. See “Opening and Closing a Client Connection”.
Use the client APIs to request operations and perform programming tasks. The application's feature set determines which operations it needs to request. The tasks that most programs perform include creating, deleting and updating instances; enumerating objects; calling methods; retrieving class definitions; and handling errors. Client programs can also create and delete classes, and create and delete namespaces, and use qualifiers. See “Performing Basic Client Operations”.
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”.
A client application must first establish a connection with the CIM Object Manager before it can perform WBEM operations such as 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.
When an application connects to the CIM Object Manager, it must also connect to a namespace, where all subsequent operations occur. A namespace is a directory-like structure that contains classes, instances, and qualifier types. The names of all objects within a namespace must be unique. When you install the Solaris WBEM SDK, four namespaces are created:
root\cimv2 – The default namespace. Contains the CIM classes that represent objects on the system on which Solaris WBEM Services is installed.
root\snmp– Contains the SNMP adapter classes.
root\system– Contains the classes that manage the CIM Object Manager.
To open a client connection, you use the CIMClient class to connect to the CIM Object Manager. The CIMClient class takes four arguments:
name – Required. An instance of a CIMNameSpace object that contains the name of the host and the namespace used for the client connection. The default is root\cimv2 on the local host (the local host is the same host in which the client application is running). Once connected to the CIM Object Manager, all subsequent CIMClient operations occur within the specified namespace.
principal – Required. An instance of a UserPrincipal object that contains the name of a valid Solaris user account. The CIM Object Manager checks the access privileges for the user name to determine the type of access allowed to CIM objects.
credential – Required. An instance of a PasswordCredential object that contains a valid password for the UserPrincipal Solaris account.
protocol – Optional (string). Protocol used for sending messages to the CIM Object Manager; either RMI (the default), or HTTP.
In this example, the application connects to the CIM Object Manager running on the local host in the default namespace. The application creates a UserPrincipal object for the root account, which has read and write access to all CIM objects in the default namespace.
{ ... /* Create a namespace object initialized with two null strings that specify the default host (the local host) and the default namespace (root\cimv2).*/ CIMNameSpace cns = new CIMNameSpace("", ""); UserPrincipal up = new UserPrincipal("root"); PasswordCredential pc = new PasswordCredential("root_password"); /* Connect to the namespace as root with the root password. */ CIMClient cc = new CIMClient(cns, up, pc); ... }
In this example, the application first creates an instance of a CIMNameSpace, UserPrincipal, and PasswordCredential object. Then, the application uses the CIMClient class to connect to the CIM Object Manager and pass the host name, namespace , user name, and password credential to the CIM Object Manager.
{ ... /* Create a namespace object initialized with A (name of namespace) 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); ... ... }
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);
Use the close method of the CIMClient class to close a client connection and free the server resources used by the session.
This example closes a client connection. The instance variable cc represents the client connection.
... cc.close(); ...
This section describes how to use the the javax.wbem.client APIs to request operations and perform common programming tasks.
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 and do not need to appear in the class declaration.
Applications can use the getQualifiers method to get the set of qualifiers defined for a class.
This example uses the newInstance method to create a Java class representing a CIM instance, for example, a Solaris package, from the Solaris_Package class.
... { /*Connect to the CIM Object Manager in the root\cimv2 namespace on the local host. Specify the username and password of an account that has write permission to the objects in the root\cimv2 namespace. */ UserPrincipal up = new UserPrincipal("root"); PasswordCredential pc = new PasswordCredential("root_password"); /* Connect to the namespace 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); } ...
Use the deleteInstance method to delete an instance.
The following example connects the client application to the CIM Object Manager, uses CIMObjectPath to construct an object containing the CIM object path of the object to be deleted, enumerateInstance to get the instance and all instances of its subclasses, and deleteInstance to delete each instance.
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]) namespace (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 namespace */ 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 // namespace. We create a CIMNameSpace (cns) pointing to // the specified namespace 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) { // 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(); } } }
Client applications commonly use the getInstance method to retrieve CIM instances from the CIM Object Manager. When an instance of a class is created, it inherits the properties of the class it is derived from and all parent classes in its class hierarchy. The getInstance method takes the Boolean argument localOnly.
If localOnly is true, getInstance returns only the non-inherited properties in the specified instance. The non-inherited properties are those defined in the instance itself.
If localOnly is false, all properties in the class are returned; those defined in the instance, and all properties inherited from all parent classes in its class hierarchy.
Use the setInstance method to update an existing instance.
The following example gets instances of an object path in an enumeration, updates the property value of b to 10 in each instance, and passes the updated instances to the CIM Object Manager.
... { // 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); } } ...
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 that gets the property value and one that sets the property value.
The following example uses enumerateInstanceNames to return the names of all instances of the Solaris processor, getProperty to get the value of the current clockspeed 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); } ... }
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, and 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)))); ... }
An enumeration is a collection of objects that can be retrieved one at a time. You can enumerate classes, class names, instances, instance names, and namespaces. The results of an enumeration depend on the method and the arguments used, as shown in the following table.
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 itself. |
If true: Returns only non-inherited 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 non-inherited 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 |
N/A |
N/A |
||
enumNameSpace |
Returns a list of the namespaces within the namespace specified in path |
If true: Returns the entire hierarchy of namespaces under the specified namespace. |
N/A |
If false: Returns only the first level children of the specified namespace. |
N/A |
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 non-inherited methods and properties for each class and subclass (localOnly is true).*/ Enumeration e = cc.enumerateClasses(cop, true, true); } ...
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(); } } }
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); } ...
This example program uses the enumNameSpace method in the CIMClient class to print the names of the namespace and all the namespaces contained within the namespace.
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 namespace 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 namespace (args[3]) to create a CIMObjectPath CIMObjectPath cop = new CIMObjectPath("", args[3]); // Enumerate the namespace 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(); } } }
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 objects themselves.
Figure 3–1 shows two classes, Teacher and Student. Both classes are linked by the TeacherStudent association. The TeacherStudent association has two references:
Teaches, a property that refers to an instance of the Teacher class
TaughtBy, a property that refers to an instance of the Student class
The association methods in CIMClient return information about the relationships between classes and instances. These methods are described in the following table.
Table 3-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 one required argument, CIMObjectPath, which is the name of a source CIM class or CIM instance whose associations, associated classes, or instances you want to return. If the CIM Object Manager does not find any associations, associated classes, or instances, it does not return anything.
If CIMObjectpath is a class, the methods return the associated classes and the subclasses of each associated class.
If CIMObjectpath is an instance, the methods return the instances of the associated class and the subclasses of each associated class.
In Figure 3–2, 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 3-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 TeacherStudent association. |
associators(MathTeacher, null, null, null, null,,false, false, null) |
Student |
Returns associated classes. Teacher is linked to Student by the TeacherStudent association. MathTeacher and ArtTeacher inherit the TeacherStudent association 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 TeacherStudentassociation. |
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) |
The name of the TeacherStudent class. |
Returns the names of the associations in which Teacher participates. |
referenceNames(Teacher, null, null) |
The name of the TeacherStudent class. |
Returns the names of the associations in which Teacher participates. |
The associatorNames and referenceNames methods do not take the arguments includeQualifiers, includeClassOrigin, and propertyList because these arguments are irrelevant to a method that returns only the names of instances or classes, not their entire contents.
To specify the name of a class, you specify its model path. The model path includes the class's namespace, 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. This model path:
\\myserver\\root\cimv2\Solaris_ComputerSystem.Name= mycomputer: CreationClassName=Solaris_ComputerSystem
Specifies the following:
\\myserver\root\cimv2 is the default CIM namespace on host myserver.
Solaris_ComputerSystem is the name of the class from which the instance is derived.
Name=mycomputer, CreationClassName=Solaris_ComputerSystem are two key properties in the format key property=value.
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.
This example enumerates the instances in the op class and its subclasses, uses a while loop to cast each instance to a CIMObjectPath (op), and passes 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); ... }
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 assocClass, resultClass, role, and resultRole parameters 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 are included in the classes and instances that are returned.
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 you invoke does not define a return value.
The invokeMethod interface takes four arguments, as described in the following table.
Table 3-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 |
This example gets the instances of the CIM_Service class (services that manage device or software features) and 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); } }
The getClass method gets a CIM class. When a class is created, it inherits the methods and properties of the class from which it is derived, and all parent classes in the class hierarchy. The getClass method takes the localOnly Boolean argument.
If localOnly is true, getClass returns only non-inherited properties and methods.
If localOnly is false, getClass returns all properties in the class.
This example uses the following methods to retrieve a class definition:
CIMNameSpace – Create a new namespace
CIMClient – Create a new client connection to the CIM Object Manager
CIMObjectPath – Create an object path, which is an object to contain the name of the class to retrieve
getClass – Retrieve the class from the CIM Object Manager
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 * namespace 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(); } } }
Each CIMClient method throws a CIMException, or error condition. The CIM Object Manager uses Java exception handling and creates a hierarchy of WBEM-specific exceptions. 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 relating to the exception. Refer to file:/usr/sadm/lib/wbem/doc/index.html for more information on the CIMException class.
The Solaris WBEM SDK installation compiles the standard CIM Managed Object Format (MOF) files into the default namespaces. If you create a new namespace, you must compile the appropriate CIM .mof files into the new namespace before you create objects in that namespace. For example, if you plan to create classes that use the standard CIM elements, compile the CIM Core Schema into the namespace. If you plan to create classes that extend the CIM Application Schema, compile the CIM Application into the namespace.
This example uses a two-step process to create a namespace within an existing namespace:
When the namespace is created, the CIMNameSpace method constructs a namespace object that contains the parameters to be passed to the CIM Object Manager.
The CIMClient class connects to the CIM Object Manager and passes the namespace object. The CIM Object Manager creates the namespace, using the parameters contained in the namespace object.
{ ... /* Creates a namespace 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 namespace (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 namespace object (cns), which contains the host name (args[0]) and parent namespace 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 namespace object that contains a null string (host name) and args[2], the name of a child namespace (for example, secondlevel). */ CIMNameSpace cop = new CIMNameSpace("", args[2]); /* Creates a new namespace by the name passed in as args[2] under the toplevel namespace on myhost./* cc.createNameSpace(cop); ... }
Use the deleteNameSpace method to delete a namespace.
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 and then use the MOF Compiler to compile the file into Java classes. See Chapter 2, Creating JavaBeans 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 it 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 namespace, you must first compile the core MOF files into the namespace. 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.
Use the CIMClient deleteClass method to delete a class. Deleting a class removes the class and throws a CIMException.
You must first remove any existing subclasses or instances before deleting a base class.
This example uses the deleteClass method to delete a class in the default namespace root\cimv2. This program takes four required string arguments (hostname, classname, username, and password). The user running this program must specify the username and password for an account that has write permission to the root\cimv2 namespace.
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 * namespace 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 // (cns) pointing to the default namespace 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(); } } }
You can set access control on a per-user or namespace basis. The following access control classes are stored in the root\security namespace:
Solaris_Acl – Base class for Solaris Access Control Lists (ACL). This class defines the string property capability and sets its default value to r (read only).
Solaris_UserAcl – Represents the access control that a user has to the CIM objects within the specified namespace.
Solaris_NamespaceAcl – Represents the access control on a namespace.
You can set access control for individual users to the CIM objects within a namespace by creating an instance of the Solaris_UserACL class and then changing the access rights for that instance. Similarly, you can set access control for a namespace by creating an instance of the Solaris_NameSpaceACL class and then using the createInstance method to set the access rights for that instance.
An effective way to combine the use of these two classes is to use the Solaris_NameSpaceACL class first, to restrict access to all users to the objects in a namespace. Then, you can use the Solaris_UserACL class to grant selected users access to the namespace.
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 following values for access privileges.
Access Right |
Description |
---|---|
r |
Read |
rw |
Read and Write |
w |
Write |
none |
No access |
The Solaris_UserAcl class defines the following key properties. Only one instance of the namespace and user name ACL pair can exist in a namespace.
Property |
Data Type |
Purpose |
---|---|---|
nspace |
string |
Identifies the namespace to which the ACL applies. |
username |
string |
Identifies the user to which the ACL applies. |
Create an instance of the Solaris_UserAcl class. For example:
... /* Create a namespace object initialized with root\security (name of namespace) on the local host. */ CIMNameSpace cns = new CIMNameSpace("", "root\security"); // Connect to the root\security namespace 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(); ...
Set the capability property to the desired access rights. For example:
... /* Change the access rights (capability) to read/write for user Guest on objects in the root\molly namespace.*/ 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")); ...
Update the instance. For example:
... // Pass the updated instance to the CIM Object Manager cc.createInstance(new CIMObjectPath(), ci); ...
The Solaris_NamespaceAcl extends the Solaris_Acl base class, from which it 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 namespace to which the access control list applies. Only one instance of the namespace ACL can exist in a namespace. |
Create an instance of the Solaris_namespaceAcl class. For example:
... /* Create a namespace object initialized with root\security (name of namespace) on the local host. */ CIMNameSpace cns = new CIMNameSpace("", "root\security"); // Connect to the root\security namespace 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(); ...
Set the capability property to the desired access rights. For example:
... /* Change the access rights (capability) to read/write to the root\molly namespace. */ ci.setProperty("capability", new CIMValue(new String("rw")); ci.setProperty("nspace", new CIMValue(new String("root\molly")); ...
Update the instance. For example:
// Pass the updated instance to the CIM Object Manager cc.createInstance(new CIMObjectPath(), ci);
A CIM qualifier is an element that characterizes a CIM class, instance, property, method, or parameter. Qualifiers have the following attributes:
Type
Value
Name
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 qualifier type named key, with a Boolean data type (default value false), which 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; };
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 and whether or not a derived class or instance can override the qualifier's original value.
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; } } } ...
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.
A batch operation does not imply a single transaction. Each operation is independent of the other operations included in the batch and has 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 because the values are returned as a list after the batch operation is complete. The methods return an integer operation ID which you can use to get the result of the operation later. As methods of BatchCIMClient are invoked, the BatchCIMClient object builds a list of CIMOperationobjects that will be executed later.
When the client executes the batch operation list by invoking CIMClient's performBatchOperations method, a BatchResult object is returned that contains the results of the batch operation. 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.
The following example shows how you can use the batching API to perform multiple operations in one remote call. In this example, three operations - enumerateInstanceNames, getClass, and enumerateInstances are performed as a single batch operation.
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(); } } }
For in-depth information on CIM Indications and how they 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:
An operation on a basic object of a system — Create, delete, modify, or access a class; modify or access an instance
Any event that takes place in the managed environment
For example, when a service terminates and a trigger is engaged, 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 /usr/sadm/lib/wbem/doc/mofhtml/index.html. The class is structured as follows:
Table 3-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 |
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 data in which a class is created, modified, or deleted, or a class instance is created, modified, deleted, read, or has a method invocation. 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 CIM Object Manager. The CIM Object Manager analyzes subscription requests and uses the EventProvider and/or the CIMIndicationProvider interface to contact the provider, requesting that it generate the appropriate indications. When the provider generates the indication, the CIM Object Manager 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. In the case of subscriptions pertaining to instance life cycle indication (subclasses of CIM_InstIndication), once the CIM Object Manager determines the classes covered by the subscription, it contacts the instance providers for those classes. For process indications, the CIM Object Manager contacts the appropriate provider using the Provider qualifier.
The CIM Object Manager and the CIM Object Manager Repository handle indications under the following circumstances:
The CIM Object Manager handles CIM_InstMethodCall, CIM_InstModification, CIM_InstDeletion and CIM_InstCreation events if the provider does not support indications, or tells the CIM Object Manager to poll.
The CIM Object Manager Repository handles all class indications and life cycle indications for classes that do not have providers. These classes include CIM_ClassCreation, CIM_ClassDeletion CIM_ClassModification, CIM_InstCreation, CIM_InstModification, CIM_InstDeletion and CIM_InstRead.
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 and compares snapshots of previous states to current states to determine if instances have been created, modified, or deleted.
In most cases, providers should handle their own indications since polling carries a high overhead. In order to generate indications, the provider itself must poll. In this case, the provider can delegate the task to the CIM Object Manager.
If a provider implements the EventProvider interface, the CIM Object Manager invokes the methods in the interface and takes actions according to the responses. When the CIM Object Manager determines that a particular provider must participate in a subscription request, the methods are invoked in the following order:
mustPoll - Invoked by the CIM Object Manager for CIM_InstCreation, CIM_InstDeletion, and CIM_InstModification to determine if 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.
authorizeFilter - If the provider implements the Authorizable interface, this method is invoked by the CIM Object Manager to determine if the subscription is authorized. The provider can make the determination based on the user ID of the owner of the indication handler—the user who receives the indications—or based on the user ID of 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 namespace.
If the provider does not implement the EventProvider interface and the CIM Object Manager tries to poll, the authorization succeeds if enumerateInstances succeeds on the provider.
activateFilter - Invoked by the CIM Object Manager when the authorization succeeds and the provider does not want to be polled.
deActivateFilter - Called when a subscription is removed either by the subscriber or the CIM Object Manager; for example, if the destination handler malfunctions.
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 describes the following:
The indications to which it wants to subscribe.
The handler to which the CIM Object Manager delivers the indication.
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.
Create an instance of CIM_Listener. See Adding a CIM Listener..
Create an instance of CIM_IndicationFilter. See Creating an Event Filter.
Create an instance of CIM_IndicationHandler. See Creating an Event Handler.
Bind the to the CIM_IndicationFilter to the CIM_IndicationHandler. See Binding an Event Filter to an Event Handler.
To receive indications of CIM events, first add an instance of CIMListener to CIMClient, by invoking the addCIMListener method on CIMClient.
The CIMListener interface must implement the indicationOccured method, which takes the argument CIMEvent. This method is invoked when an indication is available for delivery.
// Connect to the CIM Object Manager cc = new CIMClient(); // Register the CIM Listener cc.addCIMListener( new CIMListener() { public void indicationOccured(CIMEvent e) { } });
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 namespace to which the filter belongs.
The CIM_IndicationFilter class has string properties that you can 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 3-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_IndicationFilter as 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 namespace 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). |
Create an instance of the CIM_IndicationFilter class:
CIMClass cimfilter = cc.getClass (new CIMObjectPath(“CIM_IndicationFilter”), true, true, true, null); CIMInstance ci = cimfilter.newInstance(); |
Specify the name of the event filter:
Name = “filter_all_new_solarisdiskdrives” |
Create a WQL string to identify that event indications to return:
String filterString = “SELECT * FROM CIM_InstCreation WHERE sourceInstance ISA Solaris_DiskDrive”; |
Set property values in the cimfilter instance to identify the name of the filter, the filter string to select CIM events, and the 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");)
Create an instance of the cimfilter instance called filter and store it in the CIM Object Manager Repository:
CIMObjectPath filter = cc.createInstance(new CIMObjectPath(), ci); |
CIMClass cimfilter = cc.getClass(new CIMObjectPath (“CIM_IndicationFilter”), true); CIMInstance ci = cimfilter.newInstance(); //Assuming that the test_a class exists in the namespace String filterString = "select * from CIM_InstCreation where sourceInstance isa test_a" ci.setProperty("query", new CIMValue(filterString)); CIMObjectPath filter = cc.createInstance(newCIMObjectPath(), ci);
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 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 using the HTTP protocol. The Solaris Event MOF extends the CIM_IndicationHandler class by creating the Solaris_JAVAXRMIDelivery class to handle delivery of indications of CIM events to client applications using the RMI protocol. RMI clients must instantiate the Solaris_JAVAXRMIDelivery class to set up an RMI delivery location.
Table 3-7 CIM_IndicationHandler Properties
Property |
Description |
Required/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 or not to authorize a handler to receive an indication. |
Optional. The default value is the Solaris user name of the user creating the instance. |
// 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);
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”, and defines the handler property to the delivery object path created in Example 3–23.
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);
The Solaris MOFs 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 when a system cannot access a serial port, when a system successfully mounts a file system, or when the number of processes that are running on a system exceeds the allowed number.
The underlying providers for the logging classes can forward logging requests to the syslog daemon, the default logging system in the Solaris operating environment. See syslogd(1M).
WBEM log messages are stored in individual log files in the /var/sadm/wbem/log directory. The names of the log files, the directory in which the log files are stored, the log file size limit, the number of log files to store, and whether to forward messages to syslogd(1M) are 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_Device1.0.mof, and CIM_LogRecord in CIM_Device26.mof.
A log message includes the following elements:
Table 3-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 or not to send the message to syslogd(1M) |
This example creates an instance of Solaris_LogEntryand 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(); } } }
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(); } } }