5


WDR のプログラミング手法

この章では、コーディング例を示しながら、WDR を使用してタスクを実行するときの手法を説明します。ただし、ここに挙げるコーディング例は、製品版の WDR アプリケーションでの使用を目的としたものではありません。

コーディング例では、以下のプロバイダの操作方法を説明しています。


システムの状態情報のキャッシュ

WDR のクライアントアプリケーションを開発する際に考慮すべき重要な事項は、管理対象プラットフォームのドメイン、接続点、およびスロットの現在の状態をクライアントで把握する方法には、ポーリングによる方法とキャッシュを使用する方法の、全く異なる 2 つのアプローチがあることです。

クライアントでは、対応する WDR クラスのインスタンスを列挙することにより、ドメイン、接続点、およびスロットの状態を定期的にポーリングすることができます。ただし、WDR を使用した操作の実行に要する時間はシステムの状態と作業負荷に依存し、変動することがあるため、このアプローチは推奨されません。これは、システムコントローラ (SC) とクライアントアプリケーション双方の性能に悪影響を及ぼすことになります。

より適切なアプローチは、クライアントで、ドメイン、接続点、およびスロットの現在の状態のキャッシュを保持し、クライアントの状態情報のキャッシュを更新する必要があるときに、WDR プロセスインジケーションを使用して、更新を指示する方法です。詳細は、CIM プロセスインジケーションクラスを参照してください。


EventProvider の操作

EventProvider を作成するには、次の作業を実行します。


procedure icon  WDR インジケーションを選択して読み取る

以下のコードは、WDR イベントインジケーションの選択および読み取り方法を示しています。

/* 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  イベントリスナーを実装する

以下のコードでは、CIM イベントを待機できるように、CIMListener インタフェースを実装しています。CIM イベントのインジケーションに関する登録を行うには、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  イベントフィルタとイベントハンドラをバインドする

IndicationSubscription クラスを使用すると、クライアントは CIM イベントが通知されるように申請できます。以下のコードは、イベントフィルタをイベントハンドラにバインドします。

/* 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 );
	}
}


InstanceProvider の操作

以下のコーディング例では、m_Client という CIMClient オブジェクトがすでに作成されて使用できる状態になっているものとします。

1. enumerateInstanceNames メソッドと getInstance メソッドを使用して、Solaris_XCDomain クラスのすべてのインスタンスを取得します。

// 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. enumerateInstances メソッドを呼び出します。

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


AssociatorProvider の操作

以下のコーディング例では、m_Client という CIMClient オブジェクトがすでに作成されて使用できる状態になっているものとします。

1. Solaris_SystemBoardHasProcessors 関連により Solaris_CHSystemBoard クラスのインスタンスに関連付けられている Solaris_CHCPU クラスの各インスタンスを取得します。

// 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. SolarisCHSystemBoard クラスと Solaris_CHCPU クラスのインスタンスを参照する関連オブジェクトを列挙します。

// 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());                           
}


MethodProvider の操作

以下のコーディング例では、m_Client という CIMClient オブジェクトがすでに作成されて使用できる状態になっているものとします。

1. 1 つのプロセッサを構成し、その構成処理中に発生したエラーメッセージがあれば、それを標準の出力デバイスに出力します。

// 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. システムボードをドメインに割り当てて、その割り当て処理中に発生したエラーメッセージがあれば、それを標準の出力デバイスに出力します。

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