Solaris WBEM 開発ガイド

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

この章では、Solaris WBEM SDK とクライアント API (javax.wbem.client) を使ってクライアントプログラムを作成する方法について説明します。この章の内容は、次のとおりです。


注 –

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


クライアント API の概要

WBEM クライアントアプリケーションは、javax.wbem.client API を使用して CIM オブジェクトを操作します。クライアントアプリケーションは、CIM API を使ってオブジェクトを構築したあと、そのオブジェクトのインスタンスを作成します。こうしたオブジェクトには、クラス、インスタンス、名前空間などがあります。アプリケーションは、クライアント API を使ってオブジェクトを CIM オブジェクトマネージャ に渡し、WBEM 操作を要求します。たとえば、CIM クラスの作成、インスタンスの作成、名前空間の作成といった操作があります。

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

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

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

  2. クライアント API を使用して、操作の要求およびプログラミング作業を実行します。アプリケーションの機能セットは、どの処理を要求すべきかを決定します。次に、ほとんどのプログラムが実行する一般的な処理を示します。

    • インスタンスの作成、削除、更新

    • オブジェクトの列挙

    • メソッドの呼び出し

    • クラス定義の取得

    • エラー処理

    クラスの作成と削除、名前空間の作成と削除、および修飾子の使用は、クライアントプログラムからも実行できます。詳細は、「基本的なクライアント操作の実行」を参照してください。

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

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

クライアントが WBEM 操作を実行するためには、まずアプリケーションから CIMOM への接続を確立する必要があります。たとえば、CIM クラス、CIM インスタンス、CIM 修飾子型などを追加、変更、または削除する WBEM 作業があります。クライアントアプリケーションと CIM オブジェクトマネージャは、同一のホスト上でも、別のホスト上でも実行可能です。また、複数のクライアントが 1 つの CIM オブジェクトマネージャに接続を確立することもできます。

名前空間について

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

クライアント接続の開始

クライアント接続を開始する場合、CIMClient クラスを使用して CIM オブジェクトマネージャに接続します。CIMClient クラスは、次の 4 つの引数を取ります。


例 4–1 ルートアカウントへの接続

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

{
   ...

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

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


例 4–2 ユーザーアカウントへの接続

次の例では、アプリケーションは、最初に CIMNameSpaceUserPrincipal、および PasswordCredential オブジェクトのインスタンスを作成します。次に、CIMOM への接続を確立するため、CIMClient クラスを使って、資格情報 (ホスト名、名前空間、ユーザー名、およびパスワード) を渡します。

{
    ...
    /* ホスト 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);
    ...
} 


例 4–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 メソッドを使用して、クライアント接続を閉じ、セッションが使用したサーバーリソースを解放します。


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

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

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

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

この節では、javax.wbem.client API を使った操作の要求方法と、一般的なプログラミング作業の実行方法について説明します。

インスタンスの作成

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

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


例 4–5 インスタンスの作成

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

...
{ 
/* ローカルホスト上の名前空間 root\cimv2 
で CIM オブジェクトマネージャに接続する
root\cimv2 にオブジェクトへの書き込み権を
持つアカウントのユーザー名とパスワードを指定する */
 
 UserPrincipal up = new UserPrincipal("root");
 PasswordCredential pc = new PasswordCredential("root-password"); 
 /* root ユーザーとして 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 メソッドを使用します。


例 4–6 インスタンスの削除

この例は、次のことを実行します。

 
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;

/** 
 * 指定のクラスのインスタンスをすべて返す。
 * この例は、ホスト名 (args[0])、ユーザー名 (args[1])、
 * パスワード (args[2])、名前空間 (args[3])、およびクラス名 (args[4]) という
 * 5 つの引数を取る。指定のクラス名のインスタンスをすべて削除する。
 * 指定のユーザー名は、指定の名前空間に対する書き込み権を持つ必要
 * がある
 */
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 オブジェクトマネージャに接続し、
            // 作成した CIMNameSpace、UserPrincipal、および
            // PasswordCredential のオブジェクトを渡す
            cc = new CIMClient(cns, up, pc);

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

            // クラスとその全サブクラスのインスタンスオブジェクトパスの
            // 列挙を取得する。インスタンスオブジェクトパスは、
            // CIM オブジェクトマネージャがインスタンスを検索する
            // ときに使用する参照
            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();
        }
    }
}

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

クライアントアプリケーションは、一般に getInstance メソッドを使って CIMOM から CIM インスタンスを取得します。クラスのインスタンスが作成されると、クラスはクラス階層内のすべての親クラスのプロパティを継承します。getInstance メソッドは、ブール値引数 localOnly を受け取ります。

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


例 4–7 インスタンスの取得と設定

この例は次のことを行います。

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

    /* 列挙内の各インスタンスオブジェクトパスに対するインスタンスを
    取得し、各インスタンスの b のプロパティ値を 10 に更新し、更新した
    インスタンスを CIM オブジェクトマネージャに渡す */
    
    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 クラスの特性を記述する値です。プロパティは、1 組の関数と見なすことができます。一方の関数はプロパティ値を「取得」し、もう一方の関数はプロパティ値を「設定」します。


例 4–8 プロパティの取得

次の例は、enumerateInstanceNames を使って Solaris プラットフォームプロセッサのすべてのインスタンスの名前を返します。この例は、getProperty を使って各インスタンスの現在のクロック速度の値を取得し、println を使ってこの値を出力します。

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


例 4–9 プロパティの設定

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

...
{
    /* オブジェクト (CIMObjectPath) を作成して 
    Solaris_Processor クラスの名前を格納する */ 
 
    CIMObjectPath cop = new CIMObjectPath("Solaris_UserTemplate"); 
 
    /* CIM オブジェクトマネージャは、 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 つずつ取り出すことができるオブジェクトの集合です。クラス、クラス名、インスタンス、インスタンス名、および名前空間を列挙できます。次の表に示すように、列挙の結果は使用するメソッドや引数によって異なります。

オブジェクトの列挙

表 4–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 レベルの子のみを返す

なし 


例 4–10 クラスの列挙

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

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


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


例 4–12 クラス名の列挙

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

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


例 4–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 オブジェクトマネージャに接続して、作成した 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();
        }
    }
}

関連の作成

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

図 4–1 TeacherStudent 関連 1

TeacherStudent 関連 1 は、Teacher が Student に教え (Teaches)、Student が Teacher から教えられる (Taught By) 関係を表します。

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

関連メソッド

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

表 4–2 関連メソッド

ソート方法 

説明 

associators

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

associatorNames

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

references

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

referenceNames

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

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

図 4–2 TeacherStudent 関連 2

Math Teacher と Art Teacher は Teacher のサブクラス、Teacher 1、Teacher 2、および Student 1 はクラスインスタンスです。

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

表 4–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 とリンクされている。MathTeacherArtTeacher は、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 メソッドを使用して、所定のクラスのすべてのインスタンスを返し、ループ構造を使用して各インスタンスを処理します。ループでは、各インスタンスを関連メソッドに渡すことができます。


例 4–14 インスタンスの引き渡し

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

 {
    ...
    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 を指定する必要があります。最初の 4 つのパラメータは、返されるクラスおよびインスタンスをフィルタします。

これらの引数を使用すると、これらのパラメータに指定された値と一致するクラスやインスタンスだけが返されます。返されるクラスやインスタンスに含まれている情報をフィルタ処理するパラメータには、includeQualifiersincludeClassOriginpropertyList があります。

メソッドの呼び出し

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

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

表 4–4 invokeMethod パラメータ

パラメータ 

データ型 

説明 

name

CIMObjectPath

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

methodName

String

呼び出すメソッド名 

inParams

Vector

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

outParams

Vector

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


例 4–15 メソッドの呼び出し

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

{
    ...
    /* CIM_Service クラスの CIM オブジェクトパスを  
    CIM オブジェクトマネージャに渡す。このクラスで定義されたメソッドを
    呼び出す */ 
     
    CIMObjectPath op = new CIMObjectPath("CIM_Service"); 
     
    /* CIM オブジェクトマネージャは、インスタンスオブジェクトパスの
   列挙、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 を受け取ります。


例 4–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、つまりエラー状態をスローします。CIMOM は、Java の例外処理により、WBEM 固有の例外の階層を作成します。CIMException クラスは、CIM 例外の基底クラスです。CIMException 以外の CIM 例外クラスは、CIMException クラスのサブクラスです。

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

名前空間の作成

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


例 4–17 名前空間の作成

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

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

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

{
    ...
    /* クライアント上で名前空間オブジェクトを作成し、
    コマンド行から渡されるパラメータを格納する。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 オブジェクトマネージャに接続し、3 つのパラメータを渡す。
    3 つのパラメータとは、ホスト名 (args[0]) および親の名前空間名 
   (args[1]) を含む名前空間オブジェクト (cns)、ユーザー名文字列 
   (args[3])、およびパスワード文字列 (args[4]) を指す */
     
    CIMClient cc = new CIMClient (cns, up, pc);
     
    /*  CIM オブジェクトマネージャに、NULL 文字列 (ホスト名) と
    args[2] の子名前空間の名前 (たとえば secondlevel) を含む別の
    名前空間オブジェクトを渡す */
     
    CIMNameSpace cop = new CIMNameSpace("", args[2]);
    
    /* myhost の最上位の名前空間に、args[2] を介して渡された名前で、
    新しい名前空間を作成する./*
     
    cc.createNameSpace(cop);
    ...
} 

名前空間の削除

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

基底クラスの作成


注 –

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


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

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

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

クラスの削除

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


注 –

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



例 4–18 クラスの削除

このプログラム例は、deleteClass メソッドを使用して、デフォルトの名前空間 root\cimv2 にあるクラスを削除します。このプログラムは、次の 4 つの必須文字列引数を取ります。

このプログラムを実行するユーザーは、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 を作成する
            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 名前空間に格納されます。

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

Solaris_NameSpaceACL クラスを使ってこの 2 つのクラスの使用方法を組み合わせ、まず、名前空間内のオブジェクトに対するすべてのユーザーのアクセスを制限します。次に、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 を適用するユーザーを示す

Procedureユーザーのアクセス制御設定

手順
  1. Solaris_UserAcl クラスのインスタンスを作成します。

    ...
    /* ローカルホスト上に root\security (名前空間の名前)
    で初期化した名前空間オブジェクトを作成する */
    
    CIMNameSpace cns = new CIMNameSpace("", "root\security");
    
    // root ユーザーとして 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 オブジェクトマネージャに渡す 
    cc.createInstance(new CIMObjectPath(), ci); 
    ... 

Solaris_NamespaceAcl クラス

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

プロパティ 

データ型 

目的 

nspace

string

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

Procedure名前空間のアクセス制御設定

手順
  1. Solaris_namespaceAcl クラスのインスタンスを作成します。

    ...
    /* ローカルホスト上に root\security (名前空間の名前)
    で初期化した名前空間オブジェクトを作成する */   
    CIMNameSpace cns = new CIMNameSpace("", "root\security"); 
    
    // root ユーザーとして 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 オブジェクトマネージャに渡す 
    cc.createInstance(new CIMObjectPath(), ci); 

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

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

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

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

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

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

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

CIM 修飾子の取得と設定

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


例 4–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 オブジェクトマネージャに操作のリストを送信します。


注 –

バッチ操作は、単一のトランザクションを意味するわけではありません。バッチ内の個々の操作間に依存関係はありません。前の操作の成功または失敗が、後続の操作に影響を及ぼすことはありません。


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

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


例 4–20 バッチ処理の例

次の例は、バッチ処理 API を使用して、1 つのリモート呼び出し内で複数の操作を実行する方法を示します。3 つの操作を単一のバッチ操作として実行します。3 つの操作の内容は、enumerateInstanceNamesgetClassenumerateInstances です。

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 では、発行されるのはインジケーションであり、イベントではありません。イベントの発生時に、プロバイダはインジケーションを生成します。

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

たとえば、サービスの終了によってトリガーが作動したとき、このイベントは、サービスが終了したことを通知するインジケーションになります。

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

表 4–5 CIM_Indication クラス構造

ルートクラス 

スーパークラス 

サブクラス 

CIM_Indication

CIM_ClassIndication

CIM_ClassCreation, CIM_ClassDeletion, CIM_ClassModification

 

CIM_InstIndication

CIM_InstCreationCIM_InstDeletionCIM_InstMethodCallCIM_InstModificationCIM_InstRead

 

CIM_ProcessIndication

CIM_AlertIndication, CIM_AlertInstIndication, CIM_ThresholdIndication, CIM_SNMPTrapIndication

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

CIM イベントは、ライフサイクルまたはプロセスとして分類できます。「ライフサイクルイベント」は、データ内の特定の変更によって発生する組み込み型の CIM イベントです。ライフサイクルイベントをトリガーする変更には、次のものがあります。

「プロセスイベント」は、ライフサイクルイベントに含まれないユーザー定義のイベントです。

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

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

CIM オブジェクトマネージャおよび CIM オブジェクトマネージャリポジトリは、次の条件下でインジケーションを処理します。

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


注 –

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


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

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

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

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

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

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

  4. deActivateFilter– 予約者または CIMOM によって予約が削除された場合に呼び出されます。たとえば、宛先ハンドラが正しく機能しない場合などです。

予約について

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

CIM イベントのインジケーションを予約するアプリケーションは、次の情報を提供します。

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

Procedure予約の作成

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

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

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

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

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

CIM リスナーの追加

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


注 –

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



例 4–21 CIM リスナーの追加

// CIM オブジェクトマネージャに接続する
cc = new CIMClient();

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

イベントフィルタの作成

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

CIM_IndicationFilter クラスは文字列型のプロパティを持ちます。これらのプロパティの設定により、フィルタを一意に識別したり、照会文字列を指定したり、照会文字列の構文解析を行う照会言語を指定したりできます。現在は、WQL (WBEM Query Language) だけがサポートされます。

表 4–6 CIM_IndicationFilter プロパティ

プロパティ 

説明 

必須/任意 

SystemCreationClassName

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

任意。値は、CIM オブジェクトマネージャにより決定される 

SystemName

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

任意。このキープロパティのデフォルトは、CIM オブジェクトマネージャが動作しているシステム名 

CreationClassName

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

任意。CIM オブジェクトマネージャは、このキープロパティのデフォルトとして CIM_IndicationFilter を割り当てる

Name

フィルタの固有名 

任意。CIM オブジェクトマネージャは一意の名前を割り当てる 

SourceNamespace

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

任意。デフォルトは null 

Query

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

必須。 

QueryLanguage

照会を表現する言語 

必須。デフォルトは WQL 

Procedureイベントフィルタの作成

手順
  1. CIM_IndicationFilter クラスのインスタンスを作成します。

    CIMClass cimfilter = cc.getClass
            (new CIMObjectPath "CIM_IndicationFilter"),
             true, true, true, null);
    CIMInstance ci = cimfilter.newInstance();
  2. イベントフィルタ名を指定します。

    Name = "filter_all_new_solarisdiskdrive"
  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 オブジェクトマネージャリポジトリに格納します。

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

例 4–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_Event.mof は、Solaris_JAVAXRMIDelivery クラスを作成することにより、CIM_IndicationHandler クラスを拡張します。 このサブクラスは、RMI プロトコルを使用するクライアントアプリケーションに、CIM イベントのインジケーションを送信します。RMI クライアントは、RMI 送信の場所を設定するために Solaris_JAVAXRMIDelivery クラスのインスタンスを作成する必要があります。

表 4–7 CIM_IndicationHandler プロパティ

プロパティ 

説明 

必須/任意 

SystemCreationClassName

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

任意。CIM オブジェクトマネージャにより指定される 

SystemName

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

任意。このキープロパティのデフォルト値は、CIM オブジェクトマネージャが動作しているシステム名 

CreationClassName

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

任意。CIM オブジェクトマネージャは、適切なクラス名をこのキープロパティのデフォルトとして割り当てる 

Name

このハンドラの固有名 

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

Owner

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

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


例 4–23 イベントハンドラの作成

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

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

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

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

次の例では、予約 (filterdelivery) を作成し、 filter プロパティの値として 「イベントフィルタの作成」で作成した filter オブジェクトパスを指定します。また、handler プロパティの値として、例 4–23 で作成した delivery オブジェクトパスを指定します。


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

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

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

// delivery インスタンスを参照する 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 ディレクトリ内の個々のログファイルに格納されます。Solaris_LogServiceProperties クラスの singleton インスタンスでは、次のプロパティを操作できます。

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

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

表 4–8 ログメッセージの要素

要素 

説明 

Category

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

Severity

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

Application

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

User

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

Client Machine

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

Server Machine

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

Summary Message

イベントの概要説明 

Detailed Message

イベントの詳細説明 

Data

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

SyslogFlag

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

次の例では、ログを作成し、その内容を表示します。


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


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