Providers implement a provider interface that supports the type of service specific to their role. In order to implement the interface, a provider class must first declare the interface in an implements clause, and then it must provide an implementation (a body) for all of the abstract methods of the interface. The following table describes the provider interfaces. You can include a method provider, instance provider, and property provider in a single Java class file, or store each provider in a separate file.
Providers can communicate with the CIM Object Manager using the initialize method. The initialize method takes an argument of type CIMOMhandle, which is a reference to the CIM Object Manager. The CIMOMhandle class contains methods that providers can use to transfer data to and from the CIM Object Manager.
Table 7-1 Provider Interfaces
Interface |
Description |
---|---|
CIMProvider |
Base interface implemented by all providers. |
InstanceProvider |
Base interface implemented by instance providers. Instance providers serve dynamic instances of classes. |
MethodProvider |
Interface implemented by method providers, which provide implementation for all methods of CIM classes. |
PropertyProvider |
Interface implemented by property providers, which are used to retrieve and update dynamic properties. Dynamic data is not stored in the CIM Object Manager Repository. |
The following table describes the methods in the instance provider interface in the Provider package (com.sun.wbem.provider).
These methods each take the op argument, the CIM object path of the specified CIM class or CIM instance. The object path includes the namespace, class name, and keys (if the object is an instance). The namespace is a directory that can contain other namespaces, classes, instances, and qualifier types. A key is a property that uniquely identifies an instance of a class. Key properties have a KEY qualifier.
For example, the following object path has two parts:
\\myserver\root\cimv2\Solaris_ComputerSystem:Name=mycomputer: CreationClassName=Solaris_ComputerSystem
\\myserver\root\cimv2
The default CIM namespace on host myserver.
Solaris_ComputerSystem:Name=mycomputer: CreationClassName=Solaris_ComputerSystem
A specific Solaris Computer System object in the default namespace on host myserver. This Solaris computer system is uniquely identified by two key property values in the format (property=value):
Name=mycomputer
CreationClassName=Solaris_ComputerSystem
Method |
Description |
---|---|
enumInstances |
Enumerates all instances of the class specified in the object path. You can do deep or shallow enumeration, but currently the CIM Object Manager only requests shallow enumeration. |
getInstance |
Returns the instance specified in the object path (op). |
setInstance |
Sets the instance specified in the object path (op). If the instance does not exist, it must be added. |
deleteInstance |
Deletes the instance specified in the object path (op). |
The code segment in Example 7-1, creates a Solaris instance provider class that routes requests for instance data from the CIM Object Manager to one or more specialized providers. These specialized providers service requests for dynamic data for a particular type of Solaris object. For example, the Solaris_Package provider services requests for instances of the Solaris_Package class.
An instance provider must implement all methods in the InstanceProvider interface. The code segment in Example 7-1 shows only two methods:
enumInstances - Calls the appropriate provider to enumerate Solaris packages and patches. This method does a deep enumeration, which returns the class instances and all instances of its subclasses.
getInstances - Calls the appropriate provider to get instances of Solaris packages and patches.
public class Solaris implements InstanceProvider { /** * Top-level provider class routes requests from the CIM * Object Manager to the appropriate provider. */ public void initialize(CIMONHandle, ch) throws CIMException { } public void cleanup() throws CIMException { } /* This class returns a vector of enumerated instances of the specified object in the specified class. If the object is a Solaris package, it calls the Solaris_Package provider to return a list of the Solaris packages on the system. If the object is a Solaris patch, it calls the Solaris_Patch provider to return a list of the Solaris patches on the system. */ public Vector enumInstances(CIMObjectPath op, CIMClient.DEEP, CIMClass cc) throws CIMException { if (op.getObjectName().equalsIgnoreCase("solaris_package")) { Solaris_Package sp = new Solaris_Package(); return sp.enumerateInstances(op); } if (op.getObjectName().equalsIgnoreCase("solaris_patch")) { Solaris_Patch sp = new Solaris_Patch(); return sp.enumerateInstances(op); } return new Vector(); } /* This class returns an instance of the specified object in the specified class. If the object is a Solaris package, it calls the Solaris_Package provider to return the data for the specified Solaris package. If the object is a Solaris patch, it calls the Solaris_Patch provider to return the data for the specified Solaris patch. */ public CIMInstance getInstance(CIMObjectPath op, CIMClass cc) throws CIMException { if (op.getObjectName().equalsIgnoreCase("solaris_package")) { Solaris_Package sp = new Solaris_Package(); return sp.getInstance(op,cc); } if (op.getObjectName().equalsIgnoreCase("solaris_patch")) { Solaris_Patch sp = new Solaris_Patch(); return sp.getInstance(op,cc); } } |
The specialized Solaris instance providers use the API to get and set instances of objects. These providers also declare native methods that call C functions to get Solaris-specific values, such as host name, serial number, release, machine, architecture, and manufacturer.
The code segment in Example 7-2 shows the solaris_package class, which is called in Example 7-1. This code segment implements the getInstance method. This method creates a new instance of the specified class and then fills it with properties returned from native C functions, such as GetPkgArchitecture().
public class Solaris_Package { public CIMInstance getInstance(CIMObjectPath op, CIMClass cc) { String pkgName = ""; for (Enumeration e = op.getKeys().elements(); e.hasMoreElements();) { CIMProperty cp = (CIMProperty)e.nextElement(); if (cp.getName().equalsIgnoreCase("name")) { pkgName = (String) ((CIMValue)(cp.getValue())).getValue(); } } CIMInstance ci = cc.newInstance(); ci.setProperty("Name", new CIMValue(pkgName)); ci.setProperty("TargetOperatingSystem", new CIMValue(new UnsignedInt16(29))); ci.setProperty("Status", new CIMValue(GetPkgStatus(pkgName))); ci.setProperty("Architecture", new CIMValue(GetPkgArchitecture(pkgName))); ci.setProperty("Description", new CIMValue(GetPkgDescription(pkgName))); ci.setProperty("Caption", new CIMValue(GetPkgDescription(pkgName))); ci.setProperty("Manufacturer", new CIMValue(GetPkgVendor(pkgName))); ci.setProperty("Category", new CIMValue(GetPkgCategory(pkgName))); ci.setProperty("Basedir", new CIMValue(GetPkgBasedir(pkgName))); return ci; } native String GetPkgDescription(String pkgName); native String GetPkgArchitecture(String pkgName); native String GetPkgVersion(String pkgName); native String GetPkgVendor(String pkgName); native String GetPkgBasedir(String pkgName); native String GetPkgCategory(String pkgName); native String GetPkgStatus(String pkgName); static { System.loadLibrary("NativeUnix"); } } |
The following table describes the methods in the property provider interface.
Table 7-3 PropertyProvider Interface Methods
Method |
Description |
---|---|
getPropertyValue |
Returns the value of the property for the specified instance. |
setPropertyValue |
Sets the value of the property for the specified instance |
The code segment in Example 7-3 creates a property provider (fruit_prop_provider) class that is registered in Example 7-5. The fruit_prop_provider implements the PropertyProvider interface.
This sample property provider illustrates the getPropertyValue method, which returns a property value for the specified class, parent class, and property name. A CIM property is defined by its name and origin class. Two or more properties can have the same name, but the origin class uniquely identifies the property.
fruit_prop_provider implements PropertyProvider { public CIMValue getPropertyValue(CIMObjectpath op, string originclass, string PropertyName){ if (PropertyName.euqals("a") return new CIMValue("fooa") else return new CIMValue("foob"); } ... } |
The MethodProvider method takes the following arguments:
op - Object path to the instance whose method must be invoked.
originClass - Name of the class in which this method was originally defined in the class hierarchy. CIM properties are attributes of a CIM class that are inherited from a parent class. A CIM property is uniquely identified within a namespace by its name and origin class. For example, two properties named speed can be distinguished by their respective origin classes DiskDrive and CPU.
inParams - Vector of CIMValues that are the input parameters for the method.
CIMValue - Return value of the method. If the method has no return value, it must return null. A CIM value stores the CIM data type and value of a CIM property. CIM data types (defined in the CIM Specification) are limited to intrinsic data types. The following table provides the WBEM data type name for each CIM data type.
Table 7-4 Sun WBEM SDK and CIM Data Type Names
CIM Data Type |
WBEM Data Type |
Description |
---|---|---|
uint8 |
UnsignedInt8 |
Unsigned 8-bit integer |
sint8 |
Byte |
Signed 8-bit integer |
uint16 |
UnsignedInt16 |
Unsigned 16-bit integer |
sint16 |
Short |
Signed 16-bit integer |
uint32 |
UnsignedInt32 |
Unsigned 32-bit integer |
sint32 |
Integer |
Signed 32-bit integer |
uint64 |
UnsignedInt64 |
Unsigned 64-bit integer |
sint64 |
Long |
Signed 64-bit integer |
string |
String |
UCS-2 string |
boolean |
Boolean |
Boolean |
real32 |
Float |
IEEE 4-byte floating point |
real64 |
Double |
IEEE 8-byte floating point |
datetime |
CIMDateTime |
String containing a date-time |
classname ref |
CIMObjectPath |
Strongly typed reference |
char16 |
Character |
16-bit UCS-2 character |
The following table describes the method in the Method Provider interface.
Table 7-5 MethodProvider Interface Methods
Method |
Description |
---|---|
invokeMethod |
The CIM Object Manager calls this method when the specified method is invoked. |
The code segment in Example 7-4 creates a Solaris provider class that routes requests to execute methods from the CIM Object Manager to one or more specialized providers. These specialized providers service requests for dynamic data for a particular type of Solaris object. For example, the Solaris_Package provider services requests to execute methods in the Solaris_Package class.
The method provider in this example implements a single method invokeMethod that calls the appropriate provider to perform one of following operations:
Reboot a Solaris system
Reboot or shut down a Solaris system
Delete a Solaris serial port
public class Solaris implements MethodProvider { public void initialize(CIMONHandle, ch) throws CIMException { } public void cleanup() throws CIMException { } public CIMValue invokeMethod(CIMObjectPath op, String methodName, Vector inParams, Vector outParams) throws CIMException { if (op.getObjectName().equalsIgnoreCase("solaris_computersystem")) { Solaris_ComputerSystem sp = new Solaris_ComputerSystem(); if (methodName.equalsIgnoreCase("reboot")) { return new CIMValue (sp.Reboot()); } } if (op.getObjectName().equalsIgnoreCase("solaris_operatingsystem")) { Solaris_OperatingSystem sos = new Solaris_OperatingSystem(); if (methodName.equalsIgnoreCase("reboot")) { return new CIMValue (sos.Reboot()); } if (methodName.equalsIgnoreCase("shutdown")) { return new CIMValue (sos.Shutdown()); } } if (op.getObjectName().equalsIgnoreCase("solaris_serialport")) { Solaris_SerialPort ser = new Solaris_SerialPort(); if (methodName.equalsIgnoreCase("disableportservice")) { return new CIMValue (ser.DeletePort(op)); } } return null; } } |
Providers get and set information on managed devices. A native provider is a machine-specific program written to run on a managed device. For example, a provider that accesses data on a Solaris system will most likely include C functions to query the Solaris system. Two common reasons for writing a native provider are:
Efficiency - You may want to implement a small portion of time-critical code in a lower-level programming language, such as assembly, and then have your Java application call these functions.
Need to access platform-specific features - The standard Java class library may not support the platform-dependent features needed by your application.
Legacy code - Often, you have legacy code written in some programming language other than Java and want to continue to use the code with a Java provider.
The Java Native Interface is the native programming interface for Java that is part of the JDK. By writing programs using the JNI, you ensure that your code is completely portable across all platforms. The JNI allows Java code that runs within a Java Virtual Machine (VM) to operate with applications and libraries written in other languages, such as C, C++, and assembly.
For more information on writing and integrating Java programs with native methods, visit the Java web site at http://www.javasoft.com/docs/books/tutorial/native1.1/index.html.