Sun WBEM SDK 開発ガイド

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

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

プロバイダ 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 節でそのインタフェースを宣言し、続いてそのインタフェースのすべての抽象メソッドに対して実装 (本体) を提供する必要があります。

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

次の表で、com.sun.wbem.provider パッケージに含まれているプロバイダインタフェースについて説明します。com.sun.wbem.provider20 パッケージの InstanceProvider インタフェースを使用してください。 メソッドプロバイダ、インスタンスプロバイダ、およびプロパティプロバイダは、単一の Java クラスファイルに含めることも、あるいは個々のファイルに格納することもできます。

表 5–1 プロバイダインタフェース

インタフェース 

説明 

CIMProvider

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

InstanceProvider

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

MethodProvider

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

PropertyProvider

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

AssociatorProvider

動的関連インスタンスのプロバイダによって実装される基本インタフェース 

Authorizable

マーカーインタフェースは、プロバイダが独自に承認検査を行うことを CIM Object Manger に知らせる 

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

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

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

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

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

表 5–2 InstanceProvider インタフェースメソッド

メソッド 

説明 

CIMObjectPath createInstance(CIMObjectPath op, CIMInstance ci)

op によって指定されたインスタンス ci が存在しない場合は、それを作成する。この CIM インスタンスがすでにある場合は、ID が CIM_ERR_ALREADY_EXISTSCIMInstanceException をプロバイダがスローする必要がある。作成されたインスタンスの CIMObjectPath を返す。

void deleteInstance(CIMObjectPath op)

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

Vector enumInstances(CIMObjectPath path, boolean deep, CIMClass cc)

path に指定されたクラスの各インスタンスの「名前」を返す。deeptrue の場合は、指定されたクラスとそのクラスから派生したすべてのクラスのすべてのインスタンスの名前を返す。deeptrue でない場合は、指定されたクラスに属するインスタンスの名前だけを返す。

プロバイダがインスタンスをゼロから作成したくない場合は、新しいインスタンスのテンプレートを作成できる。それには、そのインスタンスが属するクラス (cc) の newInstance() メソッドを呼び出す。

Vector enumInstances(CIMObjectPath path, boolean deep, CIMClass cc, boolean localOnly)

path に指定されたクラスのインスタンス (インスタンスの名前だけでなく、インスタンス全体) を返す。

プロバイダがインスタンスをゼロから作成したくない場合は、新しいインスタンスのテンプレートを作成できる。それには、そのインスタンスが属するクラス (cc) の newInstance() メソッドを呼び出す。

localOnly が true の場合は、列挙されたインスタンスのローカルプロパティ (継承されたプロパティではない) だけを返す。localOnly が true でない場合は、すべての継承されたプロパティとローカルプロパティを返す。

Vector execQuery (CIMObjectPath op, String query, int ql, CIMClass cc

照会を実行して CIM オブジェクトを検索する。このメソッドは、指定された照会文字列に一致する、指定された CIM クラス (cc) の CIM インスタンスのベクトルを返す。

CIMInstance getInstance(CIMObjectPath op, CIMClass cc, boolean localOnly)

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

プロバイダがインスタンスをゼロから作成したくない場合は、新しいインスタンスのテンプレートを作成できる。それには、そのインスタンスが属するクラス (cc) の newInstance() メソッドを呼び出す。

localOnly が true の場合は、列挙されたインスタンスのローカルプロパティ (継承されたプロパティではない) だけを返す。localOnly が true でない場合は、すべての継承されたプロパティとローカルプロパティを返す。

void setInstance(CIMInstance ci)

指定された CIM インスタンスが存在する場合は、それを更新する。このインスタンスが存在しない場合は、ID が CIM_ERR_NOT_FOUNDCIMInstanceException をスローする。

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

次のコード例は、インスタンスプロバイダ SimpleInstanceProvider の Java ソースコードです。このインスタンスプロバイダは、Ex_SimpleInstanceProvider クラスの enumInstances インタフェースと getInstance インタフェースを実装しています。わかりやすくするために、この例では、CIMException をスローすることによって deleteInstancecreateInstancesetInstanceexecQuery の各インタフェースを実装します。実際には、インスタンスプロバイダがすべての InstanceProvider インスタンスを実装する必要があります。


例 5–1 SimpleInstanceProvider インスタンスプロバイダ

/*
 * "@(#)SimpleInstanceProvider.java"
 */
import com.sun.wbem.cim.*;
import com.sun.wbem.client.*;
import com.sun.wbem.provider.CIMProvider;
import com.sun.wbem.provider20.InstanceProvider;
import com.sun.wbem.provider.MethodProvider;
import java.util.*;
import java.io.*;

public class SimpleInstanceProvider implements InstanceProvider{
     static int loop = 0;
     public void initialize(CIMOMHandle cimom) throws CIMException {
     }
     public void cleanup() throws CIMException {
     }
     public Vector enumInstances(CIMObjectPath op, boolean deep, CIMClass cc,
            boolean localOnly) throws CIMException {
                return null;
     }
     /*
      * enumInstances:
      * 名前だけでなく、インスタンス全体が返される。
      * 詳細列挙または簡易列挙が可能だが、現在のところ
      * CIMOM は簡易列挙だけを要求する。
      */
     public Vector enumInstances(CIMObjectPath op, boolean deep, CIMClass cc)
             throws CIMException {
         if (op.getObjectName().equalsIgnoreCase("Ex_SimpleInstanceProvider")) 
             {
             Vector instances = new Vector();
             CIMObjectPath cop = new CIMObjectPath(op.getObjectName(),
                     op.getNameSpace());
                 if (loop == 0){
                     cop.addKey("First", new CIMValue("red"));
                     cop.addKey("Last", new CIMValue("apple"));
                     // このクラスを削除する場合は、この次の行を
	                    // コメントにしてコンパイルする。
                     instances.addElement(cop);
                     loop += 1;
                 } else {
                     cop.addKey("First", new CIMValue("red"));
                     cop.addKey("Last", new CIMValue("apple"));
                     // このクラスを削除する場合は、この次の行を
                     // コメントにしてコンパイルする。
                     instances.addElement(cop);
                     cop = new CIMObjectPath(op.getObjectName(),
                             op.getNameSpace());
                     cop.addKey("First", new CIMValue("green"));
                     cop.addKey("Last", new CIMValue("apple"));
                     // このクラスを削除する場合は、この次の行を
                     // コメントにしてコンパイルする。
                     instances.addElement(cop);
                 }
             return instances;
             }
         return new Vector();
     }

     public CIMInstance getInstance(CIMObjectPath op, 
             CIMClass cc, boolean localOnly) throws CIMException {
             if (op.getObjectName().equalsIgnoreCase("Ex_SimpleInstanceProvider"))
             {
                 CIMInstance ci = cc.newInstance();
                 ci.setProperty("First", new CIMValue("yellow"));
                 ci.setProperty("Last", new CIMValue("apple"));
                 return ci;
             }
            return new CIMInstance();
      }

     public Vector execQuery(CIMObjectPath op, String query, int ql, CIMClass cc)
             throws CIMException {
                 throw(new CIMException(CIMException.CIM_ERR_NOT_SUPPORTED));
    }

     public void setInstance(CIMObjectPath op, CIMInstance ci)
             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));
     }
 }


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

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

表 5–3 PropertyProvider インタフェースメソッド

メソッド 

説明 

CIMValue getPropertyValue(CIMObjectPath op, String originClass, String propertyName)

op に指定されたインスタンスの propertyName によって指定されたプロパティの値を含む CIMValue を返す。originClass には、このプロパティを最初に定義した、このクラス階層のクラスの名前を指定する。

void setPropertyValue(CIMObjectPath op, String originClass, String propertyName, CIMValue cv)

op に指定されたインスタンスの propertyName によって指定されたプロパティの値に CIMValue cv を設定する。originClass には、このプロパティを最初に定義した、このクラス階層のクラスの名前を指定する。

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

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

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


例 5–2 プロパティプロバイダの実装

...

public class SimplePropertyProvider implements PropertyProvider{
    public void initialize(CIMOMHandle cimom) 
    throws CIMException {
    }

    public void cleanup() 
    throws CIMException {
    }
    
    public CIMValue getPropertyValue(CIMObjectpath op, string originclass, 
	           string PropertyName){
		    if (PropertyName.equals("A")
		        return new CIMValue("ValueA")
  		  else
			      return new CIMValue("ValueB");
    }
    ...
}
 


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

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

表 5–4 MethodProvider インタフェースメソッド

メソッド 

説明 

CIMValue invokeMethod(CIMObjectPath op, String methodName, Vector inParams, Vector outParams)

CIM Object Manager は、op によって参照されるインスタンス内の methodName が呼び出されると、このメソッドを呼び出す。

inParams は、呼び出されるメソッドへの入力パラメータとなる CIMValues のベクトル、outParams は、呼び出されるメソッドからの出力パラメータとなる CIMValues のベクトル。

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

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

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


例 5–3 メソッドプロバイダの実装

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


アソシエータプロバイダインタフェース (AssociatorProvider)

次の表で、AssociatorProvider インタフェースのメソッドについて説明します。これらのメソッドに渡す引数についての詳細は、関連メソッドを参照してください。

表 5–5 AssociatorProvider インタフェースのメソッド

メソッド 

説明 

Vector associators(CIMObjectPath assocName, CIMObjectPath objectName, String role, String resultRole, boolean includeQualifiers, boolean includeClassOrigin, String[] propertyList)

objectName によって指定されたインスタンスに関連付けられている CIM インスタンスのベクトルを返す。

Vector associatorNames(CIMObjectPath assocName, CIMObjectPath objectName, String role, String resultRole)

objectName によって指定された CIM インスタンスに関連付けられている CIM インスタンスの名前のベクトルを返す。

Vector references(CIMObjectPath assocName, CIMObjectPath objectName, String role, boolean includeQualifiers, boolean includeClassOrigin, String[] propertyList)

objectName によって指定された CIM インスタンスが関与する関連ベクトルを返す。

Vector referenceNames(CIMObjectPath assocName, CIMObjectPath objectName, String role)

objectName によって指定された CIM インスタンスが関与する関連の名前のベクトルを返す。

例 — アソシエータプロバイダの実装

完全な関連付けプロバイダには、すべての AssociatorProvider メソッドを実装する必要があります。わかりやすくするために、次のコード例には、associators メソッドだけを実装しています。CIM Object Manager は、assocNameobjectNameroleresultRoleincludeQualifiersincludeClassOriginpropertyList のそれぞれの値を関連付けプロバイダに渡します。

例 5–4 では、CIM 関連付けクラスの名前と、返される関連付けされたオブジェクトが属する CIM クラスまたはインスタンスを出力します。このプロバイダは、example_teacher クラスと example_student クラスのインスタンスを扱います。


例 5–4 アソシエータプロバイダの実装

public Vector associators(CIMObjectPath assocName,
        CIMObjectPath objectName, 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;
		     }
		 // 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;
		  }
}

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

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

JDK の一部である JNI (Java Native Interface) は、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 を参照してください。

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

プロバイダを作成したら、プロバイダクラスファイルと共有ライブラリファイルの場所を指定し、その後 CIM Object Manager の停止と再起動を行う必要があります。

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

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


      注 –

      ある 1 つのシェルで LD_LIBRARY_PATH 環境変数を設定する場合は、設定した新しい値を認識させるために、そのシェルで CIM Object Manager の停止と再起動を行なってください。



      % setenv LD_LIBRARY_PATH /wbem/provider/
      

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


      % LD_LIBRARY_PATH = /wbem/provider/
      

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

      % cp libnative.so /usr/sadm/lib/wbem% cp native.c /usr/sadm/lib/wbem
      

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

    プロバイダクラスファイルをそれらが定義されているパッケージと同じパスに移動します。たとえば、プロバイダが com.sun.providers.myprovider.* としてパッケージされている場合は、プロバイダクラスファイルを /usr/sadm/lib/wbem/com/sun/providers/myprovider/ に移動します。

  3. Solaris プロバイダの CLASSPATH 変数に、プロバイダクラスファイルがあるディレクトリを設定します。これについては、プロバイダの CLASSPATH を設定する方法を参照してください。

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


    注 –

    ある 1 つのシェルで LD_LIBRARY_PATH 環境変数を設定する場合は、設定した新しい値を認識させるために、そのシェルで CIM Object Manager の停止と再起動を行なってください。



    # /etc/init.d/init.wbem -stop
    

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


    # /etc/init.d/init.wbem -start
    

Solaris プロバイダの CLASSPATH の設定

Solaris プロバイダの CLASSPATH を設定するには、クライアント API を使って Solaris_ProviderPath クラスのインスタンスを作成し、その pathurl プロパティにプロバイダクラスファイルの場所を設定します。Solaris_ProviderPath クラスは \root\system ネームスペースに格納されています。

プロバイダの CLASSPATH には、プロバイダクラスファイルの場所を設定することもできます。さらに、クラスパスには、jar ファイルや、クラスを含む任意のディレクトリを設定できます。CLASSPATH の設定には、Java が使用する標準の URL を使用します。

プロバイダの CLASSPATH

構文 

ディレクトリへの絶対パス 

file:///a/b/c/

CIM Object Manager が起動された、ディレクトリへの相対パス (/)..

file://a/b/c

プロバイダの CLASSPATH を設定する方法
  1. Solaris_ProviderPath クラスのインスタンスを作成します。以下に例を示します。

    /* root\system (ネームスペースの名前) で初期化されたネームスペース
    オブジェクトをローカルホスト上に作成する  */   
    CIMNameSpace cns = new CIMNameSpace("", "root\system"); 
    
    // root\system ネームスペースに root として接続する
    cc = new CIMClient(cns, "root", "root_password");
    
    // Solaris_ProviderPath クラスを取得する
    cimclass = cc.getClass(new CIMObjectPath("Solaris_ProviderPath");
    
    // Solaris_ProviderPath の新しいインスタンスを作成する
    class ci = cimclass.newInstance();

  2. pathurl プロパティにプロバイダクラスファイルの場所を設定します。以下に例を示します。

    ...
    /*  プロバイダの CLASSPATH に //com/mycomp/myproviders/ を設定する */
    ci.setProperty("pathurl", new CIMValue(new String("//com/mycomp/myproviders/")); 
    ...

  3. インスタンスを更新します。以下に例を示します。

    // 更新されたインスタンスを CIM Object Manager に渡す 
    cc.setInstance(new CIMObjectPath(), ci);  

プロバイダの登録

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

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

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

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

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


    注 –

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

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


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


    % mofcomp class_name
    

MOF コンパイラを使って MOF ファイルをコンパイルする方法については、『Solaris WBEM Services の管理』を参照してください。

MOF ファイルの変更

コンパイル済みの MOF ファイルに入っているクラス定義を変更する場合は、MOF ファイルをコンパイルし直す前に、そのクラスを CIM Object Manager Repository から削除する必要があります。削除しないと、クラスがすでに存在するためエラーになり、新しい情報が CIM Object Manager に伝達されません。クラスとクラス属性の削除で説明しているように、CIM WorkShop を使用してクラスを削除することができます。

例 — プロバイダの登録

次の例は、SimpleInstanceProvider によって提供される Ex_SimpleInstanceProvider クラスを CIM Object Manager に宣言する MOF ファイルを示したものです (例 5–1) 。MOF ファイルのプロバイダ名とクラス名は、次の規則に従っていなければなりません。


例 5–5 SimpleInstanceProvider MOF ファイル

// ===================================================================
// Title:       SimpleInstanceProvider
// Filename:    SimpleInstanceProvider.mof
// Description:
// ===================================================================

// ==================================================================
// Pragmas
// ==================================================================
#pragma Locale ("en-US")

// ==================================================================
//   SimpleInstanceProvider
// ==================================================================
[Provider("SimpleInstanceProvider")]
class Ex_SimpleInstanceProvider
{
   // プロパティ
      [Key, Description("First Name of the User")]
   string First;
      [Description("Last Name of the User")]
   string Last;
};


プロバイダの変更

プロバイダクラスは、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
    

WQL 照会の処理

WBEM クライアントは、CIMClient クラスの execQuery メソッドを使って、一連の検索条件に一致するインスタンスを検索します。CIM Object Manager は、CIM Object Manager Repository に格納されている CIM データのクライアント照会を処理すると共に、特定のプロバイダから提供される CIM データの照会をプロバイダに渡します。

すべてのインスタンスプロバイダは、com.sun.wbem.provider20 パッケージにある execQuery インタフェースを実装して、インスタンスプロバイダ自身が提供する動的データのクライアント照会を処理する必要があります。プロバイダは、com.sun.wbem.query パッケージにあるクラスやメソッドを使って、WQL (WBEM Query Language) の照会文字列をフィルタリングすることができます。インデックスを処理するエンティティへのアクセス権を持つプロバイダは、照会文字列をこのエンティティに渡して解析してもらうことができます。

照会 API による照会文字列の解析

com.sun.wbem.query パッケージ中のクラスやメソッドは、WQL パーサーと、解析する WQL 文字列を表しています。このパッケージには、照会文字列内の節を表すクラスと、これらの節の中の文字列を処理するメソッドが含まれています。

現在のところ解析可能な WQL 式のタイプは SELECT 式だけです。SELECT 式には次の部分が含まれています。

WQL の式

次の図は、WQL 式中の節と WBEM クラスの対応を表したものです。

図 5–1 WQL 式を表す WBEM クラス

Graphic

WQL 

WBEM 照会クラス 

SELECT attribute_expression

SelectList

FROM table_attribute

FromExp

WHERE conditional_expression

QueryExp

WQL は、CIM データモデルに基づいて格納されるデータを照会できるようになっています。CIM モデルでは、オブジェクトに関する情報は CIM クラスや CIM インスタンスに格納されます。CIM インスタンスには、名前、データ型、値からなるプロパティを持含めることができます。WQL は、次の表に示すように CIM オブジェクトモデルを SQL テーブルにマップします。

SQL 

WQL 

テーブル 

CIM クラス 

行 

CIM インスタンス 

列 

CIM プロパティ 

CIM の WQL 式は、次の形式で表すことができます。


SELECT FROM WHERE CIM property CIM class propertyA = 40

次はより実際的な WQL 式の例です。



SELECT * FROM Solaris_FileSystem WHERE (Name="home" OR Name="files") AND AvailableSpace > 2000000

SELECT 文

SelectExp クラスは、SELECT 分を表します。

SELECT 文は、情報検索に使用される SQL 文ですが、WQL SELECT 文には、WQL 特有の制約と拡張がいくつかあります。SQL SELECT 文は、通常データベース環境でテーブルから特定の列を検索するのに使用されます。WQL SELECT 文は、単一クラスのインスタンスを検索するのに使用されます。WQL では、複数のクラスに渡る照会はサポートされません。

検索リストは SELECT 式で表されます。SELECT 文には次の形式があります。

SELECT 文 

選択されるもの 

SELECT *

指定されたクラスとそのすべてのサブクラスのすべてのインスタンス。 

SELECT attr_exp, attr_exp...attr_exp

指定されたクラスとそのすべてのサブクラスのすべてのインスタンスのうち、指定された識別子をもっているものだけ。 

FROM 節

FROM 節は、abstract クラス fromExp によって表されます。現在のところ、fromExp の直接のサブクラスは NonJoinExp だけです。NonJoinExp は、1 つのテーブル (CIM クラス) だけを指定した FROM 節を表しています。select 操作はこのテーブルに対して行われます。

FROM 節では、照会文字列に一致するインスタンスが含まれているクラスを指定します。SQL では、FROM 節に修飾子付き属性式を指定します。これが検索するクラスの名前になります。修飾子付き属性式には、そのテーブルとクラスを指定します。現在のところ WQL FROM 節では、非 join 式だけがサポートされます。したがって、WQL FROM 節には 1 つのクラスしか指定できません。

WHERE 節

QueryExp クラスは、その各サブクラスが条件式を表している abstract クラスです。特定の CIMInstance がこれらの条件式に適用されると、ブール値を返します。

WHERE 節は、照会のスコープを狭めるためのものです。WHERE 節には条件式が含まれています。これらの条件式には、プロパティまたはキーワード、演算子、定数が含まれています。WHERE 節には、あらかじめ定義された WQL 演算子のいずれかを指定する必要があります。

SELECT 文の後に追加する WHERE 節の基本的な構文は、次のとおりです。

SELECT FROM WHERE CIM instance CIM class conditional_expression

WHERE 節の条件式は、次の形式です。

 
property operator constant

QueryExp クラスの次の各サブクラスは、WHERE 節における条件式の特定のタイプに対応しています。

WHERE 節の条件式は QueryExp クラスで表されます。条件式はツリー構造になっています。たとえば、条件式 (a=2 and b=3 or c=4) は、次のようなツリー構造で表されます。

QueryExp クラスは照会式ツリーのトップレベルだけを返します (上の例では ORQueryExp)。これによって、プロバイダは、そのクラス内のメソッドを使って照会式ツリーの分岐を下方にたどることができます。

canonize メソッドの使用

プロバイダが WQL 照会文字列を別のエンティティに渡し、この文字列を解析させるには、次のメソッドが便利です。

WQL 照会文字列を解析するプロバイダの作成

照会 API を使って WQL 照会文字列を解析するプロバイダを作成する一般的な手順は、次のとおりです。

WQL 照会文字列を解析するプロバイダを作成する方法
  1. WQL パーサーを初期化します。以下に例を示します。


     
        /* CIM Object Manager から execQuery に渡された
           照会文字列を入力データストリームに読み込む */
        ByteArrayInputStream in = new ByteArrayInputStream(query.getBytes()); 
    
        /* 入力データストリームを使ってパーサーを初期化する */
        WQLParser parser = new WQLParser(in);
           

  2. 照会結果を格納するベクトルを作成します。以下に例を示します。


     
        Vector result = new Vector();

  3. 照会から select 式を取得します。以下に例を示します。


     
        /* querySpecification がパーサーから WQL 式を返す
          (SelectExp)parser が WQL 式を select 式にキャストする */
        SelectExp q = (SelectExp)parser.querySpecification();  

  4. select 式から select リストを取得します。以下に例を示します。


     
        /* SelectExp クラスの SelectList メソッドを使って
           select リストを返す。select リストとは、
           属性または CIM プロパティのリスト */
        SelectList attrs = q.getSelectList();     

  5. From 節を取得します。以下に例を示します。


     
        /* SelectExp クラスの getFromClause メソッドを使って
           From 節を返す。From 節を非 join 式 
           (単一の CIM クラスを表すテーブル) にキャストする */
        NonJoinExp from = (NonJoinExp)q.getFromClause();

  6. enumInstances メソッドを使ってクラスの詳細列挙を返します。以下に例を示します。


     
       /* 指定されたクラス (cc) に属するすべてのインスタンス
          (継承されたプロパティとローカルプロパティを含む) を返す */
        Vector v = new Vector();
        v = enumInstances(op, true, cc, true);
        ...  

  7. 列挙のインスタンスを 1 つずつ処理し、その中で各インスタンスを照会式および select リストと比較します。以下に例を示します。


     
      /* WHERE 節の照会式が CIM インスタンスと 
    	   一致するかを比較する。select リストを CIM インスタンスに 
         適用し、select リストと一致するインスタンス  
         (CIM プロパティのリスト) を結果に追加する。 */
      for (int i = 0; i < v.size(); i++) {
    	  if ((where == null) || // WHERE 節があるか
      	    (where.apply((CIMInstance)v.elementAt(i)) == true)) { 
    	         result.addElement(attrs.apply((CIMInstance)v.elementAt(i)));
       ...        

  8. 照会結果を返します。以下に例を示します。

    return result;

例 — execQuery メソッドの実装

例 5–6 のサンプルプログラムでは、execQuery メソッドによって渡された WQL 文字列を、照会 API を使って解析します。このプログラムは、照会文字列中の Select 式を解析し、クラスを詳細列挙します。そして、列挙の各インスタンスを 1 つずつ処理して、各インスタンスを照会式および select リストと比較します。最後にプログラムは、照会文字列と一致するインスタンスの列挙が含まれているベクトルを返します。


例 5–6 execQuery メソッドを実装するプロバイダ

/*
     * execQuery メソッドは、部分的なキーマッチングに基づく限られた照会 
     * しかサポートしない。照会によって選択されたエントリがないと、
     * 空の Vector を返す
     *
     * @param	op			返される CIM インスタンスの CIM オブジェクトパス
     * @param	query	CIM 照会式
     * @param	ql			CIM 照会言語のインジケータ
     * @param	cc			CIM クラス参照
     *
     * @return	CIM オブジェクトインスタンスのリスト
     *
     * @version    1.19	01/26/00
     * @author	   Sun Microsystems, Inc.
     */
    public Vector execQuery(CIMObjectPath op, 
			    String query, 
			    int ql,
			    CIMClass cc) 
	    throws CIMException {

	ByteArrayInputStream in = new ByteArrayInputStream(query.getBytes());
	WQLParser parser = new WQLParser(in);
	Vector result = new Vector();
	try {
	    SelectExp q = (SelectExp)parser.querySpecification();
	    SelectList attrs = q.getSelectList();
	    NonJoinExp from = (NonJoinExp)q.getFromClause();
	    QueryExp where = q.getWhereClause();

	    Vector v = new Vector();
	    v = enumInstances(op, false, cc, true);

	    // インスタンスをフィルタリングする
	    for (int i = 0; i < v.size(); i++) {
		    if ((where == null) || (where.apply((CIMInstance)v.elementAt(i)) == true)) {
		        result.addElement(attrs.apply((CIMInstance)v.elementAt(i)));
		     } 
	    }
	} catch (Exception e) {
	    throw new CIMException(CIMException.CIM_ERR_FAILED, e.toString());
	}
	return result;
    } // execQuery
}