C H A P T E R  5

Programming Techniques in WDR

This chapter provides code examples that illustrate techniques for performing tasks using WDR. However, these examples are not intended for use in production WDR applications.

The code examples demonstrate how you work with the following providers:


Caching System State Information

An important consideration when developing client applications for WDR is that there are two fundamentally different possible approaches to ensure that the client has a knowledge of the current state of the domains, attachment points and slots of the managed platform: polling and using cache.

The client can periodically poll for the status of domains, attachment points and slots, by enumerating the instances of the corresponding WDR classes. This approach is not recommended, since the time taken to execute an operation using WDR is dependent on the system state and workload, and can be variable. This will adversely affect the performance of both the System Controller (SC) and the client application.

A better approach is for the client to maintain a current cache of the domain, attachment point and slot status, and use the WDR Process Indications to indicate when updates to the client's cache of status information are necessary. See the section CIM Process Indication Classes for more information.


Working with an EventProvider

To create an EventProvider, you perform the following tasks:


procedure icon  To Subscribe to and Read WDR Indications

The following code shows how to subscribe to, and to read, WDR event indications:

/* Standard java packages */
import java.io.*;
/* Solaris WBEM packages */
import com.sun.wbem.cim.*;
import com.sun.wbem.client.*;
import com.sun.wbem.security.*;
 
public class IndicationReader
{
	public static void main(String args[]) throws CIMException
		{
			if (args.length != 3) {
				System.out.println("Usage: java IndicationReader " + "<hostname> <username> <password>");
			System.exit(1);
		}
		String hostName = args[0];
		UserPrincipal userName = new UserPrincipal(args[1]);
		PasswordCredential passWord = new PasswordCredential(args[2]);
		CIMNameSpace nameSpace = new CIMNameSpace();
		nameSpace.setHost(hostName);
		// Read all WDR Indications.
		final String filter = "SELECT * FROM Solaris_WDRIndication";
		IndicationSubscription subscription = null;
		try
		{
			// creates a CIMClient adding CIMListener to it.
			CIMClient cc = new CIMClient(nameSpace, userName, passWord);
			cc.addCIMListener(new EventListener());
			// subscribes to WDR Indications and waits
			subscription = new IndicationSubscription(cc, filter);
			System.out.println("Waiting for Indications...");
			waitForQuit();
		} 
		catch (Exception e) {
			e.printStackTrace();
		} 
		finally {
			if ( subscription != null ) {
				subscription.remove();
			}
		}
	System.exit(0);
	}
	/*
	* Exit when user types 'quit'
	*/
	private static void waitForQuit() throws IOException 
	{
		BufferedReader stdin =
		new BufferedReader( new InputStreamReader(System.in));
		String line = null;
		do {
			System.out.println("Type 'quit' followed by <CR> to exit");
			System.out.print("IR> ");
			line = stdin.readLine();
		} while ( ! line.startsWith("quit") );
	}
}

procedure icon  To Implement an Event Listener

The following code inplements the CIMListener interface so that it can listen for CIM events. To register for indications of CIM events, the client must add an instance of CIMListener.

/* WBEM libraries */
import com.sun.wbem.client.*;
 
public class EventListener implements CIMListener
{
	public EventListener() 
	{
	}
	/**
	* Prints indication of an event when the indication is available
	* for delivery.
	*/
	public void indicationOccured(CIMEvent e)
	{
		System.out.println("Received " + e.getIndication());
	}
}

procedure icon  To Bind an Event Filter to an Event Handler

The IndicationSubscription class enables clients to subscribe to be notified of CIM events. The following code binds an event filter to an event handler.

/* Standard Java packages */
import java.util.*;
 
/* Standard WBEM packages */
import com.sun.wbem.cim.*;
import com.sun.wbem.client.*;
import com.sun.wbem.security.UserPrincipal;
import com.sun.wbem.security.PasswordCredential;
 
public class IndicationSubscription
{
	static protected int m_FilterCnt = 0;
 
	protected CIMClient m_Client;
	protected CIMObjectPath m_Filter;
	protected CIMObjectPath m_Handler;
	protected CIMObjectPath m_Subscription;
 
	final String subscriptionClassName = "CIM_IndicationSubscription";
	final String filterClassName = "CIM_IndicationFilter";
	final String deliveryClassName = "Solaris_RMIDelivery";
	/**
	* Force construction through another constructor that is public.
     */
	protected IndicationSubscription() {
		m_Client = null;
		m_Filter = null;
		m_Handler = null;
		m_Subscription = null;
	}
 
	/**
	* Construct an IndicationSubscription that subscribed for Indications as expressed by the specified filterExp.  Three 
	* CIM objects are created in the CIM repository as a 
	* side-effect of calling this method, a CIM_IndicationFilter, 
	* a CIM_IndicationHandler, and a CIM_IndicationSubscription.
	* These can be removed by calling the remove method.
	*
	* @param cc            a CIMClient instance
	* @param filterExp     The query string on which to filter Indications
	* @exception CIMException 
	*/
	public IndicationSubscription(CIMClient cc, String filterExp) 
	throws CIMException
	{
		m_Client = cc;
		m_Filter = createFilter(filterExp);
		m_Handler = createHandler();
		m_Subscription = createSubscription();
	}
	/**
	* Removes the otherwise persistant filter, handler and	* subscription CIM objects from the CIM repository. 
	* @exception CIMException  if an attempt is made to delete a
	* non-existent CIM object.
	*/
	public void remove() throws CIMException {
		if ( m_Subscription != null ) {
			m_Subscription.setNameSpace("");
			m_Client.deleteInstance(m_Subscription);
			m_Subscription = null;
		}
		if ( m_Handler != null ) {
			m_Handler.setNameSpace("");
			m_Client.deleteInstance(m_Handler);
			m_Handler = null;
		}
		if ( m_Filter != null ) {
			m_Filter.setNameSpace("");
			m_Client.deleteInstance(m_Filter);
			m_Filter = null;
		}
	}
 
	/**
	* Create an IndicationFilter of the specified name and with the
	* specified filterExp as the query string.  Register the filter	* by creating its instance in the repository.  Only one filter	* may exist per IndicationSubscription object.
	*
	* @param filterExp The query string on which to filter	* Indications
	* @return CIMObjectPath of the filter.
	* @exception CIMException
	*/
	protected CIMObjectPath createFilter(String filterExp) throws CIMException
	{
		CIMClass filterClass = 
			m_Client.getClass(new CIMObjectPath(filterClassName), 
			false, true, true, null);
 
		CIMInstance ci = filterClass.newInstance();
 
		ci.setProperty("Name", new CIMValue(generateFilterName()));
		ci.setProperty("Query", new CIMValue(filterExp));
		ci.setProperty("QueryLanguage", new CIMValue("WQL"));
 
		CIMObjectPath op = m_Client.createInstance(new CIMObjectPath(), ci);
		return ( op );
	}
	/**
	* Generate a unique filter name for this Java VM.
	*
	* @return Name of the filter.
	*/
	protected String generateFilterName() 
	{
		String filterName = "WDRFilter"+ m_FilterCnt;
		m_FilterCnt = (m_FilterCnt + 1) % Integer.MAX_VALUE;
		return ( filterName );
	}
 
	/**
	* Create an indication handler.
	* Register the handler by creating its instance in the repository.  
	*
	* @return CIMObjectPath of the handler.
	*/
	protected CIMObjectPath createHandler() throws CIMException
	{
		CIMClass deliveryClass = 
		m_Client.getClass(new CIMObjectPath(deliveryClassName), 
                              false, true, true, null);
		CIMInstance ci = deliveryClass.newInstance();
 
		CIMObjectPath op = m_Client.createInstance(new CIMObjectPath(), ci);
		return ( op );
	}
	/**
	* Create an indication subscription that binds filter to handler.
	* Register the subscription by creating its instance in the repository.  
	*
	* @return CIMObjectPath of subscription.
	*/
	protected CIMObjectPath createSubscription() throws CIMException
	{
		final String subscriptionClassName = "CIM_IndicationSubscription";
		CIMClass subscriptionClass = 
		m_Client.getClass(new CIMObjectPath(subscriptionClassName), false, true, false, null);
 
		CIMInstance ci = subscriptionClass.newInstance();
		ci.setProperty("Filter", new CIMValue(m_Filter));
		ci.setProperty("Handler", new CIMValue(m_Handler));
 
		m_Client.createInstance(new CIMObjectPath(), ci);
 
		// we are looking for the subscription's reference because 
		// createInstance() returns a null reference for the subscription.
		CIMObjectPath cop = 
			new CIMObjectPath(subscriptionClassName, ci.getKeyValuePairs());
		return ( cop );
	}
}


Working with an InstanceProvider

The following code samples assume that a CIMClient object called m_Client has already been created and is available for use.

1. Get all instances of the Solaris_XCDomain class using the enumerateInstanceNames and getInstance methods:

// gets path to all instances
CIMObjectPath cop = new CIMObjectPath("Solaris_XCDomain");
Enumeration e = m_Client.enumerateInstanceNames(cop);
	 
// gets instances from the instances' paths
while ( e.hasMoreElements() ) {
	cop = (CIMObjectPath) e.nextElement();
	CIMInstance ci = m_Client.getInstance(cop, true, false, false, null);
	System.out.println(ci.toString());	 	
}

2. Invoke the enumerateInstances method:

CIMObjectPath cop = new CIMObjectPath("Solaris_XCDomain");
Enumeration e = m_Client.enumerateInstances(cop, true, false, false, null);
	 
while ( e.hasMoreElements() ) {
	CIMInstance ci  = (CIMInstance) e.nextElement();	 	
	System.out.println(ci.toString());	 	                     
}


Working with an AssociatorProvider

The following code samples assume that a CIMClient object called m_Client has been created and is available for use.

1. Get each instance of the Solaris_CHCPU class that is associated with an instance of the Solaris_CHSystemBoard class via the Solaris_SystemBoardHasProcessors association:

// sbCOP is a CIMObjectPath of a system board.
String assocClass = "Solaris_SystemBoardHasProcessor";
String resultClass = "Solaris_CHCPU";
String role = "SystemBoard";
String resultRole = "Processor";
boolean includeQualifiers = true;
boolean includeClassOrigin = true;
String[] cpuProperty = null;
            
Enumeration e = m_Client.associators(sbCOP, assocClass, resultClass, role, resultRole, includeQualifiers, includeClassOrigin, cpuProperty);          
while ( e.hasMoreElements() ) {
	CIMInstance ci = (CIMInstance) e.nextElement();
	System.out.println(ci.toString());                
} 

2. Enumerate association objects that refer to an instance of the SolarisCHSystemBoard class and to instances of the Solaris_CHCPU class:

// cop is CIMObjectPath of the Solaris_CHSystemBoard instance
String resultClass = "Solaris_SystemBoardHasProcessors"
String role = "SystemBoard";
String includeQualifiers = true;
String includeClassOrigin = true;
String[] propertyList = "Processor";
 
Enumeration e = m_Client.references(cop, resultClass, role, includeQualifiers, includeClassOrigin, propertyList);            
while ( e.hasMoreElements() ) {
	CIMInstance assoc = (CIMInstance) e.nextElement(); 
	System.out.println(assoc.toString());                           
}


Working with a MethodProvider

The following code samples assume that a CIMClient object called m_Client has been created and is available for use.

1. Configure a single processor and print out to the standard output any error messages that may occur during the configuration process:

// cop is CIMObjectPath of the processor
String method = "configure";
Vector inParams = new Vector(4);
Vector outParams = new Vector(2);
 
inParams.add(CIMValue.FALSE);                 /* force */
inParams.add(new CIMValue(new String("")));   /* hwOptions */
inParams.add(new CIMValue(new Integer(3)));   /* 3 retries */
inParams.add(new CIMValue(new Integer(5)));   /* 5s delay */        
            
CIMValue returnVal = m_Client.invokeMethod(cop, method, inParams, outParams);
int status = ((Integer)(returnVal.getValue())).intValue();
if ( status != 0 && outParams.size() != 0 ) {
	Object obj = ((CIMValue)(outParams.elementAt(0))).getValue();
	String error = (String) obj;
	if ( error != null ) {
		System.out.println(error);            
	}
} 

2. Assign a system board to a domain and print to the standard output any error messages that may occur during the assignment process:

// cop is the CIMObjectPath of a system board
String method = "Assign";
Vector inParams = new Vector(1);
Vector outParams = new Vector(2);
inParams.add(new CIMValue(new Integer(domainID))); /* domainID      
CIMValue returnVal = m_Client.invokeMethod(cop, method, inParams, outParams);
int status = ((Integer)(returnVal.getValue())).intValue();
if ( status != 0 && outParams.size() != 0 ) {
	Object obj = ((CIMValue)(outParams.elementAt(0))).getValue();
	String error = (String) obj;
 
	if ( error != null ) {
		System.out.println(error);            
	}
}