Skip to main content

Using the SBLIM CIM Client efficiently

Tips to produce a code skeleton for CIM Client development

Hui Yang (hyang@cn.ibm.com), Staff Software Engineer, IBM
Hui Yang
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.
Qi Feng Xu (xuqif@cn.ibm.com), Software Engineer, IBM
Qi Feng Xu
Qi Feng Xu is a software engineer at IBM China Systems and Technology Laboratories in Shanghai. He is currently working on the Platform Configuration Library project.
Yi Sheng Zhu (zhuyis@cn.ibm.com), Software Engineer, IBM
Yi Sheng Zhu
Yi Sheng Zhu is a software engineer at the IBM China Systems and Technology Laboratories in Shanghai. He is working on the Storage Configuration Manager project. He is also interested in open source projects and football.

Summary:  We all know that templates can save time. In this article, learn how to produce a code skeleton based on predefined templates using the SBLIM Common Information Model (CIM) Client library. With CIM, most client-side applications serve as the CIM clients. They use standard CIM XML-over-HTTP protocol for communication with the CIM server. It's inconvenient to encode and decode CIM-XML statements directly. Fortunately, the SBLIM CIM Client gives you standard APIs that can facilitate CIM client development. This article also provides tips on how to add code to your skeleton produced from the templates.

Date:  20 Oct 2009
Level:  Introductory
Activity:  1183 views

Introduction

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.

SBLIM - Standards Based Linux® Instrumentation for Manageability (pronounced sublime). An IBM-initiated open source project to enhance the manageability of GNU/Linux systems by enabling Web-Based Enterprise Management (WBEM).

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
Image depicting common structure                     with SBLIM CIM Client library


Generating a code skeleton

There are three steps for generating a code skeleton.

  1. Define the code template according to your requirements.
  2. Retrieve the CIM elements definition by mining the CIM server directly with the SBLIM CIM Client library.
  3. Import the skeleton template and CIM elements information, and generate an object-oriented code skeleton set for CIM client development.

Customizing a code template

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;
}
}
            

Producing a code skeleton

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)
            


Summary

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.


Resources

Learn

Get products and technologies

Discuss

About the authors

Hui Yang

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.

Qi Feng Xu

Qi Feng Xu is a software engineer at IBM China Systems and Technology Laboratories in Shanghai. He is currently working on the Platform Configuration Library project.

Yi Sheng Zhu

Yi Sheng Zhu is a software engineer at the IBM China Systems and Technology Laboratories in Shanghai. He is working on the Storage Configuration Manager project. He is also interested in open source projects and football.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=435824
ArticleTitle=Using the SBLIM CIM Client efficiently
publish-date=10202009
author1-email=hyang@cn.ibm.com
author1-email-cc=
author2-email=xuqif@cn.ibm.com
author2-email-cc=
author3-email=zhuyis@cn.ibm.com
author3-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers