Sun WBEM 開発ガイド

第 7 章 プロバイダプログラムの作成

この章では、プロバイダの作成方法について説明します。内容は次のとおりです。

プロバイダ API の詳細は、Javadoc リファレンスページを参照してください。

プロバイダについて

プロバイダは、データにアクセスするために管理対象オブジェクトと通信するクラスです。プロバイダは、統合と解釈を行うために情報を CIM Object Manager に送ります。CIM Object Manager Repository に存在しないデータの要求を管理アプリケーションから受け取る場合、CIM Object Manager はその要求をプロバイダに送ります。

オブジェクトプロバイダは、CIM Object Manager と同じマシンにインストールされている必要があります。CIM Object Manager は、オブジェクトプロバイダ API を使用して、ローカルマシンにインストールされているプロバイダと通信します。

アプリケーションが CIM Object Manager に動的データを要求した場合、CIM Object Manager はプロバイダインタフェースを使用してその要求をプロバイダに渡します。

プロバイダは、CIM Object Manager からの要求に応答して次の機能を実行します。

プロバイダの種類

プロバイダは扱えるサービスの要求タイプにより分類されます。Sun WBEM SDK では、次の 3 種類のプロバイダをサポートしています。

プロバイダ 1 つでメソッドとインスタンスの両方を提供できるため便利です。

ほとんどのプロバイダは、プルプロバイダです。つまり、必要に応じてデータを動的に生成することによりそれ自体のデータを管理します。プルプロバイダは、CIM Object Manager および CIM Repository と最小限の対話しか行いません。プルプロバイダによって管理されるデータは、通常、頻繁に変化します。そのため、プロバイダはアプリケーションから要求が出るたびにデータを動的に生成するか、あるいはローカルキャッシュからデータを取り出す必要があります。

プロバイダは、単体でインスタンスプロバイダ、プロパティプロバイダ、およびメソッドプロバイダの役割を同時に果たすことができます。このためには、関連するすべてのメソッドを適切に登録、実装する必要があります。

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

プロバイダは、それらの役割に固有のサービスをサポートするプロバイダインタフェースを実装します。インタフェースを実装するには、プロバイダクラスは初めに implements 節でそのインタフェースを宣言し、続いてそのインタフェースのすべての抽象メソッドに対して実装 (本体) を提供する必要があります。次の表では、プロバイダインタフェースについて説明しています。メソッドプロバイダ、インスタンスプロバイダ、およびプロパティプロバイダは、単一の Java クラスファイルに含めることも、あるいは個々のファイルに格納することもできます。

プロバイダは、initialize メソッドを使用して CIM Object Manager と通信できます。initialize メソッドには、CIM Object Manager に対する参照である、 CIMOMhandle 型の引数を指定できます。CIMOMhandle クラスには、プロバイダが CIM Object Manager との間でデータ転送に使用できるメソッドが含まれます。

表 7-1 プロバイダインタフェース

インタフェース 

説明 

CIMProvider

すべてのプロバイダが実装する基本インタフェース 

InstanceProvider

インスタンスプロバイダが実装する基本インタフェース。インスタンスプロバイダは、クラスの動的インスタンスを提供する 

MethodProvider

メソッドプロバイダが実装するインタフェース。メソッドプロバイダは、CIM クラスのすべてのメソッドの実装を提供する 

PropertyProvider

プロパティプロバイダが実装するインタフェース。プロパティプロバイダは、動的プロパティの検出と更新のために使用される。動的データは、CIM Object Manager Repository には格納されない 

インスタンスプロバイダインタフェース (InstanceProvider)

次の表は、Provider パッケージ (com.sun.wbem.provider) に含まれるインスタンスプロバイダインタフェースのメソッドについて説明しています。

これらの各メソッドは引数 op を取ります。op は、指定された CIM クラスまたは CIM インスタンスの CIM オブジェクトパスです。オブジェクトパスには、ネームスペース、クラス名、およびキー (オブジェクトがインスタンスの場合) が含まれます。ネームスペースは、ほかのネームスペース、クラス、インスタンス、および修飾子のデータ型を格納できるディレクトリです。キーは、クラスインスタンスを個別に識別するプロパティです。キープロパティには、キー修飾子が含まれます

たとえば、次のオブジェクトパスは 2 つの部分から構成されます。

¥¥myserver¥root¥cimv2¥Solaris_ComputerSystem:Name=mycomputer:
   CreationClassName=Solaris_ComputerSystem

表 7-2 InstanceProvider インタフェースメソッド

メソッド 

説明 

enumInstances

オブジェクトパスに指定されたクラスのすべてのインスタンスを列挙する。ディープ (deep) または シャロー (shallow) 列挙が可能だが、現在 CIM Object Manager はシャロー列挙だけを要求する 

getInstance

オブジェクトパス (op) に指定されたインスタンスを返す

setInstance

オブジェクトパス (op) に指定されたインスタンスを設定する。そのインスタンスが存在しない場合は、追加する必要がある

deleteInstance

オブジェクトパス (op) に指定されたインスタンスを削除する

例 - インスタンスプロバイダの実装

例 7-1 のコードセグメントは、CIM Object Manager からのインスタンスデータ要求を 1 つ以上の特化されたプロバイダに送る Solaris インスタンスプロバイダクラスを作成します。これらの特化されたプロバイダは、特定の Solaris オブジェクトの動的データの要求に対するサービスを提供します。たとえば、Solaris_Package プロバイダは、Solaris_Package クラスのインスタンスの要求に対応します。

インスタンスプロバイダは、InstanceProvider インタフェースのすべてのメソッドを実装する必要があります。例 7-1 のコードセグメントは、次の 2 つのメソッドだけを示しています。


例 7-1 インスタンスプロバイダの実装

public class Solaris implements InstanceProvider
{
   /**
    * 最上位レベルのプロバイダクラスが、CIM Object Manager
    * からの要求を適切なプロバイダに送る。
    */
 
    public void initialize(CIMONHandle, ch) 
    throws CIMException {
    }
 
    public void cleanup() 
    throws CIMException {
    }
 
    /* このクラスは、指定されたクラス内の指定されたオブジェクトの
    列挙済みインスタンスが入ったベクトルを返す。オブジェクトが Solaris
    パッケージの場合、このクラスは Solaris_Package プロバイダを呼び
    出し、システム上の Solaris パッケージのリストを返す。
    オブジェクトが Solaris パッチの場合、Solaris_Patch プロバイダを
    呼び出し、システム上の Solaris パッチのリストを返す。*/
 
    public Vector enumInstances(CIMObjectPath op, CIMClient.DEEP, CIMClass cc)
    throws CIMException {
        if (op.getObjectName().equalsIgnoreCase("solaris_package")) {
            Solaris_Package sp = new Solaris_Package();
            return sp.enumerateInstances(op);
        }
        if (op.getObjectName().equalsIgnoreCase("solaris_patch")) {
            Solaris_Patch sp = new Solaris_Patch();
            return sp.enumerateInstances(op);
        }
       return new Vector();
    }
 
 
    /* このクラスは、指定されたクラス内の指定されたオブジェクトの
    インスタンスを返す。オブジェクトが Solaris パッケージの場合、
    このクラスは Solaris_Package プロバイダを呼び出し、指定された
    Solaris パッケージのデータを返す。オブジェクトが Solaris
    パッチの場合、Solaris_Patch プロバイダを呼び出し、指定された
    Solaris パッチのデータを返す。*/
 
    public CIMInstance getInstance(CIMObjectPath op, CIMClass cc) 
    throws CIMException {
        if (op.getObjectName().equalsIgnoreCase("solaris_package")) {
            Solaris_Package sp = new Solaris_Package();     
            return sp.getInstance(op,cc);
        }
        if (op.getObjectName().equalsIgnoreCase("solaris_patch")) {
            Solaris_Patch sp = new Solaris_Patch();         
            return sp.getInstance(op,cc);
        } 
}
 


特化された Solaris インスタンスプロバイダは、API を使用してオブジェクトインスタンスの取得と設定を行います。これらのプロバイダは、C 関数を呼び出して Solaris 固有の値 (ホスト名、シリアル番号、リリース、マシン、アーキテクチャ、メーカーなど) を取得するネイティブメソッドの宣言も行います。

例 7-2 のコードセグメントは、例 7-1 で呼び出される solaris_package クラスを示します。このコードセグメントは、getInstance メソッドを実装します。このメソッドは、指定されたクラスの新しいインスタンスを作成し、ネイティブ C 関数 (GetPkgArchitecture() など) が返すプロパティをそれらのインスタンスに割り当てます。


例 7-2 Solaris パッケージプロバイダ

public class Solaris_Package 
{
    public CIMInstance getInstance(CIMObjectPath op, CIMClass cc) {
        String pkgName = "";
 
        for (Enumeration e = op.getKeys().elements(); e.hasMoreElements();) {
            CIMProperty cp = (CIMProperty)e.nextElement();
            if (cp.getName().equalsIgnoreCase("name")) {
                pkgName = (String) ((CIMValue)(cp.getValue())).getValue();
            }
        }
 
 
        CIMInstance ci = cc.newInstance();
        ci.setProperty("Name", new CIMValue(pkgName));
        ci.setProperty("TargetOperatingSystem", 
                          new CIMValue(new UnsignedInt16(29)));
 
        ci.setProperty("Status", 
                     new CIMValue(GetPkgStatus(pkgName)));
  			 ci.setProperty("Architecture", 
                          new CIMValue(GetPkgArchitecture(pkgName)));
        ci.setProperty("Description", new CIMValue(GetPkgDescription(pkgName)));
        ci.setProperty("Caption", new CIMValue(GetPkgDescription(pkgName)));
        ci.setProperty("Manufacturer", new CIMValue(GetPkgVendor(pkgName)));
        ci.setProperty("Category", new CIMValue(GetPkgCategory(pkgName)));
        ci.setProperty("Basedir", new CIMValue(GetPkgBasedir(pkgName)));
       return ci;
    }
 
    native String GetPkgDescription(String pkgName);
    native String GetPkgArchitecture(String pkgName);
    native String GetPkgVersion(String pkgName);
    native String GetPkgVendor(String pkgName);
    native String GetPkgBasedir(String pkgName);
    native String GetPkgCategory(String pkgName);
    native String GetPkgStatus(String pkgName);
 
 
   static {
       System.loadLibrary("NativeUnix");
   
    }
 
}
 

プロパティプロバイダインタフェース (PropertyProvider)

次の表は、プロパティプロバイダインタフェースのメソッドについて説明しています。

表 7-3 PropertyProvider インタフェースメソッド

メソッド 

説明 

getPropertyValue

指定されたインスタンスのプロパティの値を返す 

setPropertyValue

指定されたインスタンスのプロパティの値を設定する 

例 - プロパティプロバイダの実装

例 7-3 のコードセグメントは、例 7-5 で登録されるプロパティプロバイダ (fruit_prop_provider) クラスを作成します。fruit_prop_provider は、PropertyProvider インタフェースを実装します。

このサンプルプロパティプロバイダは、指定されたクラスのプロパティ値、親クラス、およびプロパティ名を返す getPropertyValue メソッドを示しています。CIM プロパティは、その名前と親クラスによって定義されます。複数のプロパティで同じ名前を使用できますが、親クラスはプロパティを個別に識別します。


例 7-3 プロパティプロバイダの実装

fruit_prop_provider implements PropertyProvider 
{
public CIMValue getPropertyValue(CIMObjectpath op, string originclass, 
	string PropertyName){
 
		if (PropertyName.euqals("a")
			return new CIMValue("fooa")
 
		else
			return new CIMValue("foob");
}
...
}
 


メソッドプロバイダインタフェース (MethodProvider)

MethodProvider メソッドには、次の引数を指定できます。

次の表では、MethodProvider インタフェースのメソッドについて説明します。

表 7-5 MethodProvider インタフェースメソッド

メソッド 

説明 

invokeMethod

CIM Object Manager は、指定されたメソッドが呼び出される場合にこのメソッドを呼び出す 

例 - メソッドプロバイダの実装

例 7-4 のコードセグメントは、CIM Object Manager からのメソッド実行要求を 1 つ以上の特化されたプロバイダに送る Solaris プロバイダクラスを作成します。これらの特化されたプロバイダは、特定の Solaris オブジェクトの動的データの要求に対するサービスを行います。たとえば、Solaris_Package プロバイダは、Solaris_Package クラスのメソッドを実行する要求に対応します。

この例のメソッドプロバイダは、適切なプロバイダを呼び出して次に示す処理の 1 つを実行する単一のメソッド invokeMethod を実装します。


例 7-4 MethodProvider の実装

public class Solaris implements MethodProvider
{
 
    public void initialize(CIMONHandle, ch) 
    throws CIMException {
    }
 
    public void cleanup() 
    throws CIMException {
    }
   public CIMValue invokeMethod(CIMObjectPath op, String methodName, 
        Vector inParams, Vector outParams) throws CIMException {
        if (op.getObjectName().equalsIgnoreCase("solaris_computersystem")) {
            Solaris_ComputerSystem sp = new Solaris_ComputerSystem();
            if (methodName.equalsIgnoreCase("reboot")) {
               return new CIMValue (sp.Reboot());
            }
        }
        if (op.getObjectName().equalsIgnoreCase("solaris_operatingsystem")) {
            Solaris_OperatingSystem sos = new Solaris_OperatingSystem();
            if (methodName.equalsIgnoreCase("reboot")) {
               return new CIMValue (sos.Reboot());
            }
            if (methodName.equalsIgnoreCase("shutdown")) {
               return new CIMValue (sos.Shutdown());
            }
        }
        if (op.getObjectName().equalsIgnoreCase("solaris_serialport")) {
            Solaris_SerialPort ser = new Solaris_SerialPort();
            if (methodName.equalsIgnoreCase("disableportservice")) {
               return new CIMValue (ser.DeletePort(op));
            }
        }
        return null;
    }
}
 


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

プロバイダは、管理対象デバイスに関する情報の取得と設定を行います。ネイティブプロバイダは、管理対象デバイスで動作するように作成されるマシン固有のプログラムです。たとえば、Solaris システム上のデータにアクセスするプロバイダは、通常、C 関数を組み込んで Solaris システムの照会を行います。ネイティブプロバイダは、一般に次のような理由で作成されます。

JDK の一部である Java Native Interface (JNI) は、Java のネイティブプログラミングインタフェースです。JNI を使用してプログラムを作成すると、ほとんどのプラットフォームで完全に移植可能です。Java Virtual Machine (VM) で動作する Java コードで JNI を使用すると、そのコードは C、C++、アセンブラのようなほかの言語で作成されたアプリケーションおよびライブラリで実行できます。

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

プロバイダのインストール

プロバイダを作成したあと、プロバイダクラスファイルと共有ライブラリファイルの場所を指定する必要があります。

プロバイダプログラムをインストールする方法
  1. 次に示す方法の 1 つを使用して、共有ライブラリファイルの場所を指定します。

    • LD_LIBRARY_PATH 環境変数を、共有ライブラリファイルのある場所に設定します。C シェルを使用している場合の入力例を次に示します。

      % setenv LD_LIBRARY_PATH /wbem/provider/
      

      Borne シェルを使用している場合の入力例を次に示します。

      $ LD_LIBRARY_PATH=/wbem/provider/
      $ export LD_LIBRARY_PATH
      

    • 共有ライブラリファイルを、LD_LIBRARY_PATH 環境変数によって指定されているディレクトリにコピーします。WBEM のインストールを行うと、この環境変数は /install_dir/opt/SUNWconn/wbem/lib に設定されます。次に入力例を示します。

    % cp libnative.so /install_dir/opt/SUNWconn/wbem/lib
    % cp native.c /install_dir/opt/SUNWconn/wbem/lib
     
    

  2. プロバイダクラスファイルを、/install_dir/opt/SUNWconn/wbem/lib に移動します。

  3. CLASSPATH 変数を、プロバイダクラスファイルが入っているディレクトリに設定します。

    たとえば、プロバイダファイルを次のディレクトリ

    /install_dir/opt/SUNWconn/wbem/bin/com/mycomp/wbem/provider/
    

    に置く場合は、C シェルでは CLASSPATH 変数を次のように設定します。

    % setenv CLASSPATH /install_dir/opt/SUNWconn/wbem/bin/com/mycomp/wbem/provider/
    

    Borne シェルでは次の構文を使用します。

    $ CLASSPATH=/install_dir/opt/SUNWconn/wbem/bin/com/mycomp/wbem/provider/ 
    $ export CLASSPATH
    

  4. CIM Object Manager が動作していることを確認します。

    インストールを行うと CIM Object Manager は自動的に起動します。CIM Object Manager が動作していない場合は、「CIM Object Manager の再起動」を参照してください。

プロバイダの登録

サポートするデータと処理、およびそれらの物理的な実装についての情報を公開するため、CIM Object Manager にプロバイダを登録します。CIM Object Manager は、この情報を使用してプロバイダのロードと初期化、および特定のクライアント要求に適切なプロバイダを決定します。プロバイダはすべて同じ方法で登録します。登録時に CIM Object Manager、プロバイダとも動作している必要はありません。

プロバイダを登録する方法
  1. CIM クラスを定義する MOF ファイルを作成します。

  2. そのクラスに、provider 修飾子を割り当てます。provider 修飾子には、プロバイダ名を割り当てます。

    プロバイダ名により、そのクラスのプロバイダとしての役目をする Java クラスが識別されます。クラス名は、完全に指定する必要があります。次に例を示します。


    注 -

    プロバイダについては、プロバイダ名が固有になるように、Java クラスおよびパッケージ命名規則に従うことを推奨します。固有のパッケージ名の接頭辞は小文字の ASCII 文字で、トップレベルのドメイン名にする必要があります。現在は、comedugovmilnetorg、または、ISO 標準 3166、1981 で指定されている国名を識別する 2 文字コードなどです。

    パッケージ名のあとの名前は、組織内部の命名規則によって異なります。たとえば、あるディレクトリ名のコンポーネントは、部名、課名、プロジェクト名、マシン名、あるいはログイン名などになります (例 : com.mycompany.wbem.myprovider)。


    [Provider("com.kailee.wbem.providers.provider_name")]
    Class_name {
    ...
    };

  3. MOF ファイルをコンパイルします。次に例を示します。

    mofcomp class_name

例 - プロバイダの登録

例 7-5 のサンプル MOF ファイルは、インスタンスプロバイダ (fruit_class_provider)、プロパティプロバイダ (fruit_prop_provider)、およびメソッドプロバイダ (fruit_method_provider) を登録する Fruit というクラスを作成します。


例 7-5 インスタンスプロバイダ、プロパティプロバイダ、およびメソッドプロバイダの登録

 
// fruit_class_provider を Fruit クラスのプロバイダとして登録
[Provider("com.food.fruitprovider.fruit_class_provider")] 
 
Fruit {
 
// fruit_prop_provider は、プロパティ a のプロバイダである。
		[Provider("com.food.fruitprovider.fruit_class_provider")] 
-		string a;
 
		// fruit_prop_provider は、プロパティ b のプロバイダでもある。
		[Provider("com.food.fruitprovider.fruit_class_provider")] 
		string b;
 
		// fruit_method_provider は、メソッド b のプロバイダである。
		[Provider("com.food.fruitprovider.fruit_class_provider")] 
		int b();
};
 


プロバイダの変更

プロバイダクラスは、CIM Object Manager とプロバイダの動作中に変更できます。しかし、加えた変更を有効にするためには、CIM Object Manager を停止して再起動する必要があります。

プロバイダを変更する方法
  1. プロバイダソースファイルを編集します。

  2. プロバイダソースファイルをコンパイルします。次に例を示します。

    % javac MyProvider.java
    

  3. システムプロンプトで次のコマンドを入力し、システム上でスーパーユーザーになります。

    % su
    

  4. プロンプトに対し、スーパーユーザーのパスワードを入力します。

  5. 次のコマンドを入力して、init.wbem コマンドがある位置にディレクトリを変更します。

    # cd /etc/init.d/
    

  6. 次のコマンドを入力して、CIM Object Manager を停止します。

    # ./init.wbem stop
    

  7. 次のコマンドを入力して、CIM Object Manager を再起動します。

    # ./init.wbem start
    

プロバイダの例

第 8 章「Sun WBEM SDK サンプルの使用」で、プロバイダの例の設定と実行方法について説明しています。