The Distributed Management Task Force (DMTF) develops standards that enable interoperable IT management. The DMTF CIM is a conceptual information model for describing computing and business entities in enterprise and Internet environments. It provides a consistent definition and structure of data using object-oriented techniques. CIM's common definitions enable vendors to exchange semantically rich management information among systems throughout the network.
In this article, learn how to produce a code skeleton based on predefined templates using the SBLIM CIM Client library. Also included are tips on how to write code with the classes that are created.
You can use the code skeleton as a glue layer that facilitates further CIM client-side application development. The glue layer will make it easier for you to implement a CIM client application (with less programming), and to maintain the application in the future.
Overview of the SBLIM CIM Client
The SBLIM CIM Client is a Java implementation of a WBEM services client that includes an IETF RFC 2614-compliant SLP client for the CIM service discovery. The CIM Client for Java is a mature library in production use with several commercial products and open source projects. It is widely used by management applications in all areas that leverage CIM technology. Users can easily communicate with CIM servers and extract information. The SBLIM CIM Client helps you complete onerous tasks, such as parsing XML-based CIM response messages, and generating CIM requests from Java objects.
Configuration is also easier with the SBLIM CIM Client. Many properties can be set in the configuration file. You can set the pool size of an HTTP connection, track the communication history between the client and server, etc. With CIM, application developers can focus on business logic implementation and leave all the other boring and error-prone tasks to the SBLIM CIM Client.
The common structure of the SBLIM CIM Client library is shown in Figure 1.
Figure 1. Common structure with SBLIM CIM Client library
There are three steps for generating a code skeleton.
- Define the code template according to your requirements.
- Retrieve the CIM elements definition by mining the CIM server directly with the SBLIM CIM Client library.
- Import the skeleton template and CIM elements information, and generate an object-oriented code skeleton set for CIM client development.
You need to tailor code templates at the very beginning to define how the created code will look. You can use several mechanisms in this subprocess, such as Extensible Stylesheet Language Transformations (XSLT) and the Java-based template engine Velocity. Either can be used as a stand-alone utility for generating code skeletons. In most cases, you can define common methods for CIM operation in class templates, such as enumerating CIM object paths or instances, getting property values, and invoking methods. Additional specific snippets can also be integrated into the class template; it’s a very convenient and flexible way to meet special requirements.
Typically, the following basic methods for CIM operation can be defined in a template.
getInstances()- Enumerates the CIM instances on the target CIM server that are of the specified class, or of its subclasses, and returns copies of these instances.
deleteInstance()- Deletes a CIM instance on the target CIM server.
getAssociatedPaths()- Enumerates all CIM object paths on the target CIM server that are associated with the source class through the specified CIM association.
getAssociatedInstances()- Enumerates all CIM instances on the target CIM server that are associated with the source class through the specified CIM association.
-
getAssociationPaths() - Enumerates all CIM association paths on the target CIM server that associates the source class. This method only exists in an association class.
getAssociationInstances()- Enumerates all CIM association instances on the target CIM server that associates the source class. This method only exists in an association class.
Invoke- Calls the extrinsic method calls exposed by the CIM instance.
An example of a tailored code template for Velocity is shown in Listing 1.
Listing 1. Sample code of tailored code template for Velocity engine
public class ${cls.Name} {
/**
* Itererate all ${cls.Name} instances.
*
* @param client A CIM Client used to connect to the CIMOM.
* @return An Array of ${cls.Name} instances.
* @throws WBEMException Exception while getting instances.
*/
public static ${cls.Name} [] getInstances(WBEMClient client, String nameSpace)
throws WBEMException {
${cls.Name} [] result = new ${cls.Name} [0];
CloseableIterator iter = client.enumerateInstances(${cls.Name}.makePath(nameSpace),
true, false, false, null);
try{
result = parseResult(client, iter);
}catch(Exception e){
if(e instanceof WBEMException)
throw (WBEMException)e;
}finally{
iter.close();
}
return result;
}
/**
* Remove this CIM Instance on the target CIM server. *
* @throws WBEMException Exception while deleting instance.
*/
public void deleteInstance() throws WBEMException {
if (m_cop != null) {
m_client.deleteInstance(this.m_cop);
} else {
throw new RuntimeException("");
}
}
/**
* Itererate all ${cls.Name} instances that are associated with the
* specified class through the specified CIM Association.
*
* @param client A CIM Client used to connect to the CIMOM.
* @param sourcePath The CIMObjectPath of the source Instance.
* @param associationClass The Class Name of the CIM Association.
* @return An Array of ${cls.Name} instances. *
* @throws WBEMException Exception while getting instances.
*/
public static ${cls.Name}[] getAssociatedInstances(WBEMClient client,
CIMObjectPath sourcePath,
String associationClass)
throws WBEMException {
${cls.Name}[] result = new ${cls.Name}[0];
CloseableIterator iter = client.associators(sourcePath, associationClass,
"${cls.Name}", null, null, false, false, null);
try{
result = parseResult(client, iter);
}catch(Exception e){
if(e instanceof WBEMException)
throw (WBEMException)e;
}finally{
iter.close();
}
return result;
}
/**
* Itererate all ${cls.Name} instances that are associated with the
* specified class through the specified CIM Association.
*
* @param client A CIM Client used to connect to the CIMOM.
* @param sourcePath The CIMObjectPath of the source Instance.
* @return An Array of ${cls.Name} instances.
* @throws WBEMException Exception while getting instances.
*/
public static ${cls.Name}[] getAssociationInstances(WBEMClient client,
CIMObjectPath sourcePath)
throws WBEMException {
${cls.Name}[] result = new ${cls.Name}[0];
CloseableIterator iter = client.references(sourcePath,
"${cls.Name}", null, false, false, null);
try{
result = parseResult(client, iter);
}catch(Exception e){
if(e instanceof WBEMException)
throw (WBEMException)e;
}finally{
iter.close();
}
return result;
}
}
|
Retrieving CIM element definitions
Technically, the main components of a managed object format (MOF) specification are:
- Textual descriptions of element qualifiers (metadata about classes, properties, methods, etc.).
- Comments and compiler directives.
- The specific class and instance definitions that convey the semantics of the CIM schema.
The CIM element definitions are necessary for the next process because they are specific to each CIM class, and they can be in context for each template.
Generally, you need to compile the MOF files to a CIM server. Then you use the SBLIM CIM Client library to get these meaningful descriptions. Lots of open source Java implementation tools supply this special function, such as the WBEM Services project. You can easily compile the MOF files to a target CIM server with one command line, then retrieve CIM elements definitions from the CIM server conveniently with the help of the SBLIM CIM Client. The code below shows an example.
Listing 2. Sample code for retrieving CIM elements definitions
/**
* Mine the CIM Agent for all CIM Classes that are exposed in the specified Namespace.
* @param ns The Namespace
* @return A Vector of CIMClass objects
* @throws WBEMException In the case of any CIM Errors
*/
private Vector<CIMClass> mineCimAgent(String ns)
throws WBEMException {
WBEMClient cc = getCimClient(ns);
CIMObjectPath cp = new CIMObjectPath(null, ns);
// Use WBEMClient to retrieve all classes under namespace ns.
CloseableIterator classes = cc.enumerateClasses(cp,true,true,true,true);
Vector<CIMClass> result = new Vector<CIMClass>();
CIMClassProperty property = null;
for(CIMClass cls : classes){
result.add(cls);
// Get Description property of one CIM class.
property = cls.getProperty("Description");
}
return result;
}
/**
* Generate the CIMClass into its Java representation
* @param cls The CIM Class
* @throws Exception In the case of any Errors
*/
private void generateToJava(CIMClass cls) throws Exception {
try {
// Prepare context for velocity. CIMClassWrapper is a customized class to
// help retrieve class properties and other information.
VelocityContext context = new VelocityContext();
CIMClassWrapper clsWrapper = new CIMClassWrapper(cls);
context.put("cls", clsWrapper);
// Merge the template against the context.
final String vmFile = "CIM_ClassTemplate.vm";
Template template = Velocity.getTemplate(vmFile);
// Make the output java file path, and write the java file.
String file = packagePath + File.separator + cls.getName() + ".java";
Writer writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file)));
template.merge(context, writer);
writer.flush();
writer.close();
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
throw e;
}
}
|
The first step is to adopt one transformation engine to merge the template against the CIM elements descriptions. Then, you produce a set of formatted code skeletons. Either XSLT or Velocity can be used in this subprocess, which fills the variables in the predefined template with the context information of CIM elements to generate source code. One copy of the code skeleton almost maps the structure of one CIM class defined in the MOF file, and wraps all the methods for CIM-related operation.
Listing 3 shows an example code snippet for creating a code skeleton.
Listing 3. Generated code skeleton
public class CIM_StorageVolume{
/**
* Itererate all CIM_StorageVolume instances.
*
* @param client A CIM Client used to connect to the CIMOM.
* @return An Array of CIM_StorageVolume instances.
* @throws WBEMException Exception while getting instances.
*/
public static CIM_StorageVolume[] getInstances(WBEMClient client, String nameSpace)
throws WBEMException {
CIM_StorageVolume[] result = new CIM_StorageVolume[0];
CloseableIterator iter = client.enumerateInstances(CIM_StorageVolume.makePath(nameSpace),
true, false, false, null);
try{
result = parseResult(client, iter);
}catch(Exception e){
if(e instanceof WBEMException) {
throw (WBEMException)e;
}
}finally{
iter.close();
}
return result;
}
/**
* Remove this CIM Instance on the target CIM server.
*
* @throws WBEMException Exception while deleting instance.
*/
public void deleteInstance() throws WBEMException{
if (m_cop != null) {
m_client.deleteInstance(this.m_cop);
} else {
throw new RuntimeException();
}
}
/**
* Itererate all CIM_StorageVolume instances that are associated with the specified
* class through the specified CIM Association.
*
* @param client A CIM Client used to connect to the CIMOM.
* @param sourcePath The CIMObjectPath of the source Instance.
* @param associationClass The Class Name of the CIM Association.
* @return An Array of CIM_StorageVolume instances.
* @throws WBEMException Exception while getting instances.
*/
public static CIM_StorageVolume[] getAssociatedInstances(WBEMClient client, CIMObjectPath
sourcePath, String associationClass)
throws WBEMException {
CIM_StorageVolume[] result = new CIM_StorageVolume[0];
CloseableIterator iter = client.associators(sourcePath, associationClass,
"CIM_StorageVolume", null, null, false, false, null);
try{
result = parseResult(client, iter);
}catch(Exception e){
if(e instanceof WBEMException)
throw (WBEMException)e;
}finally{
iter.close();
}
return result;
}
}
}
|
If you deploy the created code skeleton in the CIM client-side program, you don't need to face the SBLIM CIM Client APIs directly. The code skeleton can be taken as a glue layer, which works with the SBLIM CIM Client seamlessly and supplies object-oriented APIs to upper-level development.
Examples using the code skeleton
The example code snippets below illustrate how to use the skeleton that was previously generated in this article.
Listing 4. Use the skeleton previously generated
//Get an WBEMClient instance and initialize it
WBEMClient client = WBEMClientFactory.getClient("CIM-XML");
Subject subject = new Subject();
subject.getPrincipals().add(new UserPrincipal(usr));
subject.getPrivateCredentials().add(new PasswordCredential(pwd));
CIMObjectPath path = new CIMObjectPath(url.getProtocol(),
url.getHost(), String.valueOf(url.getPort()), null, null, null);
client.initialize(path, subject, null);
|
Query instances under one namespace.
Listing 5. Query instances
CIM_StorageVolume[] volumes = CIM_StorageVolume.getInstances(client, namespace);
for(CIM_StorageVolume volume : volumes) {
System.out.println(volume);
}
|
Then delete one specified instance.
volumes[0].deleteInstance(); |
Query associated instances.
Listing 5. Query associated instances
volumes = CIM_StorageVolume.getAssociatedInstances(client, deviceCOP,
CIM_SystemDevice.getCimClassName());
for(CIM_StorageVolume volume : volumes) {
System.out.println(volume);
}
|
Invoke one extrinsic method.
int returnVal = volumes[0].enableDevice(true);
//Check the return value
assert(0 == returnVal)
|
This article introduced how to generate Java classes with the SBLIM CIM Client using a template. You learned how to use those Java classes in your application. This combination maps a huge number of CIM classes to object-oriented language classes, which facilitates your CIM application development in the future.
Learn
-
Learn how Distributed
Management Task Force Inc. enables more effective management of millions of IT
systems worldwide by bringing the IT industry together to collaborate on the development, validation, and promotion of systems management standards.
-
Read the Specification for CIM
Operations over HTTP, DSP0200, V1.1.
-
To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
-
Stay current with developerWorks' Technical events and webcasts.
-
Follow developerWorks on Twitter.
-
Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
-
Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products, as well as our most popular articles and tutorials.
-
Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
Get products and technologies
-
Innovate your next open source development project with IBM trial software, available for download or on DVD.
- Download
IBM product evaluation versions
or explore
the online trials in the IBM SOA Sandbox and get your hands on application development tools and middleware products from
DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
-
Participate in developerWorks blogs and get involved in the developerWorks community.

Hui Yang is a staff software engineer at the IBM China Systems & Technology Laboratory Laboratories in Shanghai. He is currently working on the Platform Component Configuration Library project, which supplies CIM-related back-end support for the IBM Director and Storage Configuration Manager projects. He is also interested in CIM technology and open source projects, and he will be very happy to play table tennis with you.
Comments (Undergoing maintenance)







