Solaris WBEM 開発ガイド

プロバイダインタフェースの実装

プロバイダの作成時には、プロバイダがサポートするインタフェースを指定する必要があります。プロバイダがサポートする各インタフェースのすべてのメソッドを実装してください。またすべてのプロバイダには、 CIMProvider インタフェースを実装する必要があります。プロバイダインタフェースには、次の 2 つのメソッドがあります。

インスタンスプロバイダの作成

次のコード例は、 Ex_SimpleCIMInstanceProvider クラスの enumerateInstances および getInstance インタフェースを実装します。わかりやすくするために、この例では、CIMException をスローすることによって deleteInstancecreateInstancesetInstanceexecQuery の各インタフェースを実装します。


注 –

execQuery メソッドの実装についての詳細は、照会の構文解析を参照してください。



例 6–1 CIMInstance プロバイダ

/*
 * "@(#)SimpleCIMInstanceProvider.java"
 */
import javax.wbem.cim.*;
import javax.wbem.client.*;
import javax.wbem.provider.CIMProvider;
import javax.wbem.provider.CIMInstanceProvider;
import javax.wbem.provider.MethodProvider;
import java.util.*;
import java.io.*;

public class SimpleCIMInstanceProvider implements CIMInstanceProvider {
     static int loop = 0;
     public void initialize(CIMOMHandle cimom) throws CIMException {
     }
     public void cleanup() throws CIMException {
     }
     public CIMObjectPath[] enumerateInstanceNames(CIMObjectPath op, 
                                                   CIMClass cc) 
         throws CIMException {
            return null;
     }
     /*
      * enumerateInstances:
      * 名前だけではなくインスタンス全体を返す
      */
     public CIMInstance[] enumerateInstances(CIMObjectPath op,
                          boolean localOnly,boolean includeQualifiers,
                          boolean includeClassOrigin,String[] 
                          propertyList, CIMClass cc) throws CIMException
     {
     if (op.getObjectName().equalsIgnoreCase
                            ("Ex_SimpleCIMInstanceProvider")) {
         Vector instances = new Vector();
         CIMInstance ci = cc.newInstance();
         if (loop == 0){
             ci.setProperty("First", new CIMValue("red"));
             ci.setProperty("Last", new CIMValue("apple"));
             // 要求されたプロパティのみを含める
             ci = ci.filterProperties(propertyList, includeQualifier,
                                                 includeClassOrigin);
             instances.addElement(ci);
             loop += 1;
         } else {
             ci.setProperty("First", new CIMValue("red"));
             ci.setProperty("Last", new CIMValue("apple"));
             // 要求されたプロパティのみを含める
             ci = ci.filterProperties(propertyList, includeQualifier,
                                                 includeClassOrigin);
             instances.addElement(ci);
             ci = cc.newInstance();
             ci.setProperty("First", new CIMValue("green"));
             ci.setProperty("Last", new CIMValue("apple"));
             // 要求されたプロパティのみを含める
             ci = ci.filterProperties(propertyList, includeQualifier,
                                                 includeClassOrigin);
             instances.addElement(ci);
         }
         return (CIMInstance[])instances.toArray();
     }
     throw new CIMException(CIM_ERR_INVALID_CLASS);
     }

     public CIMInstance getInstance(CIMObjectPath op, 
                                    boolean localOnly, 
                                    boolean includeQualifiers, 
                                    boolean includeClassOrigin,
                                    String[] propertyList, 
                                    CIMClass cc) 
         throws CIMException {
             if (op.getObjectName().equalsIgnoreCase
                             ("Ex_SimpleCIMInstanceProvider"))
             {
                 CIMInstance ci = cc.newInstance();
                 // 取得したいインスタンスを一意に識別するため
                 // オブジェクトパス内の渡された項目からキーを取得することが
                 // 必要である
                 java.util.Vector keys = cop.getKeys();
                 // これは例なので、キーをインスタンス内に配置するだけで
                 // 終了する
                 ci.setProperties(keys);
                 // キープロパティ以外のプロパティがある場合はここに追加する

                 // 要求されたプロパティのみを含める
                 ci = ci.filterProperties(propertyList, includeQualifiers,
                                                      includeClassOrigin);
                 return ci;
             }
             throw new CIMException(CIM_ERR_INVALID_CLASS);
      }

     public CIMInstance[] execQuery(CIMObjectPath op, \
                            String query, String ql, CIMClass cc)
           throws CIMException {
           throw(new CIMException(CIMException.CIM_ERR_NOT_SUPPORTED));
    }

     public void setInstance(CIMObjectPath op, CIMInstance ci, boolean 
                             includeQualifiers, String[] propertyList)
           throws CIMException {
           throw(new CIMException(CIMException.CIM_ERR_NOT_SUPPORTED));
    }

     public CIMObjectPath createInstance(CIMObjectPath op, 
                                         CIMInstance ci) 
                                         throws CIMException {
           throw(new CIMException(
                     CIMException.CIM_ERR_NOT_SUPPORTED));
    }

     public void deleteInstance(CIMObjectPath cp) 
         throws CIMException {
         throw(new CIMException(CIMException.CIM_ERR_NOT_SUPPORTED));
     }
 }


メソッドプロバイダの作成

クライアントプログラムが Solaris WBEM プロバイダのメソッドを呼び出すためには、invokeMethod メソッドが必要です。これは、組み込み済みのプロバイダと開発者によって追加されたプロバイダの両方に当てはまります。

次のコード例では、CIMOM からの要求を 1 つ以上の特別なプロバイダに配信する Solaris_ComputerSystem プロバイダクラスを作成します。これらのプロバイダは、特定の管理対象オブジェクトの動的データの要求を処理します。たとえば、Solaris_Package プロバイダは、Solaris_Package クラスメソッドを実行する要求に対応します。

メソッドプロバイダは、invokeMethod という単一メソッドを実装します。このメソッドは、システムのリブート、システムのシャットダウン、シリアルポートの削除のいずれかの処理を実行する適切なプロバイダを呼び出します。


例 6–2 メソッドプロバイダ

...
public class Solaris_ComputerSystem implements MethodProvider {
	ProviderCIMOMHandle pch = null;
	public void initialize(CIMOMHandle ch) throws CIMException {
		pch = (ProviderCIMOMHandle)ch;
	}

	public void cleanup() throws CIMException {
	}

	public CIMValue invokeMethod(CIMObjectPath op, String methodName,
			Vector inParams, Vector outParams)  throws CIMException {
		if (op.getObjectName().equalsIgnoreCase("solaris_computersystem")) {
			if (methodName.equalsIgnoreCase("reboot")) {
				// ここに表示されていないヘルパー関数を呼び出す
				return new CIMValue(rebootSystem());
			}
			if (methodName.equalsIgnoreCase("shutdown")) {
				// ここに表示されていないヘルパー関数を呼び出す
				return new CIMValue(shutdownSystem());
			}
		}
		if (op.getObjectName().equalsIgnoreCase("solaris_serialport")) {
			if (methodName.equalsIgnoreCase("disableportservice")) {
				// ここに表示されていないヘルパー関数を呼び出す
				return new CIMValue(deletePort(op));
			}
		}
		// ここに到達した場合はエラーを返す
		throw new CIMException(CIMException.CIM_ERR_NOT_SUPPORTED,
			"The requested function does not exist");
	}
	// 以下にヘルパー関数を定義する
	...
}

アソシエータプロバイダの作成


注 –

クライアントプログラムによって呼び出される個々の関連メソッド内の objectName 引数、すなわち CIMObjectPath は、クラスではなく「インスタンス」のオブジェクトパスになっていなければなりません。


CIMOM がインスタンスのオブジェクトパスを認識しない場合は、クライアントが CIM オブジェクトマネージャリポジトリ内の関連のクラス定義を求めているものと見なします。関連のクラス定義には、その関連のメンバーインスタンスを派生するテンプレートが含まれます。したがって、CIMOM は、プロバイダの関連メソッドではなくクライアント API の関連メソッドを使用します。

関連を設計およびコーディングする場合に最も重要な部分は、関連クラスです。作成する関連は、関連クラスのコンテンツ以上には複雑になりません。関連のメンバー数は、関連クラスの参照数に等しくなります。役割は、さらに複雑な関連をモデル化する場合に使用できます。次に、関連クラスの例を示します。

次のコード例では associators メソッドを実装します。CIMOM は、associatorNamesobjectNameroleresultRoleincludeQualifiersincludeClassOrigin、および propertyList のそれぞれの値を関連プロバイダに渡します。また CIM 関連クラスの名前と、返される関連オブジェクトが属する CIM クラスまたはインスタンスを出力します。このプロバイダは、example_teacher クラスと example_student クラスのインスタンスを処理します。


例 6–3 CIMAssociator プロバイダ

...

public CIMInstance[] associators(CCIMObjectPath assocName, CIMObjectPath 
                objectName, String resultClass, String role, String
                resultRole, boolean includeQualifiers, boolean 
                includeClassOrigin, String[] propertyList)
                throws CIMException {
        
    System.out.println("Associators "+assocName+" "+objectName);
    if (objectName.getObjectName()equalsIgnoreCase("example_teacher")) {
        Vector v = new Vector();
        if ((role != null)  && (!role.equalsIgnoreCase("teaches"))) {
            // Teacher は、teaches という役割だけを担う
            return v;
        }
        if ((resultRole != null)  && (!resultRole.equalsIgnoreCase
                                     ("taughtby"))) {
            // Teacher は、taughtby という役割によってのみ得られる
            return v;
        }
        // Teacher のアソシエータを取得する
        CIMProperty nameProp = (CIMProperty)objectName.getKeys().elementAt
                               (0);
        String name = (String)nameProp.getValue().getValue();
        // Student のクラスを取得する
        CIMObjectPath tempOp = new CIMObjectPath("example_student");
        tempOp.setNameSpace(assocName.getNameSpace());
        CIMClass cc = cimom.getClass(tempOp, false);
        // objectName によって渡されたインスタンス名をテストし、Student
        // クラスの関連インスタンスを返す
        if(name.equals("teacher1")) {
            // teacher1 の Student (複数) を取得する
            CIMInstance ci = cc.newInstance();
            ci.setProperty("name", new CIMValue("student1"));
            v.addElement(ci.filterProperties(propertyList, 
                             includeQualifiers,
                             includeClassOrigin));
            ci = cc.newInstance();
            ci.setProperty("name", new CIMValue("student2"));
            v.addElement(ci.filterProperties(propertyList,
                        includeQualifiers, includeClassOrigin));
            return v;
        }
    }
}

インジケーションプロバイダの作成

CIM イベントのインジケーションを生成するには、次のタスクを実行する必要があります。

イベントインジケーションを生成する方法
  1. EventProvider インタフェースを実装します。

    次に例を示します。

    public class sampleEventProvider implements 
            InstanceProvider EventProvider{
    
        // プロバイダが CIM オブジェクトマネージャに接続するための参照
        private ProviderCIMOMHandle cimom;
       }

  2. プロバイダが処理するインスタンスインジケーションに対して、表 6–2 に示すそれぞれのメソッドを実行します。

  3. 作成、変更、および削除のインスタンスイベントに対してインジケーションを作成します。

    以下に createInstance メソッドの例を示します。

    public CIMObjectPath createInstance(CIMObjectPath op, 
            CIMInstance ci)
        throws CIMException {
            CIMObjectpath newop = ip.createInstance(op, ci);
           
            CIMInstance indication = new CIMInstance();
            indication.setClassName("CIM_InstCreation");
            
            CIMProperty cp = new CIMProperty();
            cp.setName("SourceInstance");
            cp.setValue(new CIMValue(ci));
            
            Vector v = new Vector();
            v.addElement(cp);
            indication.setProperties(v);
            ...
        }

  4. イベントインジケーションを CIM オブジェクトマネージャに送信します。

    cimom.deliverEvent(op.getNameSpace(), indication);

イベントプロバイダメソッド

イベントプロバイダは、EventProvider インタフェースを実装します。クライアントが CIM イベントのインジケーションを予約した場合、CIMOM は、このインタフェースに含まれるメソッドを使ってプロバイダに通知します。このメソッドは、クライアントが CIM イベントの予約を取り消した場合にも使用されます。さらにこれらのメソッドにより、CIMOM が特定のイベントインジケーションのポーリングを行うかどうか、インジケーションをハンドラに返すことを承認するかどうかも指定します。

次の表に、イベントプロバイダで実装する必要のある EventProvider インタフェースのメソッドを示します。

表 6–2 EventProvider メソッド

メソッド 

説明 

activateFilter

クライアントが予約を作成すると、CIMOM は、このメソッドを呼び出して、CIM イベントの検査をプロバイダに依頼する 

authorizeFilter

クライアントが予約を作成すると、CIMOM は、このメソッドを呼び出して、指定されたフィルタ式が許可されているかを検査する 

deActivateFilter

クライアントが予約を削除すると、CIMOM は、このメソッドを呼び出して、指定されたイベントフィルタの停止をプロバイダに依頼する 

mustPoll

クライアントが予約を作成すると、CIMOM は、このメソッドを呼び出して、指定されたフィルタ式をプロバイダが許可するかどうか、そのフィルタ式のポーリングが必要かどうかを検査する 

CIMOM は、すべてのメソッドに次の引数の値を渡します。

さらに、activateFilter メソッドは、これがこのイベント型の最初のフィルタであることを示すブール値 firstActivation を受け取ります。deActivateFilter メソッドは、これが最後のフィルタであることを示すブール値 lastActivation を受け取ります。

インジケーションの作成と配信

クライアントアプリケーションが CIM_IndicationSubscription クラスのインスタンスを作成して CIM イベントのインジケーションを予約すると、CIMOM は、この要求を適切なプロバイダに転送します。プロバイダが EventProvider インタフェースを実装する場合、CIMOM は、指定するイベントのインジケーションの送信をいつ開始するかをプロバイダに通知します。プロバイダは、activateFilter メソッドを呼び出すことにより、この通知を行います。また、CIMOM は、プロバイダの deActivateFilter メソッドを呼び出して、指定するイベントのインジケーションの送信をいつ停止するかをプロバイダに通知します。

プロバイダは、インスタンスを作成、変更、削除するたびに、インジケーションを作成、配信して、CIMOM の要求に応答します。通常、プロバイダは、CIMOM が activateFilter メソッドを呼び出すときに設定されるフラグ変数を定義します。このフラグの設定は、CIMOM が deActivateFilter メソッドを呼び出すときにクリアされます。そのあと、プロバイダは、インスタンスを作成、変更、または削除するメソッドの中で、動作中のフラグの状態を検査します。フラグが設定されている場合、プロバイダは、作成された CIM インスタンスオブジェクトを含むインジケーションを作成します。プロバイダは、deliverEvent メソッドを使って、CIMOM にインジケーションを返します。フラグが設定されていない場合、プロバイダは、イベントインジケーションの作成や配信を行いません。

プロバイダは、activateFilter メソッドが呼び出されると、インジケーションの配信を開始します。プロバイダは、CIM_Indication の concrete (具象) サブクラスのインスタンスを作成し、ProviderCIMOMHandled.deliverIndication メソッドを起動します。CIMOM は、インジケーションを受信し、そのインジケーションを適切なインジケーションハンドラに配信します。プロバイダは、複数の種類のイベントを処理できます。たとえば、サイクルインジケーションの場合、プロバイダは CIM_InstCreationCIM_InstDeletion、および CIM_InstModification を処理できます。

予約者が設定した種類を監視する場合、プロバイダは activateFilter および deActivateFilter 呼び出しにそれぞれ渡された firstActivation および lastActivation フラグを使用できます。firstActivation フラグは、特定のイベントの種類をはじめて予約した場合には、true になります。同様に lastActivation は、特定のイベントの種類の最後の予約を削除すると、true になります。これらのフラグを検査すると、プロバイダは、指定したイベントの種類を監視するために簡単にリソースを割り当てたり、割り当てを解除したりすることができます。

承認について

機密データを扱うプロバイダは、インジケーションの要求に対する承認を検査することができます。その場合、プロバイダは Authorizable インタフェースを実装して、そのプロバイダが承認を検査することを示す必要があります。また、プロバイダは authorizeFilter メソッドを実装する必要があります。CIMOM は、このメソッドを呼び出して、イベントハンドラの所有者 (UID) がフィルタ式の評価に基づいて送信されるインジケーションを受信することを承認されているかどうかを検査します。イベントの宛先の所有者 (イベントハンドラ) の UID は、フィルタを動作中にするように要求するクライアントアプリケーションの所有者と同じである必要はありません。

ネイティブプロバイダの作成

プロバイダは、管理対象デバイスに関する情報の取得と設定を行います。ネイティブプロバイダは、特定の管理対象デバイスに特化して作成されたプログラムです。たとえば、Solaris システム上のデータにアクセスするプロバイダには、通常、システムを照会するために C 関数が含まれます。

ネイティブプロバイダは、一般に次のような理由で作成されます。

Java Native Interface は、JDK ソフトウェアの一部です。Java Native Interface を使ってプログラムを作成すれば、その Java プログラムコードはどのプラットフォームにも移植可能です。Java コードは、Java Native Interface により、Java 以外の言語 (C、C++、アセンブラなど) で作成されたアプリケーションやライブラリを使用できます。

Java プログラムの作成、および Java プログラムとネイティブメソッドの統合についての詳細は、Java Web サイト http://java.sun.com を参照してください。