Solaris WBEM SDK 開発ガイド

第 3 章 クライアントプログラムの記述

この章では、Solaris WBEM SDK クライアント API (javax.wbem.client) を使用して、クライアントプログラムを記述する方法を説明します。次の内容が含まれます。


注 -

WBEM クライアント API (javax.wbem.client) の詳細は、/usr/sadm/lib/wbem/doc/index.html を参照してください。


概要

WBEM クライアントアプリケーションは、javax.wbem.client API を使用して CIM オブジェクトを操作します。クライアントアプリケーションは、CIM API を使用してオブジェクト(クラス、インスタンス、名前空間など) を構築し、続いてそのオブジェクトの初期化またはインスタンス化を実行します。クライアントアプリケーションはクライアント API を使用してオブジェクトを CIM Object Manager に渡し、CIM のクラス、インスタンス、名前空間の作成などの WBEM 操作を要求します。

クライアントアプリケーションの処理手順

クライアントアプリケーションは通常、次の手順で処理を行います。

  1. CIMClient を使用して CIM Object Manager に接続します。クライアントアプリケーションは、WBEM の操作 (CIM クラスの作成や CIM インスタンスの更新など) を実行する必要があるたびに、CIM Object Manager に接続します。詳細は、「クライアント接続の開始と終了」を参照してください。

  2. クライアントAPI を使用して、操作の要求およびプログラミング作業を実行します。アプリケーションの機能セットは、どの処理を要求すべきかを決定します。ほとんどのプログラムが実行するタスクには、インスタンスの作成、削除、更新、オブジェクトの列挙、メソッドの呼び出し、クラス定義の取得、およびエラーの処理が含まれます。クライアントプログラムから、クラスの作成と削除、名前空間の作成と削除、および修飾子の使用を実行することも可能です。詳細は、「基本的なクライアント操作の実行」を参照してください。

  3. CIMClient を使用して CIM Object Manager へのクライアント接続を閉じて、クライアントセッションが使用しているリソースをすべて解放します。詳細は、「クライアント接続の開始と終了」を参照してください。

クライアント接続の開始と終了

クライアントアプリケーションは、最初に CIM Object Manager を使用して接続を確立してから、CIM クラス、CIM インスタンス、CIM 修飾子タイプの追加、変更、削除などの WBEM 操作を実行します。クライアントアプリケーションと CIM Object Manager は、同一のホスト上でも、別のホスト上でも実行可能です。また、複数のクライアントが 1 つの CIM Object Manager に接続を確立することもできます。

名前空間について

アプリケーションが CIM Object Manager への接続を行う場合、名前空間への接続も行う必要があります。後続の操作はすべてこの名前空間上で行われます。名前空間は、ディレクトリに似た構造を持ち、内部にクラス、インスタンス、および修飾子タイプを含みます。名前空間内のオブジェクト名は、すべて一意にする必要があります。Solaris WBEM SDK をインストールすると、次の 4 つの名前空間が作成されます。

クライアント接続の開始

クライアント接続を開始する場合、CIMClient クラスを使用して CIM Object Manager に接続します。CIMClient クラスは、次の 4 つの引数を取ります。


例 3-1 ルートアカウントへの接続

次の例では、アプリケーションは、デフォルトの名前空間のローカルホストで稼働する CIM Object Manager に接続します。アプリケーションは、デフォルトの名前空間のすべての CIM オブジェクトに読み取り権および書き込み権を持つ、ルートアカウント用 UserPrincipal オブジェクトを作成します。

{
    ...

  /* 2 つの NULL 文字を使用して初期化された名前空間オブジェクトを作成する。
     2 つの NULL 文字はデフォルトのホスト (ローカルホスト) とデフォルトの
     名前空間 (root\cimv2) を表す */
 
    CIMNameSpace cns = new CIMNameSpace("", "");

    UserPrincipal up = new UserPrincipal("root");
    PasswordCredential pc = new PasswordCredential("root_password"); 
    /* root パスワードを使用し、スーパーユーザーとして名前空間に接続する */
 
    CIMClient cc = new CIMClient(cns, up, pc);
    ...
}



例 3-2 ユーザーアカウントへの接続

次の例では、アプリケーションは、最初に CIMNameSpaceUserPrincipal、および PasswordCredential オブジェクトのインスタンスを作成します。次に、 CIMClient クラスを使用して CIM Object Manager に接続し、ホスト名、名前空間、ユーザー名、およびパスワード資格を CIM Object Manager に渡します。

{
    ...
    /* ホスト happy 上の A (名前空間名) 
       によって初期化される名前空間オブジェクトを作成する */
    CIMNameSpace cns = new CIMNameSpace("happy", "A");
    UserPrincipal up = new UserPrincipal("Mary");
    PasswordCredential pc = new PasswordCredential("marys_password");
    CIMClient cc = new CIMClient(cns, up, pc);
    ...
    ...
} 



例 3-3 RBAC の役割 ID の認証

SolarisUserPrincipal および SolarisPasswordCredential クラスを使用して、ユーザーの役割 ID を認証します。次の例では、Mary の役割を Admin として認証します。

{
...
CIMNameSpaceRole cns = new CIMNameSpace("happy", "A");
SolarisUserPrincipal sup = new SolarisUserRolePrincipal("Mary", "Admin");
SolarisPswdCredential spc = new
        SolarisPswdCredential("marys_password", "admins_password");
CIMClient cc = new CIMClient(cns, sup, spc);


クライアント接続の終了

CIMClient クラスの close メソッドを使用して、クライアント接続を閉じ、セッションが使用したサーバーリソースを解放します。


例 3-4 クライアント接続の終了

次の例では、クライアント接続を閉じます。インスタンス変数 cc は、クライアント接続を表します。

...
cc.close();
...

基本的なクライアント操作の実行

このセクションでは、javax.wbem.client API を使用して、操作の要求および一般的なプログラミング作業を実行する方法を説明します。

インスタンスの作成

既存のクラスのインスタンスを作成するには、newInstance メソッドを使用します。既存のクラスがキープロパティを保持する場合、アプリケーションはそのプロパティを一意の値に設定する必要があります。インスタンスは、必要に応じてそのクラスに定義されていない別の修飾子を定義することもできます。それらの修飾子をインスタンスまたは特定のインスタンスプロパティ用に定義できますが、クラス宣言内で定義する必要はありません。

アプリケーションは、クラスに定義されている一連の修飾子を getQualifiers メソッドを使用して取得できます。


例 3-5 インスタンスの作成

次の例では、newInstance メソッドを使用して、 CIM インスタンスを表す Java クラスを作成します (たとえば、 Solaris_Package クラスから Solaris パッケージを作成する)。

...
{ 
/* ローカルホストの root\cimv2 名前空間の 
   CIM Object Manager に接続。root\cimv2 名前空間内の
   オブジェクトに対する書き込み権を持つアカウントのユーザー名とパスワードを
   指定する */
 
    UserPrincipal up = new UserPrincipal("root");
    PasswordCredential pc = new PasswordCredential("root_password"); 
    /* root パスワードを使用して、スーパーユーザーとして名前空間に
       接続する */
 
    CIMClient cc = new CIMClient(cns, up, pc);
...
 
// Solaris_Package クラスを取得
cimclass = cc.getClass(new CIMObjectPath("Solaris_Package"),  
                                          true, true, true, null);
 
/* プロパティのデフォルト値を使用して生成された Solaris_Package 
   クラスの新しいインスタンスを作成する。このクラスのプロバイダが
   デフォルト値を指定しないと、プロパティの値は NULL 文字になるため、
   明示的に設定する必要がある */
 
 CIMInstance ci = cc.createInstance (new CIMObjectPath("Solaris_Package"), 
 ci);
}
... 


インスタンスの削除

インスタンスの削除には、deleteInstance メソッドを使用します。


例 3-6 インスタンスの削除

次の例では、クライアントアプリケーションを CIM Object Manager に接続し、CIMObjectPath を使用して削除するオブジェクトの CIM オブジェクトパスを含むオブジェクトを構築し、enumerateInstance を使用してインスタンスおよびサブクラスのすべてのインスタンスを取得し、 deleteInstance を使用して各インスタンスを削除します。

 
import java.rmi.*;
import java.util.Enumeration;

import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import javax.wbem.cim.CIMInstance;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;

import javax.wbem.client.CIMClient;
import javax.wbem.client.PasswordCredential;
import javax.wbem.client.UserPrincipal;

/** 
 * 指定されたクラスのインスタンスをすべて返す。
 * このプログラム例では、5 つの必須コマンド行引数、hostname (args[0])、
 * username (args[1])、password (args[2]) namespace (args[3])、
 * および classname (args[4]) を取り、
 * 指定されたクラス名のインスタンスをすべて削除する。
 * 指定されたユーザー名は、
 * 指定された名前空間への書き込み権を持つ必要がある
 */
public class DeleteInstances {
    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        // 5 つの引数が指定されない場合、使用法を表示して終了する
        if (args.length != 5) {
           System.out.println("Usage: DeleteInstances host username " +
                              "password namespace classname ");
           System.exit(1);
           }
       try {
          // args[0] にはホスト名が、args[3] には名前空間 
          // が含まれる。指定されたホスト上の指定された
          // 名前空間を指す CIMNameSpace (cns) を作成する
          CIMNameSpace cns = new CIMNameSpace(args[0], args[3]);

         // args[1] と args[2] にはユーザー名およびパスワードが含まれる。
         // ユーザー名を使用して UserPrincipal (up) を作成し、
         // パスワードを使用して PasswordCredential を作成する
         UserPrincipal up = new UserPrincipal(args[1]);
         PasswordCredential pc = new PasswordCredential(args[2]);

        // CIM Object Manager に接続して、
        // 作成した CIMNameSpace、UserPrincipal、および 
        // PasswordCredential オブジェクトを渡す
        cc = new CIMClient(cns, up, pc);

        // クラス名 (args[4]) を取得し、CIMObjectPath を作成する
        CIMObjectPath cop = new CIMObjectPath(args[4]);

        // クラスおよびそのサブクラスすべてのインスタンスオブジェクトパス
        // すべての列挙を取得する。インスタンスオブジェクトパスは、
        // CIM Object Manager がインスタンス検出に
        // 使用する参照を指す
        Enumeration e = cc.enumerateInstanceNames(cop);


        // 列挙されたインスタンスオブジェクトパスを繰り返し処理する。
        // オブジェクトを作成して列挙された各インスタンスのオブジェクトパス
        // を格納し、インスタンスの出力後に削除する
        while (e.hasMoreElements()) {
           CIMObjectPath  op = (CIMObjectPath)e.nextElement();
           System.out.println(op);
           cc.deleteInstance(op);
        } // while 終了 
  } catch (Exception e) {
       // 例外が発生した場合はそれを出力する
       System.out.println("Exception: "+e);
  } // catch 終了

 // セッションを閉じる
 if (cc != null) {
     cc.close();
       }
    }
}


インスタンスの取得と設定

クライアントアプリケーションが CIM Object Manager から CIM インスタンスを取得する場合には、通常 getInstance メソッドが使用されます。クラスのインスタンスが作成されるときに、インスタンスはその派生元クラスとそのクラス階層にあるすべての親クラスのプロパティを継承します。getInstance メソッドはブール値引数 localOnly を受け取ります。localOnly が true の場合、getInstance メソッドは指定されたインスタンスによって継承されたプロパティ以外のプロパティだけを返します。

既存のインスタンスを更新する場合は、setInstance メソッドを使用します。


例 3-7 インスタンスの取得と設定

次の例では、列挙されたオブジェクトパスのインスタンスを取得し、各インスタンス内で b のプロパティ値を 10 に更新し、更新したインスタンスを CIM Object Manager に渡します。

...
{
    // オブジェクトパス、myclass という CIM 名を含むオブジェクト 
    // を作成する
    CIMObjectPath cop = new CIMObjectPath("myclass"); 

    /* 列挙内の各インスタンスオブジェクトパスのインスタンスを取得し、
       各インスタンス内で b のプロパティ値を 10 に更新し、
       更新したインスタンスを CIM Object Manager に渡す */
    
    while(e.hasMoreElements()) {
           CIMInstance ci = cc.getInstance((CIMObjectPath)(e.nextElement
                                          ()),true, true, true, null);
           ci.setProperty("b", new CIMValue(new Integer(10)));
           cc.setInstance(new CIMObjectPath(),ci);
           }
}
...


プロパティの取得と設定

CIM プロパティは、CIM クラスの特性を記述する値です。プロパティは、プロパティ値を取得する機能と、プロパティ値を設定する機能の組み合わせとして考えることができます。


例 3-8 プロパティの取得

次の例では、enumerateInstanceNames を使用して Solaris プロセッサのすべてのインスタンス名を返し、getProperty を使用して各インスタンスの現在のクロック速度の値を取得し、println を使用して出力します。

...
{
/* オブジェクト CIMObjectPath を作成して、
Solaris_Processor クラスの名前を格納する */ 
 
CIMObjectPath cop = new CIMObjectPath("Solaris_Processor"); 
 
/* CIM Object Manager は、Solaris_Processor クラスのインスタンス名を
   含む列挙を返す */
 
Enumeration e = cc.enumerateInstanceNames(cop); 
 
/* インスタンスオブジェクトパスの列挙を繰り返し処理する。
   getProperty メソッドを使用して、Solaris プロセッサごとの
   現在のクロック速度の値を取得する */
 
while(e.hasMoreElements()) {
        CIMValue cv = cc.getProperty(e.nextElement(CIMObjectPath), 
                                     "CurrentClockSpeed");
        System.out.println(cv);
}
...
}
 



例 3-9 プロパティの設定

次の例では、すべての Solaris_UserTemplate インスタンスの初期シェル 値を設定します。このコードセグメントは、enumerateInstanceNames を使用して Solaris_UserTemplate のすべてのインスタンス名を取得し、setProperty を使用して各インスタンスの初期シェル値を設定します。

...
{
    /* オブジェクト (CIMObjectPath) を作成して
    Solaris_Processor クラスの名前を格納する */ 
 
    CIMObjectPath cop = new CIMObjectPath("Solaris_UserTemplate"); 
 
    /* CIM Object Manager は、Solaris_UserTemplate クラスおよび
       そのサブクラスすべてのインスタンス名を含む列挙を返す */
 
    Enumeration e = cc.enumerateInstanceNames(cop); 
 
    /* インスタンスオブジェクトパスの列挙を繰り返し
処理する。setProperty メソッドを使用して、初期シェル値を
Solaris_UserTemplate インスタンスごとに /usr/bin/sh に
設定する */
 
   for (; e.hasMoreElements(); cc.setProperty(e.nextElement(), 
        "/usr/bin/sh", new CIMValue(new Integer(500))));
 
...
}
 


オブジェクトの列挙

列挙とはオブジェクトの集合です。列挙は一度に 1 つずつ取り出すことができます。クラス、クラス名、インスタンス、インスタンス名、および名前空間を列挙できます。次の表に示すように、列挙の結果は使用するメソッドや引数によって異なります。

オブジェクトの列挙

表 3-1 オブジェクトの列挙

メソッド 

引数なし 

deep

localOnly

enumerateClasses

path に指定されたクラスの内容を返す

true の場合:指定されたクラスのサブクラスの内容を返す。ただし、クラス自体は返さない

true の場合:指定されたクラスの継承しないプロパティおよびメソッドのみを返す

false の場合:指定されたクラスの直接のサブクラスの内容を返す

false の場合:指定されたクラスのプロパティをすべて返す

enumerateInstances

path に指定されたクラスのインスタンスを返す

true の場合:指定されたクラスおよびそのサブクラスのインスタンスを返す

true の場合:指定されたクラスのインスタンスの継承しないプロパティのみを返す

false の場合:指定されたクラスおよびそのサブクラスのインスタンスを返すサブクラスのプロパティは、フィルタ処理される

false の場合:指定されたクラスのインスタンスのプロパティをすべて返す

enumerateClassNames

path に指定されたクラスの名前を返す

true の場合:指定されたクラスから派生したすべてのクラスの名前を返す

なし 

false の場合:指定されたクラスの第 1 レベルの子の名前のみを返す

なし 

enumerateInstanceNames

path に指定されたクラスのインスタンスの名前を返す

なし 

なし 

なし 

なし 

enumNameSpace

path に指定された名前空間内の名前空間のリストを返す

true の場合:指定された名前空間内の名前空間階層全体を返す

なし 

false の場合:指定された名前空間の第 1 レベルの子のみを返す

なし 


例 3-10 列挙クラス

次のプログラム例は、クラスおよびそのサブクラスの内容を返します。

...
{
    /* CIMObjectPath オブジェクトを作成し、 
    列挙する CIM クラスの名前 (myclass) を使用して
初期化する */
     
    CIMObjectPath cop = new CIMObjectPath(myclass); 
     
    /* この列挙には、列挙されたクラス内のクラスとサブクラスが
       含まれる (deep=true)。この列挙は、クラスおよびサブクラスごとに
       継承されないメソッドおよびプロパティのみを返す 
       (localOnly は true)*/
 
    Enumeration e = cc.enumerateClasses(cop, true, true);  
}
...


例 3-11 クラスおよびインスタンスの列挙

次のプログラム例は、クラスおよびインスタンスの列挙で deep および shallow (deep=false) が指定された場合の動作を示します。 localOnly フラグは、クラスおよびインスタンスの名前ではなく、クラスおよびインスタンスの内容を返します。

import java.rmi.*;
import java.util.Enumeration;

import javax.wbem.client.CIMClient;
import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import javax.wbem.cim.CIMInstance;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;

import javax.wbem.client.UserPrincipal;
import javax.wbem.client.PasswordCredential;


/** 
 * このプログラム例では、クラスとインスタンスを列挙する。
コマンド行から渡されるクラスについて、deep および 
 * shallow 列挙を実行する
 */
public class ClientEnum {

    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        CIMObjectPath cop = null;
        if (args.length < 4) {
            System.out.println("Usage: ClientEnum host user passwd " + 
                               "classname");
            System.exit(1);
   }
   try {
       CIMNameSpace cns = new CIMNameSpace(args[0]);
       UserPrincipal up = new UserPrincipal(args[1]);
       PasswordCredential pc = new PasswordCredential(args[2]);
       cc = new CIMClient(cns, up, pc);


       // コマンド行からクラス名を取得する
       cop = new CIMObjectPath(args[3]);    
       // クラスの deep 列挙を実行する
       Enumeration e = cc.enumerateClasses(cop, true, true, true, 
                                           true);
       // クラスのサブクラスをすべて出力する
       while (e.hasMoreElements()) {
           System.out.println(e.nextElement());
       }
       System.out.println("+++++");
       // クラスの shallow 列挙を実行する
       e = cc.enumerateClasses(cop, false, true, true, true);
       // 第 1 レベルのサブクラスを出力する
       while (e.hasMoreElements()) {
           System.out.println(e.nextElement());
       }
       System.out.println("+++++");
       // クラスのインスタンスの deep 列挙を実行する
       e = cc.enumerateInstances(cop, false, true, true, true, null);
       // クラスおよびそのサブクラスのインスタンスを
       // すべて出力する 
       while (e.hasMoreElements()) {
           System.out.println(e.nextElement());
       }
       System.out.println("+++++");
       // クラスのインスタンスの shallow 列挙を実行する
       e = cc.enumerateInstances(cop, false, false, true, true, null);
       // クラスのインスタンスをすべて出力する
       while (e.hasMoreElements()) {
           System.out.println(e.nextElement());
       }
       System.out.println("+++++");

       e = cc.enumerateInstanceNames(cop);
       while (e.hasMoreElements()) {
           System.out.println(e.nextElement());
       }
       System.out.println("+++++");

       e = cc.enumerateInstanceNames(cop);
       while (e.hasMoreElements()) {
           CIMObjectPath opInstance = (CIMObjectPath)e.nextElement();
           CIMInstance ci = cc.getInstance(opInstance, false, 
                                           true, true, null);
           System.out.println(ci); 
       }
       System.out.println("+++++");

  }
  catch (Exception e) {
      System.out.println("Exception: "+e);
  }

 // セッションを閉じる
 if (cc != null) {
     cc.close();
  }
 }
}


例 3-12 クラス名の列挙

次のプログラム例は、クラス名およびサブクラス名のリストを返します。

...
{
    /* CIMObjectPath オブジェクトを作成し、 
    列挙する CIM クラスの名前 (myclass) を使用して初期化する */
    CIMObjectPath cop = new CIMObjectPath(myclass); 
    
    /* この列挙には、列挙されたクラス内のクラスおよびサブクラスの
       名前が含まれる */
    Enumeration e = cc.enumerateClassNames(cop, true);
}
... 



例 3-13 名前空間の列挙

このプログラム例は、CIMClient クラスの enumNameSpace メソッドを使用して、名前空間とその中に含まれるすべての名前空間の名前を出力します。

 
import java.rmi.*;
import java.util.Enumeration;

import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import javax.wbem.cim.CIMInstance;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;

import javax.wbem.client.CIMClient;
import javax.wbem.client.PasswordCredential;
import javax.wbem.client.UserPrincipal;


/** 
 *
 */
public class EnumNameSpace {
    public static void main(String args[]) throws CIMException {
        CIMClient cc = null;
        // 4 つの引数が指定されない場合、使用法を表示して終了する
        if (args.length < 4) {
            System.out.println("Usage: EnumNameSpace host username " +
                               "password namespace");
            System.exit(1);
            }
        try {
            // args[0] にはホスト名が含まれる。指定されたホスト上の
            // 指定された名前空間を指す。
            // CIMNameSpace (cns) を作成する
            CIMNameSpace cns = new CIMNameSpace(args[0], "");

           // args[1] と args[2] にはユーザー名およびパスワードが含まれる。
           // ユーザー名を使用して UserPrincipal (up) を、
           // パスワードを使用して PasswordCredential を作成する
           UserPrincipal up = new UserPrincipal(args[1]);
           PasswordCredential pc = new PasswordCredential(args[2]);

           // CIM Object Manager に接続して
           // 作成した CIMNameSpace、UserPrincipal、および 
           // PasswordCredential オブジェクトを渡す
           cc = new CIMClient(cns, up, pc);

           // 名前空間 (args[3]) を使用して CIMObjectPath を作成する
           CIMObjectPath cop = new CIMObjectPath("", args[3]);

           // 名前空間を列挙する
           Enumeration e = cc.enumNameSpace(cop);
           while (e.hasMoreElements()) {
               System.out.println((CIMObjectPath)e.nextElement());
           } // while の終了

           } catch (Exception e) {
              // 例外が発生した場合はそれを出力する
              System.out.println("Exception: "+ e);
           } // catch の終了

          // セッションを閉じる
          if (cc != null) {
              cc.close();
        }
    }
}


関連の作成

関連とは、コンピュータやそのハードディスクなどの管理される複数のリソース間の関係を表したものです。この関係は、関連修飾子を含む特殊なクラス型である関連クラス内で抽象化されます。オブジェクト自体に影響を与えることなく、関連クラスを追加または変更できます。

図 3-1 TeacherStudent 関連 1

Graphic

図 3–1 に、Teacher Student という 2 つのクラスを示します。両方のクラスは、TeacherStudent 関連によってリンクされています。TeacherStudent 関連には、次の 2 つの参照が存在します。

関連メソッド

CIMClient 内の関連メソッドは、クライアントとインスタンス間の関連 (関係) に関する情報を返します。次の表では、これらのメソッドについて説明します。

表 3-2 関連メソッド

メソッド 

説明 

associators

指定された CIM クラスやインスタンスに関連付けられている CIM クラスやインスタンスを取得する 

associatorNames

指定された CIM クラスやインスタンスに関連付けられている CIM クラスやインスタンスの名前を取得する 

references

指定された CIM クラスやインスタンスを参照する関連クラスやインスタンスを取得する 

referenceNames

指定された CIM クラスやインスタンスを参照する関連クラスやインスタンスの名前を取得する 

これらのメソッドは、1 つの必須引数 CIMObjectPath を取ります。この引数には、検索する関連や、関連付けされたクラスまたはインスタンスを持つソースの CIM クラスまたは CIM インスタンスの名前を指定します。CIM Object Manager は、関連や関連づけされたクラスまたはインスタンスを検出できない場合、何も返しません。

図 3-2 TeacherStudent 関連 2

Graphic

図 3–2では、associators および associatorNames メソッドが、Teacher および Student クラスに関連付けられたクラスの情報を返します。references および referenceNames メソッドは、Teacher および Student クラス間の関連に関する情報を返します。

表 3-3 TeacherStudent メソッド

例 

出力 

説明 

associators(Teacher, null, null, null, null, false, false, null)

Student クラス

関連付けられているクラスを返す。Student は、TeacherStudent 関連によって Teacher とリンクされている

associators(MathTeacher, null, null, null, null,,false, false, null)

Student

関連付けられているクラスを返す。Teacher は、TeacherStudent 関連によって Student とリンクされている。Math TeacherArt Teacher は、Teacher から TeacherStudent 関連を継承する

associatorNames(Teacher, null, null, null, null)

Student クラスの名前

関連付けられているクラスの名前を返す。Student は、TeacherStudent 関連によって Teacher とリンクされている

references(Student , null, null. false, false, null)

TeacherStudent

Student が関与している関連を返す

references(Teacher , null, null. false, false, null)

TeacherStudent

Teacher が関与している関連を返す

references(Teacher , null, null, false, false, null)

TeacherStudent

Teacher が関与している関連を返す

referenceNames(Teacher , null, null)

TeacherStudent クラスの名前

Teacher が関与している関連の名前を返す

referenceNames(Teacher , null, null)

TeacherStudent クラスの名前

Teacher が関与している関連の名前を返す


注 -

associatorNames および referenceNames メソッドは、引数 includeQualifiersincludeClassOrigin、および propertyList を取りません。インスタンスまたはクラスの名前だけ (内容全体ではなく) を返すメソッドには、これらの引数は関係ないからです。


関連メソッドへのクラスの引き渡し

クラス名を指定する場合、そのモデルパスを指定します。モデルパスには、クラスの名前空間、クラス名、およびキーが含まれます。キーは、管理リソースを一意に識別するプロパティまたはプロパティのセットです。キープロパティは、key 修飾子によって示されます。次にモデルパスを示します。

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

このモデルパスには、以下が指定されています。

関連メソッドへのインスタンスの引き渡し

enumerateInstances メソッドを使用して、所定のクラスのすべてのインスタンスを返し、ループ構造を使用して各インスタンスを処理します。ループでは、各インスタンスを関連メソッドに渡すことができます。


例 3-14 インスタンスの引き渡し

次の例では、op クラスとそのサブクラス内のインスタンスを列挙し、while ループを使って、各インスタンスを CIMObjectPath (op) にキャストし、 associators メソッドへの最初の引数として渡します。

 {
    ...
    Enumeration e = cc.enumerateInstances(op, true);
    while (e.hasMoreElements()) {
        op = (CIMObjectPath)e.nextElement();
        Enumeration e1 = cc.associators(op, null, null, 
                null, null, false, false, null);
    ...
    }           

関連メソッドでのオプション引数の使用

関連メソッドでオプション引数を使用して、返されるクラスやインスタンスをフィルタ処理できます。すべてのパラメータが処理されるまで、オプションの各パラメータ値は、その結果をフィルタ処理のために次のパラメータに渡します。

任意の 1 つのオプションパラメータ、またはその組み合わせた値を渡すことができます。各パラメータには値または null を指定する必要があります。返されるクラスやインスタンスをフィルタ処理するパラメータには、assocClassresultClassroleresultRole があります。これらの引数を使用すると、これらのパラメータに指定された値と一致するクラスやインスタンスだけが返されます。返されるクラスやインスタンスに含まれている情報をフィルタ処理するパラメータには、includeQualifiersincludeClassOriginpropertyList があります。

メソッドの呼び出し

プロバイダによってサポートされるクラス内のメソッドを呼び出すには、invokeMethod インタフェースを使用します。メソッドのシグニチャーを取得するには、最初にそのメソッドが属するクラスの定義を取得する必要があります。invokeMethod メソッドは CIMValue を返します。呼び出したメソッドが戻り値を定義していない場合には、戻り値は null です。

invokeMethod インタフェースは、次の表に示す 4 つの引数を受け取ります。

表 3-4 invokeMethod パラメータ

パラメータ 

データ型 

説明 

name

CIMObjectPath

インスタンス名。このインスタンスでメソッドを呼び出す 

methodName

String

呼び出すメソッド名 

inParams

Vector

メソッドに渡す入力パラメータ 

outParams

Vector

メソッドから受け取る出力パラメータ 


例 3-15 メソッドの呼び出し

次の例では、CIM_Service クラスのインスタンス (デバイスやソフトウェアの機能を管理するサービス) を取得してから、invokeMethod メソッドを使って各サービスを停止します。

{
    ...
    /* CIM_Service クラスの 
CIM オブジェクトパスを CIM Object Manager に渡す。
このクラスで定義されたメソッドを呼び出す */ 
     
    CIMObjectPath op = new CIMObjectPath("CIM_Service"); 
     
    /* CIM Object Manager は インスタンスオブジェクトパスの列挙、
CIM_Service クラスのインスタンス名を]
返す */
     
    Enumeration e = cc.enumerateInstanceNames (op, true); 
     
    /* インスタンスオブジェクトパスの列挙を繰り返し処理する */
     
    while(e.hasMoreElements()) {
                // インスタンスを取得する
                CIMObjectPath op = (CIMObjectPath) e.nextElement();
                //Stop Service メソッドを呼び出して CIM サービスを停止する
                cc.invokeMethod("StopService", null, null);
              }
}
 


クラス定義の取得

CIM クラスを取得するには getClass メソッドを使用します。クラスを作成すると、その派生元クラスとそのクラス階層のすべての親クラスのメソッドとプロパティを継承します。getClass メソッドは、ブール値引数 localOnly を受け取ります。


例 3-16 クラス定義の取得

このプログラム例は、次のメソッドを使用してクラス定義を取得します。

import java.rmi.*;
import javax.wbem.client.CIMClient;
import javax.wbem.cim.CIMInstance;
import javax.wbem.cim.CIMValue;
import javax.wbem.cim.CIMProperty;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;
import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import java.util.Enumeration;
/**
 * コマンド行で指定されたクラスを取得する。作業を
 * デフォルトの名前空間 root\cimv2 で行う
 */
public class GetClass {
    public static void main(String args[]) throws CIMException {
      CIMClient cc = null;
      try {
         CIMNameSpace cns = new CIMNameSpace(args[0]);
         UserPrincipal up = new UserPrincipal("root");
         PasswordCredential pc = new PasswordCredential("root_password");
         cc = new CIMClient(cns);
         CIMObjectPath cop = new CIMObjectPath(args[1]);
             // 指定されたクラスに対してローカルなメソッド 
             // とプロパティのみを返す (localOnly は true)
         cc.getClass(cop, true);
      } catch (Exception e) {
         System.out.println("Exception: "+e);
      }
      if(cc != null) {
         cc.close();
        }
    }
}


例外の処理

CIMClient メソッドは、CIMException、つまりエラー状態をスローします。CIM Object Manager は、Java の例外処理を使用して WBEM 固有の例外の階層を作成します。CIMException クラスは、CIM 例外の基底クラスです。CIMException 以外の CIM 例外クラスは、CIMException クラスのサブクラスです。

CIM 例外の各クラスは、API コードが処理する特定のエラー状態を定義します。CIMException は、エラーコードおよび例外に関連したパラメータを取得するメソッドを保持します。CIMException クラスの詳細は、 /usr/sadm/lib/wbem/doc/index.html を参照してください。

名前空間の作成

Solaris WBEM SDK のインストールにより、標準の CIM (MOF) ファイルがデフォルトの名前空間にコンパイルされます。新しい名前空間を作成する場合は、その名前空間にオブジェクトを作成する前に適切な CIM .mof ファイルを新しい名前空間にコンパイルする必要があります。たとえば、標準の CIM 要素を使用するクラスを作成する場合は、名前空間に CIM コアスキーマをコンパイルします。CIM アプリケーションスキーマを拡張するクラスを作成する場合は、名前空間に CIM アプリケーションをコンパイルします。


例 3-17 名前空間の作成

次の例では、2 段階の処理を実行して、既存の名前空間内に名前空間を作成します。

  1. 名前空間の作成時に、CIMNameSpace メソッドが CIM Object Manager に渡すパラメータを含む名前空間オブジェクトを作成します。

  2. CIMClient クラスは、CIM Object Manager に接続して名前空間オブジェクトを渡します。CIM Object Manager は、名前空間オブジェクトに含まれるパラメータを使用して名前空間を作成します。

{
    ...
    /* クライアント上で名前空間オブジェクトを作成し、コマンド行から
渡されるパラメータを格納する。args[0] にはホスト名 (たとえば myhost) が、
args[1] には親の名前空間 (たとえば最上位ディレクトリ) が含まれる */
     
    CIMNameSpace cns = new CIMNameSpace (args[0], args[1]); 

    UserPrincipal up = new UserPrincipal("root");
    PasswordCredential pc = new PasswordCredential("root_password"); 
     
    /* CIM Object Manager に接続し、3 つのパラメータを渡す。
3 つのパラメータとは、ホスト名 (args[0]) および親の名前空間名 (args[1]) 
を含む名前空間オブジェクト (cns)、ユーザー名文字列 (args[3])、
およびパスワード文字列 (args[4]) を指す */
     
    CIMClient cc = new CIMClient (cns, up, pc);
     
    /* CIM Object Manager に、NULL 文字列 (ホスト名) と args[2]の
子名前空間の名前 (たとえば secondlevel) を含む
別の名前空間オブジェクトを渡す */
     
    CIMNameSpace cop = new CIMNameSpace("", args[2]);
    
    /* myhost の最上位の名前空間に args[2] として渡された名前で、
新しい名前空間を作成する /*
     
    cc.createNameSpace(cop);
    ...
} 


名前空間の削除

名前空間を削除するには、deleteNameSpace メソッドを使用します。

基底クラスの作成


注 -

MOF 言語を使用して基底クラスを作成することもできます。MOF の構文に慣れている場合は、テキストエディタを使用して MOF ファイルを作成し、次に MOF コンパイラを使用してそのファイルを Java クラスにコンパイルします。詳細は、第 2 章「MOF コンパイラを使用した JavaBeans の作成」を参照してください。


CIM クラスを表す Java クラスを作成するには、CIMClass クラスを使用します。ほとんどの基底クラスは、クラス名およびキープロパティまたは abstract 修飾子を指定するだけで宣言できます。ただし、ほとんどのクラスには、クラスのデータを表すプロパティが含まれます。プロパティを宣言するには、プロパティのデータ型、名前、およびオプションのデフォルト値を含めます。プロパティのデータ型は、CIMDataType のインスタンスである必要があります。

プロパティには、キープロパティであることを示すキー修飾子を指定できます。キープロパティは、クラスのインスタンスを一意に定義します。インスタンスを持てるのは、キーが指定されたクラスだけです。そのため、キープロパティが定義されないクラスは、abstract クラスとしてしか使用できません。新しい名前空間内でクラスにキープロパティを定義する場合は、最初にコア MOF ファイルをその名前空間にコンパイルする必要があります。コア MOF ファイルには、標準の CIM 修飾子 (キー修飾子など) の宣言が含まれます。

クラス定義は、別名、修飾子、修飾子フレーバなどの MOF 機能が含まれることにより複雑化します。

クラスの削除

クラスを削除するには、CIMClientdeleteClass メソッドを使用します。クラスを削除すると、 CIMException がスローされます。


注 -

基底クラスを削除する場合、最初に既存のサブクラスまたはインスタンスをすべて削除しておく必要があります。



例 3-18 クラスの削除

このプログラム例は、deleteClass メソッドを使用して、デフォルトの名前空間 root\cimv2 にあるクラスを削除します。このプログラムは、4 つの必須文字列引数 (hostnameclassnameusername、および password) を取ります。このプログラムを実行するユーザーは、root\cimv2 名前空間への書き込み権を持つアカウントのユーザー名とパスワードを指定する必要があります。

 
import javax.wbem.cim.CIMClass;
import javax.wbem.cim.CIMException;
import javax.wbem.cim.CIMNameSpace;
import javax.wbem.cim.CIMObjectPath;
import javax.wbem.client.CIMClient;
import javax.wbem.client.UserPrincipal;
import javax.wbem.client.PasswordCredential;

import java.rmi.*;
import java.util.Enumeration;

/**
 * コマンド行宇で指定されたクラスを削除する。
 * デフォルトの名前空間 root\cimv2 で作業を行う
 */
public class DeleteClass {
    public static void main(String args[]) throws CIMException {
       CIMClient cc = null;
       // 4 つの引数が指定されていない場合、使用法を表示して終了する
       if (args.length != 4) {
           System.out.println("Usage: DeleteClass host className " +
                              "username password"); 
           System.exit(1);
       }
       try {
          // args[0] にはホスト名が含まれる。指定されたホスト上の
          // デフォルトの名前空間を指す CIMNameSpace (cns) を作成する
          CIMNameSpace cns = new CIMNameSpace(args[0]);

          // args[2] と args[3] には、ユーザー名およびパスワードが含まれる。
          // ユーザー名を使用して UserPrincipal (up) を、
          // パスワードを使用して PasswordCredential を作成する
          UserPrincipal up = new UserPrincipal(args[2]);
          PasswordCredential pc = new PasswordCredential(args[3]);

          cc = new CIMClient(cns, up, pc);

          // クラス名 (args[4]) を取得し、CIMObjectPath を作成する
          CIMObjectPath cop = new CIMObjectPath(args[1]);
          // クラスを削除する
          cc.deleteClass(cop);
   }
   catch (Exception e) {
          System.out.println("Exception: "+e);
   }
   if (cc != null) {
       cc.close();
       }
    }
}

アクセス制御の設定

ユーザーまたは名前空間ごとに、アクセス制御を設定できます。次のアクセス制御クラスは、root\security 名前空間に格納されます。

Solaris_UserACL クラスのインスタンスを作成し、そのインスタンスのアクセス権を変更することにより、名前空間内の CIM オブジェクトへの各ユーザーのアクセス制御を設定できます。同様に、Solaris_NameSpaceACL クラスのインスタンスを作成し、createInstance メソッドを使用してそのインスタンスへのアクセス権を設定することにより、名前空間へのアクセス制御を設定できます。

これら 2 つのクラスを結び付けて使用する場合、Solaris_NameSpaceACL クラスを最初に使用して、名前空間内のオブジェクトへのすべてのユーザーのアクセスを制限するのは効果的な方法です。次に、Solaris_UserACL クラスを使用して、選択したユーザーに名前空間へのアクセスを許可します。

Solaris_UserAcl クラス

Solaris_UserAcl クラスは、Solaris_Acl 基底クラスを拡張したクラスです。Solaris_UserAcl クラスは、 Solaris_Acl 基底クラスから文字列プロパティ capability をデフォルト値 r (読み取り専用) で継承します。capability プロパティを次のいずれかの値に設定することで、アクセス権を指定できます。

アクセス権 

説明 

r

読み取り 

rw

読み取りおよび書き込み 

w

書き込み 

なし 

アクセス権なし 

Solaris_UserAcl クラスは、次のキープロパティを定義します。名前空間内には、名前空間とユーザー名 ACL のペアのインスタンスを 1 つだけ入れることができます。

プロパティ 

データ型 

目的 

nspace

string

ACL を適用する名前空間を示す

username

string

ACL を適用するユーザーを示す

ユーザーのアクセス制御設定
  1. Solaris_UserAcl クラスのインスタンスを作成します。次に例を示します。

    ... 
    /* root\security
    (名前空間の名前) を使用して初期化した名前空間オブジェクトを
    ローカルホスト上に作成する */
    
    CIMNameSpace cns = new CIMNameSpace("", "root\security");
    
    // root\security 名前空間にスーパーユーザーとして接続する 
    cc = new CIMClient(cns, user, user_passwd);
    
    // Solaris_UserAcl クラスを取得する
    cimclass = cc.getClass(new CIMObjectPath("Solaris_UserAcl");
    
    // Solaris_UserAcl の新しいインスタンスを作成する
    class ci = cimclass.newInstance();
    ...

  2. capability プロパティを目的のアクセス権に設定します。次に例を示します。

    ...
    /* root\molly 名前空間内のオブジェクトに対するユーザー Guest の
    アクセス権 (capability) を読み取りおよび書き込みに変更する */
    ci.setProperty("capability", new CIMValue(new String("rw")); 
    ci.setProperty("nspace", new CIMValue(new String("root\molly")); 
    ci.setProperty("username", new CIMValue(new String("guest"));
    ...

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

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

Solaris_NamespaceAcl クラス

Solaris_NamespaceAcl クラスは、 Solaris_Acl 基底クラスを拡張したクラスです。Solaris_UserAcl クラスは、 Solaris_Acl 基底クラスから文字列プロパティ capability をデフォルト値 r (すべてのユーザーに対し読み取り専用) で継承します。Solaris_NamespaceAcl クラスは、次のキープロパティを定義します。

プロパティ 

データ型 

目的 

nspace

string

アクセス制御リストを適用する名前空間を示す。名前空間内には、名前空間 ACL のインスタンスを 1 つだけ指定できる

名前空間のアクセス制御設定
  1. Solaris_namespaceAcl クラスのインスタンスを作成します。次に例を示します。

    ...
    /* root\security  (名前空間の名前) を使用して
    初期化した名前空間オブジェクトをローカルホスト上に作成する */   
    CIMNameSpace cns = new CIMNameSpace("", "root\security"); 
    
    // root\security 名前空間にスーパーユーザーとして接続する
    cc = new CIMClient(cns, user, user_passwd);
    
    // Solaris_namespaceAcl クラスを取得する
    cimclass = cc.getClass(new CIMObjectPath("Solaris_namespaceAcl");
    
    // Solaris_namespaceAcl の新しいインスタンスを作成する
    class ci = cimclass.newInstance();
    ...

  2. capability プロパティを目的のアクセス権に設定します。次に例を示します。

    ...
    /* root\molly 名前空間へのアクセス権 (capability) を
    読み取りおよび書き込みに変更する */
    ci.setProperty("capability", new CIMValue(new String("rw")); 
    ci.setProperty("nspace", new CIMValue(new String("root\molly"));
    ...

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

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

修飾子と修飾子のデータ型の処理

CIM 修飾子は、CIM クラス、インスタンス、プロパティ、メソッド、またはパラメータの特性を示す要素です。修飾子の属性は、次のとおりです。

MOF 構文では、各 CIM 修飾子は、定義された CIM 修飾子データ型を 1 つ持ちます。修飾子には、その修飾子を使用可能な CIM 要素を示すスコープ属性はありません。スコープを定義できるのは、修飾子のデータ型宣言内だけです。修飾子内でスコープを変更することはできません。

次に、CIM 修飾子のデータ型を宣言する MOF 構文を示します。この文は、ブール型 (デフォルト値は false) を使用して修飾子のデータ型 key を定義します。このデータ型が記述できるのは、プロパティと、オブジェクトに対する参照だけです。DisableOverride フレーバは、このキー修飾子がそれらの値を変更できないことを意味します。

Qualifier Key : boolean = false, Scope(property, reference), 
                    Flavor(DisableOverride);

次のコード例は、CIM 修飾子の MOF 構文を示します。このサンプル MOF ファイルでは、key と説明は、プロパティ a の修飾子です。プロパティのデータ型は、プロパティ名 a を持つ整数です。

{
[key, Description("test")]
int a;
};

CIM 修飾子の取得と設定

修飾子フレーバは、修飾子の使用を制御するフラグです。フレーバは、派生クラスとインスタンスに修飾子を継承できるかどうか、および派生クラスまたはインスタンスが修飾子の元の値をオーバーライドできるかどうかを指定する規則を記述します。


例 3-19 CIM 修飾子の設定

次のコード例は、新しいクラスの CIM 修飾子のリストをそのスーパークラス内の修飾子に設定します。

{

 try {
     cimSuperClass = cimClient.getClass(new CIMObjectPath(scName));
        Vector v = new Vector();
        for (Enumeration e = cimSuperClass.getQualifiers().elements();
                         e.hasMoreElements();) { 
CIMQualifier qual = (CIMQualifier)((CIMQualifier)e.nextElement()).clone();
        v.addElement(qual);
        }
        cimClass.setQualifiers(v); 
 } catch (CIMException exc) {
          return;
        }
    }
}
...


クライアント要求のバッチ処理

複数の CIMClient API 呼び出しを単一のリモート呼び出しとしてバッチ処理することにより、複数のリモートメッセージ交換による遅延を軽減できます。BatchCIMClient クラスのインスタンスを使用して、バッチ要求内で実行する操作のリストを作成できます。次に、CIMClient クラスの performBatchOperations メソッドを使用して、CIM Object Manager に操作のリストを送信します。


注 -

バッチ操作は、単一のトランザクションを意味するわけではありません。各操作は、バッチに含まれる他の操作とは独立しており、前に実行される操作が正常終了したかまたは失敗したかには影響されません。


BatchCIMClient クラスには、非バッチモードと同じ CIM 操作を実行できるメソッドが含まれます。これらのメソッドは、BatchCIMClient メソッドが CIMClient クラス内の等価の型と同じ型を返さないことを除き (バッチ操作の完了後に値がリストとして返されるため)、CIMClient メソッドと類似しています。このメソッドは、整数の操作 ID を返します。この ID を使用して、操作の結果をあとで取得できます。BatchCIMClient のメソッドが呼び出されると、BatchCIMClient オブジェクトは、後で実行される CIMOperation オブジェクトのリストを作成します。

クライアントが、CIMClient performBatchOperations メソッドを呼び出すことによって、バッチ操作リストを実行すると、バッチ操作の結果を含む BatchResult オブジェクトが返されます。次に、クライアントは操作 ID を BatchResult クラスの getResult に渡して、操作の結果を取得します。リスト内の操作により例外が発生すると、BatchResult オブジェクトに例外オブジェクトが埋め込まれます。失敗した操作 ID を使用する getResult メソッドを起動すると、getResult メソッドにより例外がスローされます。


例 3-20 バッチ処理の例

次の例は、バッチ処理 API を使用して、1 つのリモート呼び出し内で複数の操作を実行する方法を示します。この例では、3 つの操作 (enumerateInstanceNamesgetClass、および enumerateInstances) が単独のバッチ操作として実行されます。

import java.util.Enumeration;
import java.util.ArrayList;
import java.util.Vector;
import java.lang.String;

import javax.wbem.cim.*;
import javax.wbem.client.*;
import javax.wbem.client.UserPrincipal;
import javax.wbem.client.PasswordCredential;


public class TestBatch {
    public static void main(String args[]) throws CIMException {
	       CIMClient cc = null;
	       CIMObjectPath cop = null;
	       String protocol = CIMClient.CIM_RMI;
	       if (args.length < 4) {
	           System.out.println("Usage: TestBatch host user passwd 
                                classname " + "[rmi|http]");
	           System.exit(1);
	           }
	       try {
	           CIMNameSpace cns = new CIMNameSpace(args[0]);

	           UserPrincipal up = new UserPrincipal(args[1]);
	           PasswordCredential pc = new PasswordCredential(args[2]);
	           if (args.length == 5 && args[4].equalsIgnoreCase("http")) {
	    	           protocol = CIMClient.CIM_XML;
	           }
	           cc = new CIMClient(cns, up, pc, protocol);

	           CIMObjectPath op = new CIMObjectPath(args[3]);

	           BatchCIMClient bc = new BatchCIMClient();
	           int[] ids = new int[3];

	           ids[0] = bc.enumerateInstanceNames(op);
	           ids[1] = bc.getClass(op, false, true, true, null);
	           ids[2] = bc.enumerateInstances(op, true, false, false, 
                                           false, null);

	           BatchResult br = cc.performBatchOperations(bc);

            Enumeration instanceNames = (Enumeration)br.getResult
                                        (ids[0]);
	           CIMClass cl = (CIMClass)br.getResult(ids[1]);
	           Enumeration instances = (Enumeration)br.getResult(ids[2]);

	           while (instanceNames.hasMoreElements()) {
	               System.out.println((CIMObjectPath)instanceNames.
                                    nextElement());
	           }

	           System.out.println(cl.toMOF());

	           while (instances.hasMoreElements()) {
	               System.out.println((CIMInstance)instances.
                                    nextElement());
	           }

	       }
	       catch (Exception e) {
	           e.printStackTrace();
	           System.out.println("Exception: "+e);
	       }

	       // セッションを閉じる
	       if (cc != null) {
	           cc.close();
	       }
    }
}

CIM イベントの処理


注 -

CIM インジケーション、および CIM インジケーションを使用してイベントの発生を通知する方法については、 http://www.dmtf.org/education/whitepapers.php の CIM Schema White Papers を参照してください。


「イベント」とは、1 つの発生した事象です。「インジケーション」とは、イベントの発生通知です。CIM (Common Information Model) では、発行されるのはインジケーションであり、イベントではありません。イベントの発生時に、プロバイダはインジケーションを生成します。

インジケーションは、状態の変化を認識する 0 以上の「トリガー」を保持します。WBEM は、トリガーを表す明示的なオブジェクトを保持しません。その代わり、トリガーは以下により暗黙的に示されます。


たとえば、サービスが終了してトリガーが機能すると、このイベントによりサービスの終了を通知するインジケーションが生成されます。


Solaris WBEM サービススキーマ内の関連する CIM イベントクラスは、/usr/sadm/lib/wbem/doc/mofhtml/index.html で確認できます。クラスは、次のように構築されます。

表 3-5 CIM_Indication クラス構造

ルートクラス 

スーパークラス 

サブクラス 

CIM_Indication

CIM_ClassIndication

CIM_ClassCreationCIM_ClassDeletion CIM_ClassModification

 

CIM_InstIndication

CIM_InstCreation CIM_InstDeletionCIM_InstMethodCall CIM_InstModificationCIM_InstRead

 

CIM_ProcessIndication

CIM_AlertIndicationCIM_AlertInstIndication CIM_ThresholdIndicationCIM_SNMPTrapIndication

インジケーションについて

CIM イベントは、ライフサイクルまたはプロセスとして分類できます。「ライフサイクルイベント」は、データの変更に対応して発生する組み込みの CIM イベントであり、その内部で、クラスの作成、変更、削除、クラスインスタンスの作成、変更削除、読み取り、またはメソッド呼び出しが行われます。「プロセスイベント」は、ライフサイクルイベントに含まれないユーザー定義のイベントです。

イベントプロバイダは、CIM Object Manager により作成された要求に応答してインジケーションを生成します。CIM Object Manager は予約要求を分析し、 EventProviderCIMIndicationProvider インタフェース、あるいはその両方を使用してプロバイダと通信し、適切なインジケーションの生成を要求します。プロバイダがインジケーションを生成すると、CIM Object Manager は CIM_IndicationHandler インスタンスにより指定された宛先にインジケーションを配信します。これらのインスタンスは、予約者により作成されます。

イベントプロバイダは、インスタンスプロバイダと同じ方法で検出されます。インスタンスのライフサイクルインジケーション (CIM_InstIndication のサブクラス) に属する予約の場合、CIM Object Manager が予約の有効範囲内のクラスを判別すると、これらのクラスのインスタンスプロバイダに対し通信を行います。プロセスインジケーションの場合、CIM Object Manager は Provider 修飾子を使用して、適切なプロバイダと通信を行います。

CIM Object Manager および CIM Object Manager Repository は、次の条件下でインジケーションを処理します。

上記の場合、プロバイダはインジケーションを生成しないか、EventProvider インタフェースを実装します。また、プロバイダは、イベントの生成機能を CIM Object Manager に委託することもできます。CIM Object Manager は、プロバイダに対して enumerateInstances を呼び出して、以前の状態のスナップショットを現在の状態と比較し、インスタンスが作成、変更、または削除されたかどうかを判断します。


注 -

ポーリングを使用すると大幅なオーバーヘッドが発生するため、ほとんどの場合、プロバイダが独自のインジケーションを処理する必要があります。インジケーションを生成する場合、プロバイダ自体がポーリングを行う必要があります。このとき、プロバイダはタスクを CIM Object Manager に委託できます。


プロバイダが EventProvider インタフェースを実装する場合、CIM Object Manager はインタフェース内のメソッドを呼び出し、その応答に応じて操作を実行します。特定のプロバイダが予約要求に参加する必要があると CIM Object Manager が判断すると、次の順序でメソッドが呼び出されます。

  1. mustPoll - CIM_InstCreationCIM_InstDeletion、および CIM_InstModification に対応して CIM Object Manager により呼び出され、CIM Object Manager によるポーリングをプロバイダが望んでいるかどうかを判断します。プロバイダが EventProvider インタフェースを実装していない場合、CIM Object Manager はデフォルトでポーリングを実行するとみなします。

  2. authorizeFilter - プロバイダが Authorizable インタフェースを実装する場合、CIM Object Manager によりこのメソッドが呼び出され、予約が承認されるかどうかを判断します。プロバイダは、インジケーションハンドラの所有者のユーザー ID (インジケーションを受信するユーザー)、または予約を作成したユーザーに基づいて、決定を行います。

    プロバイダが Authorizable インタフェースを実装しない場合、CIM Object Manager は、名前空間に対してデフォルトの読み取り承認検査を実行します。

    プロバイダが EventProvider インタフェースを実装せず、CIM Object Manager がポーリングを試みる場合、プロバイダに対する enumerateInstances が正常終了すると、承認が正しく行われます。

  3. activateFilter - 承認が正しく行われ、プロバイダがポーリングを要求しない場合に、CIM Object Manager により呼び出されます。

  4. deActivateFilter - 予約が予約者または CIM Object Manager により削除される場合 (宛先ハンドラが正常に機能しない場合など) に呼び出されます 。

予約について

クライアントアプリケーションでは、CIM イベントが通知されるように予約することができます。「予約」は、1 つまたは複数の一連のインジケーションを宣言することによって行います。現在は、プロバイダがイベントインジケーションを予約することはできません。

CIM イベントのインジケーションを予約するアプリケーションには、 次の指定を行います。

イベントの発生は、CIM_Indication クラスのいずれかのサブクラスのインスタンスとして表されます。インジケーションは、そのイベントがクライアントによって予約されているときだけ生成されます。

予約の作成

アプリケーションは、1 つまたは複数のイベントフィルタと 1 つまたは複数のイベントハンドラを作成できます。イベントインジケーションは、アプリケーションがイベントの予約を作成するまで送信されません。

  1. CIM_Listener のインスタンスを作成します。詳細は、「CIM リスナーの追加」を参照してください。

  2. CIM_IndicationFilter のインスタンスを作成します。詳細は、「イベントフィルタの作成」を参照してください。

  3. CIM_IndicationHandler のインスタンスを作成します。詳細は、「イベントハンドラの作成」を参照してください。

  4. CIM_IndicationFilter CIM_IndicationHandler にバインドします。詳細は、「イベントフィルタとイベントハンドラのバインド」を参照してください。

CIM リスナーの追加

CIM イベントのインジケーションを受信するには、最初に CIMClient に対して addCIMListener メソッドを呼び出して、CIMListener のインスタンスを CIMClient に追加します。


注 -

CIMListener インタフェースは、indicationOccured メソッドを実装する必要があります。このメソッドは、引数として CIMEvent を取ります。インジケーションが送信可能な場合、このメソッドが呼び出されます。



例 3-21 CIM リスナーの追加

// CIM Object Manager に接続する
cc = new CIMClient();

// CIM リスナーを登録する
cc.addCIMListener(
new CIMListener() {
    public void indicationOccured(CIMEvent e) {
    }
});


イベントフィルタの作成

イベントフィルタでは、送信するイベントの種類と、どのような条件下で送信するかを指定します。CIM_IndicationFilter クラスのインスタンスを作成し、そのプロパティの値を定義することによって、イベントフィルタを作成します。各イベントフィルタは、そのフィルタが属する名前空間に属するイベントに対してのみ有効です。

CIM_IndicationFilter クラスは、一意のフィルタ識別、照会文字列の指定、照会文字列を構文解析する照会言語の指定が可能な文字列プロパティを保持します。現在は、WQL (WBEM Query Language) だけがサポートされます。

表 3-6 CIM_IndicationFilter プロパティ

プロパティ 

説明 

必須/任意 

SystemCreationClassName

このフィルタを作成するクラスがあるシステム名、またはこのクラスが適用されるシステム名 

任意。値は、CIM Object Manager により決定される 

SystemName

このフィルタがあるシステム名、またはこのフィルタが適用されるシステム名 

任意。このキープロパティのデフォルトは、CIM Object Manager が動作しているシステム名 

CreationClassName

このフィルタの作成に使用するクラス名またはサブクラス名 

任意。CIM Object Manager は、このキープロパティのデフォルトとして CIM_IndicationFilter を割り当てる

Name

フィルタの固有名 

任意。CIM Object Manager は一意の名前を割り当てる 

SourceNamespace

CIM インジケーション生成元であるローカル名前空間へのパス 

任意。デフォルトは null 

Query

インジケーションをどのような条件のときに生成するかを定義する照会式。現在は、Level 1 の WQL 式だけがサポートされる。WQL 照会式の詳細は、第 5 章「WBEM 照会の作成」を参照

必須 

QueryLanguage

照会を表現する言語 

必須。デフォルトは WQL  

イベントフィルタの作成
  1. CIM_IndicationFilter クラスのインスタンスを作成します。

    CIMClass cimfilter = cc.getClass
            (new CIMObjectPath(“CIM_IndicationFilter”),
             true, true, true, null);
    CIMInstance ci = cimfilter.newInstance();

  2. イベントフィルタ名を指定します。

    Name = “filter_all_new_solarisdiskdrives”

  3. WQL 文字列を作成し、返されるイベントインジケーションを指定します。

    String filterString = “SELECT * 
            FROM CIM_InstCreation WHERE sourceInstance 
            ISA Solaris_DiskDrive”;

  4. cimfilter インスタンスの各プロパティ値に、フィルタ名、CIM イベントを選択するフィルタ文字列、照会文字列を解析する照会言語 (WQL) を設定します。

    ci.setProperty(“Name”, new 
            CIMValue("filter_all_new_solarisdiskdrives”));
    ci.setProperty("Query", new CIMValue(filterString));
    ci.setProperty("QueryLanguage", new CIMValue("WQL");)

  5. cimfilter インスタンスを filter という名前で作成し、CIM Object Manager Repository 内に格納します。

    CIMObjectPath filter = cc.createInstance(new
                                                   CIMObjectPath(), ci);


例 3-22 イベントフィルタの作成

CIMClass cimfilter = cc.getClass(new CIMObjectPath
                                (“CIM_IndicationFilter”), true);
CIMInstance ci = cimfilter.newInstance();
// test_a クラスが名前空間内に存在するものとする
String filterString = "select * from CIM_InstCreation where sourceInstance 
                       isa test_a"

ci.setProperty("query", new CIMValue(filterString));
CIMObjectPath filter = cc.createInstance(newCIMObjectPath(), ci);


イベントハンドラの作成

イベントハンドラは、CIM_IndicationHandler クラスのインスタンスです。 CIM_IndicationHandler クラスのインスタンス内でプロパティを設定して、ハンドラに一意の名前を付け、その所有者の UID を示します。CIM イベント MOF には、HTTP プロトコルを使ってクライアントアプリケーションに送信されるインジケーションの宛先を指定する CIM_IndicationHandlerCIMXML クラスが定義されています。Solaris イベント MOF は、Solaris_JAVAXRMIDelivery クラスを作成して CIM_IndicationHandler クラスを拡張し、RMI プロトコルを使用して CIM イベントインジケーションをクライアントアプリケーションへ送信します。RMI クライアントは、Solaris_JAVAXRMIDelivery クラスのインスタンスを作成して、RMI 送信の場所を設定する必要があります。

表 3-7 CIM_IndicationHandler プロパティ

プロパティ 

説明 

必須/任意 

SystemCreationClassName

このハンドラを作成するクラスがあるシステム名、またはこのクラスが適用されるシステム名 

 任意。CIM Object Manager により指定される

SystemName

このハンドラがあるシステム名、またはこのハンドラが適用されるシステム名。 

任意。このキープロパティのデフォルト値は、CIM Object Manager が動作しているシステム名。 

CreationClassName

このハンドラの作成に使用するクラスまたはサブクラス 

任意。CIM Object Manager は、適切なクラス名をこのキープロパティのデフォルトとして割り当てる 

Name

このハンドラの固有名 

任意。クライアントアプリケーションは固有名を指定する必要がある 

Owner

このハンドラを作成した、または保持するエンティティ名。プロバイダは、この値を検査して、インジケーションの受信をハンドラに承認するかどうかを判断できる 

任意。デフォルトは、このインスタンスを作成するユーザーの Solaris ユーザー名 


例 3-23 イベントハンドラの作成

// Solaris_JAVAXRMIDelivery クラスのインスタンスを作成するか、
// ハンドラの適切なインスタンスを取得する
CIMInstance ci = cc.getIndicationHandler(null);

// 新しいインスタンス (delivery) を
// rmidelivery インスタンスから作成する
CIMObjectPath delivery = cc.createInstance(new CIMObjectPath(), ci);


イベントフィルタとイベントハンドラのバインド

CIM_IndicationSubscription クラスのインスタンスを作成することにより、イベントフィルタとイベントハンドラをバインドします。このクラスのインジケーションを作成すると、イベントフィルタにより指定されたイベントのインジケーションが送信されます。

次の例では、予約 (filterdelivery) を作成し、“イベントフィルタの作成”で作成した filter オブジェクトパスに filter プロパティを定義します。また、例 3–23 で作成した delivery オブジェクトパスに handler プロパティを定義します。


例 3-24 イベントフィルタとイベントハンドラのバインド

CIMClass filterdelivery = cc.getClass(new 
        CIMObjectPath(“CIM_IndicationSubscription”), 
        true, true, true, null);
ci = filterdelivery.newInstance():

// フィルタインスタンスを参照する filter という名のプロパティを作成する
ci.setProperty("filter", new CIMValue(filter));

// 送信インスタンスを参照する handler という名のプロパティを作成する
ci.setProperty("handler", new CIMValue(delivery));

CIMObjectPath indsub = cc.createInstance(new CIMObjectPath(), ci);


ログメッセージの読み取りと書き込み

Solaris MOF には、ログクラスが含まれます。クライアントは、これらのクラスを使用してエラー、警告、および情報メッセージをログに記録し、読み取ることができます。たとえば、ログメッセージから、システムがシリアルポートにアクセスできなくなった日時、システムがファイルシステムを正常にマウントした日時、またシステムで稼働するプロセス数が許可された数を超えた日時などを知ることができます。

ログクラスの基盤となるプロバイダは、ログ要求を syslog デーモン (Solaris オペレーティング環境のデフォルトログシステム) に転送できます。詳細は、syslogd(1M) のマニュアルページを参照してください。

ログファイルについて

WBEM ログメッセージは、/var/sadm/wbem/log ディレクトリ内の個々のログファイルに格納されます。ログファイル名、ログファイルの格納ディレクトリ、ログファイルのサイズ制限、格納するログファイルの数、メッセージを syslogd(1M) に転送するかどうかは、Solaris_LogServiceProperties クラスの singleton インスタンスを使用して指定するプロパティです。

各ログエントリの形式は、CIM_LogRecord のサブクラスである Solaris_LogEntry クラスによって定義されます。Solaris_LogEntrySolaris_Device1.0.mof 内に、CIM_LogRecordCIM_Device26.mof 内に存在します。

ログメッセージには、次の要素が含まれます。

表 3-8 ログメッセージの要素

要素 

説明 

Category

メッセージの種類 – アプリケーション、システム、またはセキュリティ 

Severity

状況の重大性 – 警告またはエラー 

Application

ログメッセージを書き込んだアプリケーション (またはプロバイダ) の名前 

User

ログメッセージの生成時にアプリケーションを使用していたユーザー名 

Client Machine

ログメッセージの生成時にユーザーが使用していたシステム名および IP アドレス 

Server Machine

ログメッセージの原因となったイベントが発生したシステム名 

Summary Message

イベントの概要説明 

Detailed Message

イベントの詳細説明 

Data

イベントをより把握するための状況説明 

SyslogFlag

メッセージを syslogd(1M) に送信するかどうかを指定するブール値のフラグ


例 3-25 Solaris_LogEntry のインスタンス作成

このプログラム例では、Solaris_LogEntry のインスタンスを作成し、そのインスタンスを設定します。

public class CreateLog {
    public static void main(String args[]) throws CIMException {

        // 渡されたコマンド行引数が不足している場合は、
        // 使用法を表示する
        if (args.length < 3) {
            System.out.println("Usage: CreateLog host username password 
                               " + "[rmi|http]"); 
            System.exit(1);
        }

        String protocol = CIMClient.CIM_RMI;
        CIMClient cc = null;
        CIMObjectPath cop = null;
        BufferedReader d = new BufferedReader(new InputStreamReader
                                             (System.in));

        String input_line = "";

        // 作成するレコード数をユーザーに問い合わせる
        System.out.print("How many log records do you want to write? ");
        int num_recs = 0;

        try {
                num_recs = Integer.parseInt(d.readLine());
        } catch (Exception ex) {
                ex.printStackTrace();
                System.exit(1);
        }

        // try-catch ブロックのオーバーアーチ
        try {
            CIMNameSpace cns = new CIMNameSpace(args[0]);
            UserPrincipal up = new UserPrincipal(args[1]);
            PasswordCredential pc = new PasswordCredential(args[2]);

            // トランスポートプロトコルをデフォルトの RMI に設定する 
            if (args.length == 4 && args[3].equalsIgnoreCase("http")) {
                protocol = CIMClient.CIM_XML;
            }

            cc = new CIMClient(cns, up, pc, protocol);

                Vector keys = new Vector();
                CIMProperty logsvcKey = null;


                // ログ記録の作成に必要な関連情報の
                // 入力をユーザーに求める

                System.out.println("Please enter the record Category: ");
                System.out.println("\t(0)application, (1)security, 
                                                      (2)system");
                logsvcKey = new CIMProperty("category");
                input_line = d.readLine();
                logsvcKey.setValue(new CIMValue(Integer.valueOf
                                               (input_line)));
                keys.addElement(logsvcKey);
                System.out.println("Please enter the record Severity:");
                System.out.println("\t(0)Informational, (1)Warning, 
                                                        (2)Error");
                logsvcKey = new CIMProperty("severity");
                input_line = d.readLine();
                logsvcKey.setValue(new CIMValue(Integer.valueOf
                                  (input_line)));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("Source");
                System.out.println("Please enter Application Name:");
                logsvcKey.setValue(new CIMValue(d.readLine()));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("SummaryMessage");
                System.out.println("Please enter a summary message:");
                logsvcKey.setValue(new CIMValue(d.readLine()));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("DetailedMessage");
                System.out.println("Please enter a detailed message:");
                logsvcKey.setValue(new CIMValue(d.readLine()));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("RecordData");
                logsvcKey.setValue(
                        new CIMValue("0xfe 0x45 0xae 0xda random data"));
                keys.addElement(logsvcKey);
                logsvcKey = new CIMProperty("SyslogFlag");
                logsvcKey.setValue(new CIMValue(new Boolean(true)));
                keys.addElement(logsvcKey);
                CIMObjectPath logreccop = 
                        new CIMObjectPath("Solaris_LogEntry", keys);
                CIMClass logClass = cc.getClass(logreccop);
                CIMInstance ci = logClass.newInstance();
                ci.setClassName("Solaris_LogEntry");
                ci.setProperties(keys);
                // System.out.println(ci.toString());

                // 要求された数のレコードインスタンスを作成する
                for (int i = 0; i < num_recs; i++) {
                        cc.createInstance(logreccop, ci);
                }
        } catch (Exception e) {
            System.out.println("Exception: "+e);
                e.printStackTrace();
        }

        // セッションを閉じる
        if (cc != null) {
            cc.close();
        }
    }
}


例 3-26 ログ記録リストの表示

このプログラム例では、ログ記録のリストを表示します。

 public class ReadLog {
    public static void main(String args[]) throws CIMException {

        String protocol = CIMClient.CIM_RMI;

        // 渡されたコマンド行引数が不足している場合、
        // 使用法を表示する
        if (args.length < 3) {
            System.out.println("Usage: ReadLog host username password " +
                               "[rmi|http]"); 
            System.exit(1);
        }

        CIMClient cc = null;
        CIMObjectPath cop = null;
        CIMObjectPath serviceObjPath = null;
        Vector inVec = new Vector();
        Vector outVec = new Vector();

        // try-catch ブロックのオーバーアーチ
        try {
            CIMNameSpace cns = new CIMNameSpace(args[0]);
            UserPrincipal up = new UserPrincipal(args[1]);
            PasswordCredential pc = new PasswordCredential(args[2]);

            // トランスポートプロトコルをデフォルトの RMI に設定する
            if (args.length == 4 && args[3].equalsIgnoreCase("http")) {
                protocol = CIMClient.CIM_XML;
            }

            cc = new CIMClient(cns, up, pc, protocol);

            cop = new CIMObjectPath("Solaris_LogEntry");

            //  Solaris_LogEntry クラスのインスタンスリストを列挙する
            Enumeration e = cc.enumerateInstances(cop, true, false,
                                                false, false, null);

            // リストを繰り返し処理して、各プロパティを出力する
            for (; e.hasMoreElements(); ) {
                System.out.println("---------------------------------");
                CIMInstance ci = (CIMInstance)e.nextElement();
                System.out.println("Log filename : " + 
                    ((String)ci.getProperty("LogName").getValue().
                                                       getValue()));
                int categ = 
    (((Integer)ci.getProperty("Category").getValue().getValue()).
       intValue());
                if (categ == 0)
                    System.out.println("Category : Application Log");
                else if (categ == 1)
                    System.out.println("Category : Security Log");
                else if (categ == 2)
                    System.out.println("Category : System Log");
                int severity = 
    (((Integer)ci.getProperty("Severity").getValue().getValue()).
       intValue());
                if (severity == 0)
                    System.out.println("Severity : Informational");
                else if (severity == 1)
                    System.out.println("Severity : Warning Log!");
                else if (severity == 2)
                    System.out.println("Severity : Error!!");
                System.out.println("Log Record written by :" + 
    ((String)ci.getProperty("Source").getValue().getValue()));
                System.out.println("User : " + 
    ((String)ci.getProperty("UserName").getValue().getValue()));
                System.out.println("Client Machine : " + 
    ((String)ci.getProperty("ClientMachineName").getValue().getValue()));
                System.out.println("Server Machine : " + 
    ((String)ci.getProperty("ServerMachineName").getValue().getValue()));
                System.out.println("Summary Message : " + 
    ((String)ci.getProperty("SummaryMessage").getValue().getValue()));
                System.out.println("Detailed Message : " + 
    ((String)ci.getProperty("DetailedMessage").getValue().getValue()));
                System.out.println("Additional data : " + 
    ((String)ci.getProperty("RecordData").getValue().getValue()));
                boolean syslogflag =
((Boolean)ci.getProperty("SyslogFlag").getValue().getValue()).
  booleanValue();
                if (syslogflag == true) {
                    System.out.println("Record was written to syslog");
                } else {
                    System.out.println("Record was not written to syslog");
                }
                System.out.println("---------------------------------");
            }
        } catch (Exception e) {
            System.out.println("Exception: "+e);
            e.printStackTrace();
        }

        // セッションを閉じる
        if (cc != null) {
            cc.close();
        }
    }
}