管理クライアント・プログラムの開発

WebSphere® Application Server 管理アプリケーション・プログラミング・インターフェース (API) および Java™ Management Extensions (JMX) を使用する管理クライアント・プログラムを開発できます。

このタスクの概要

製品管理 API は、分散システムの操作面の制御、および構成の更新機能を提供します。 AdminClient インターフェースについては、アプリケーション・プログラミング・インターフェースの資料を参照してください。

MBean オペレーションの例を参照してください。 MBean プログラミングについては、MBean Java API の資料を参照してください。 この資料で、「 参照 > プログラミング・インターフェース > Mbean インターフェース」をクリックします。

この例は NodeAgent MBean の入手方法と使用方法を示していますが、これはご使用の製品には使用不可です。 ただし、NodeAgent MBean を入手し、使用する方法の説明は、ご使用の製品に使用可能なその他の MBeans に対して行うものと類似しています。

手順

  1. AdminClient インスタンスを作成します。

    管理クライアント・プログラムは、基本インストール内のアプリケーション・サーバーで稼働している AdminService オブジェクトでメソッドを呼び出す必要があります。

    AdminClient クラスは、サポートされている Java Management Extensions (JMX) コネクターのいずれかを介して、リモート AdminService オブジェクトにプロキシーを提供します。
    • 以下の例は、Simple Object Access Protocol (SOAP) コネクターの AdminClient インスタンスの作成方法を示しています。
      Properties connectProps = new Properties();
      connectProps.setProperty(
      AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);
      
      connectProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
      connectProps.setProperty(AdminClient.CONNECTOR_PORT, "8879");
      connectProps.setProperty(AdminClient.USERNAME, "test2");
      connectProps.setProperty(AdminClient.PASSWORD, "user24test");
      AdminClient adminClient = null;
      try
      {
             adminClient = AdminClientFactory.createAdminClient(connectProps);
      }
      catch (ConnectorException e)
      {
             System.out.println("Exception creating admin client: " + e);
      }
      1. Properties オブジェクトをセットアップします。

        この例では、ご使用のサーバーにアクセスするために必要なプロパティーで、Properties オブジェクトをセットアップします。 この場合、SOAP コネクターを使用してサーバーにアクセスします。コネクター・タイプに対して、値 AdminClient.CONNECTOR_TYPE_SOAP を使用します。

      2. [AIX Solaris HP-UX Linux Windows][IBM i]簡単にするために、サーバーと同じマシン上でクライアント・プログラムを実行します。ホスト名には localhost を使用します。

        ローカル・ホストの代わりにリモート・ホストにアクセスするには、そのホストのネットワーク解決可能名を使用します。

      3. サーバー SOAP コネクターが listen しているポート番号を設定します。

        単一サーバー・インストールでは、アプリケーション・サーバー SOAP コネクターのデフォルト・ポート番号は 8880 です。

      4. 接続プロパティーを設定後、AdminClientFactory クラスおよび Properties オブジェクトを使用して、選択済みサーバーに接続される AdminClient オブジェクトを作成します。

        必要なプロトコルおよびセキュリティー環境などの要因に応じて、他のプロパティーを設定する必要がある場合があります。 例えば、アプリケーション・クライアント・プログラムのセキュリティーを使用可能にする場合は、 javax.net.ssl.* を組み込みます。 properties. AdminClient インターフェースについて詳しくは、 javax.net.ssl.* を参照してください。 プロパティー、および追加の作成例については、アプリケーション・プログラミング・インターフェース資料の AdminClient インターフェースを参照してください。

    • 以下の例は、リモート・メソッド呼び出し (RMI) コネクターの AdminClient インスタンスの作成方法を示しています。 一部のコマンドは印刷目的のために複数行に分割されています。
      Properties connectProps = new Properties();
      connectProps.setProperty(AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_RMI);
      connectProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
      connectProps.setProperty(AdminClient.CONNECTOR_PORT, "2809");
      connectProps.setProperty(AdminClient.USERNAME, "test2");
      connectProps.setProperty(AdminClient.PASSWORD, "user24test");
      System.setProperty("com.ibm.CORBA.ConfigURL", 
       "file:C:/AA/cf010839.26/profiles/AppSrv02/properties/sas.client.props");
      System.setProperty("com.ibm.SSL.ConfigURL", 
       "file:C:/AA/cf010839.26/profiles/AppSrv02/properties/ssl.client.props");
      AdminClient adminClient = null;
      try
      {
             adminClient = AdminClientFactory.createAdminClient(connectProps);
      }
      catch (ConnectorException e)
      {
             System.out.println("Exception creating admin client: " + e);
      }
      サポートされる構成: サーブレットや JavaServer Pages (JSP) ファイルなど、アプリケーション・サーバー上で実行されるアプリケーション・コード内で createAdminクライアント・メソッドを使用する場合は、CACHE_DISABLED プロパティーを true に設定する必要があります。 以下に例を示します。
      connectProps.setProperty(AdminClient.CACHE_DISABLED, "true");
      1. Properties オブジェクトをセットアップします。

        この例では、ご使用のサーバーにアクセスするために必要なプロパティーで、Properties オブジェクトをセットアップします。 この場合、リモート・メソッド呼び出しコネクターを使用して、サーバーにアクセスします。コネクター・タイプに対して、値 AdminClient.CONNECTOR_TYPE_RMI を使用します。

      2. [AIX Solaris HP-UX Linux Windows][IBM i]簡単にするために、サーバーと同じマシン上でクライアント・プログラムを実行します。ホスト名には localhost を使用します。

        ローカル・ホストの代わりにリモート・ホストにアクセスするには、そのホストのネットワーク解決可能名を使用します。

      3. サーバー RMI コネクターが listen しているポート番号を設定します。

        単一サーバー・インストールでは、アプリケーション・サーバー RMI コネクターのデフォルト・ポート番号は 2809 です。 WebSphere Application Server Network Deployment インストール済み環境では、デプロイメント・マネージャー RMI コネクターのデフォルト・ポート番号は 9809 です。

      4. 接続プロパティーを設定後、AdminClientFactory クラスおよび Properties オブジェクトを使用して、選択済みサーバーに接続される AdminClient オブジェクトを作成します。

        必要なプロトコルおよびセキュリティー環境などの要因に応じて、他のプロパティーを設定する必要がある場合があります。 例えば、アプリケーション・クライアント・プログラムでセキュリティーを有効にする場合、ssl.client.props ファイルおよび sas.client.props ファイルをポイントするようにシステム・プロパティーを設定する必要があります。 ローカル・マシン上で実行する場合、実際のロケーションをポイントできます。 リモート・マシン上で実行する場合、これらのプロパティー・ファイルをサーバー・マシンからコピーして、任意の場所に配置し、ファイルを配置したパスを指定できます。

        ユーザー名およびパスワードは sas.client.props ファイル内に指定できます。その場合、com.ibm.CORBA.loginSource=properties を指定します。 ユーザー名およびパスワードをクライアント・プログラム内に設定する場合、sas.client.props ファイルに com.ibm.CORBA.loginSource=none を指定します。

  2. MBean を検出します。

    AdminClient インスタンスを取得する場合、それを使用して、管理サーバーおよびアプリケーション・サーバー内の管理対象リソースにアクセスすることができます。 各管理対象リソースは、そのリソースにアクセスする際に使用される AdminService に MBean を登録します。 MBean は、MBean を識別する ObjectName インスタンスによって表されます。 ObjectName インスタンスは、ドメイン・ネームと、それに続く 1 つ以上のキー・プロパティーの順不同のセットから構成されます。 このドメイン・ネームの構文は以下のとおりです。

    [domainName]:property=value[,property=value]*
    
    WebSphere Application Serverの場合、ドメイン名は次のようになります。WebSphereまた、管理のために定義される主なプロパティーは以下のとおりです。
    表 1. キー・プロパティーの説明 キー・プロパティーには、type、name、cell、node、および process があります。
    キー・プロパティー 説明
    type MBean のタイプ。 例: Server、 TraceService、Java 仮想マシン (JVM)。
    名前 MBean の個々のインスタンスの名前の ID。
    セル MBean が実行しているセルの名前。
    ノード MBean が実行しているノードの名前。
    process MBean が実行しているプロセスの名前。

    WebSphere Application Server の一部の MBean は、追加のキー・プロパティーを使用します。 キー・プロパティーのない MBean は、 WebSphere Application Server プロセスで MBean サーバーに登録できます。 ただし、このような MBean は、製品で追加される分散機能拡張 (例えば要求ルーティングや分散イベント通知など) に参加させることはできません。

    ObjectName インスタンスのキー・プロパティーの完全なセットを知っている場合は、それを使用して、それが識別する MBean を検出することができます。 ただし、キー・プロパティーをすべて知らないで MBean を検出する方が、通常はより実用的であり、便利です。 突き合わせる必要のないキー・プロパティーについては、ワイルドカード文字のアスタリスク (*) を使用します。 次のテーブルは、単一または複数の MBean を突き合わせるワイルドカード・キー・プロパティーを持つオブジェクト名の例の一部を提供します。
    表 2. ワイルドカード・キー・プロパティーを持つオブジェクト名の例。 ワイルドカードのキー・プロパティーを指定する場合には、アスタリスク (*) を組み込みます。
    オブジェクト名 説明
    *:type=Server,* タイプ Server のすべての MBean
    *:node=Node1,type=Server,* Node1 上のタイプ Server のすべての MBean
    *:type=JVM,process=server1,node=Node1,* server1 node Node1 という名前のサーバーの JVM MBean
    *:process=server1,* server1 という名前のすべてのサーバーのすべての MBean
    *:process=server1,node=Node1,* Node1 上の server1 という名前のサーバーのすべての MBean

    キー・プロパティーに一致するオブジェクト名を使用して照会することにより、MBean を探し出すことができます。 以下の例は、ノード MyNode のノード・エージェント用の MBean を検出する方法を示しています。

    String nodeName = "MyNode";
    String query = "WebSphere:type=NodeAgent,node=" + nodeName + ",*";
    ObjectName queryName = new ObjectName(query);
    ObjectName nodeAgent = null;
    Set s = adminClient.queryNames(queryName, null);
    if (!s.isEmpty())
        nodeAgent = (ObjectName)s.iterator().next();
    else
        System.out.println("Node agent MBean was not found");
    1. タイプおよびノードのキー・プロパティーを指定する照会ストリングを使用して、ObjectName インスタンスを構築します。

      残りのキー・プロパティーに対してワイルドカードを使用することにより、このパターンは、ノード MyNode 上のタイプ NodeAgent のすべての MBean のオブジェクト名と一致します。 ノードごとに 1 つのノード・エージェントしか存在しないため、ユーザーが必要な MBean を識別するにはこの情報で十分です。

    2. この ObjectName インスタンスを、AdminClient インターフェースの queryNames メソッドに提供します。

      AdminClient インターフェースは、AdminService インターフェースに対してリモート呼び出しを実行し、照会と一致する MBean オブジェクト名のセットを取得します。 このメソッドに対する 2 番目のヌル・パラメーターは、最初のパラメーターで ObjectName パターンと一致する MBeans 上で、追加照会として使用できる照会式 (QueryExp) オブジェクトです。

    3. セット・イテレーターを使用し、最初 (この場合は唯一) のエレメントを取得します。

      このエレメントは、ノード・エージェントの MBean ObjectName インスタンスです。

  3. MBean を使用します。

    特定の MBean ができることは、その MBean の管理インターフェースによります。 MBean は、以下を宣言することができます。

    • ユーザーが取得または設定できる属性
    • ユーザーが呼び出すことができるオペレーション
    • ユーザーがリスナーを登録できる通知
    WebSphere Application Serverによって提供される MBean については、MBean API の資料に、それらがサポートするインターフェースに関する情報が記載されています。
    以下の例では、上記で検出した NodeAgent MBean で使用可能なオペレーションの 1 つを呼び出します。 以下の例では、MyServer アプリケーション・サーバーを始動しま す。
    String opName = "launchProcess";
    String signature[] = { "java.lang.String" };
    String params[] = { "MyServer" };
    try
    {
         adminClient.invoke(nodeAgent, opName, params, signature);
    }
    catch (Exception e)
    {
         System.out.println("Exception invoking launchProcess: " + e);
    }
    AdminClient.invoke メソッドは、 MBean でオペレーションを呼び出す一般的な方法です。 パラメーターは次のとおりです。
    • ターゲット MBean のオブジェクト名、nodeAgent
    • オペレーションの名前、opName
    • オペレーション・パラメーターが含まれるオブジェクト配列、params
    • オペレーション・シグニチャーが含まれるストリング配列、signature
    この例の launchProcess オペレーションは、始動するサーバーを識別するストリングである単一パラメーターを持ちます。

    呼び出されたメソッドはオブジェクト・インスタンスを戻します。呼び出しコードはオブジェクト・インスタンスを使用して、呼び出されたオペレーションの正しい戻りの型にキャストすることができます。 launchProcess オペレーションはボイドと宣言されるため、この例では戻り値を無視することができます。

  4. イベントに登録します。

    リソースの管理に加えて、JMX API は、特定の管理イベントをモニターするアプリケーションもサポートしています。 特定のイベントは、サーバーが始動する際などに通知を作成します。 管理アプリケーションは、これらの通知に対するリスナーとして登録できます。 WebSphere Application Server は、JMX 通知モデルの完全な実装を提供し、分散環境で通知を受信できるように追加機能を提供します。 製品の MBean から発行される通知の完全なリストについては、MBean API の文書で com.ibm.websphere.management.NotificationConstants クラスの項目を参照してください。

    以下の例は、ObjectName ノード・エージェントを使用して、MBean から発行されるイベント通知へのオブジェクトの登録方法を示します。

    adminClient.addNotificationListener(nodeAgent, this, null, null);

    この例では、最初のパラメーターはノード・エージェント MBean の ObjectName です。 2 番目のパラメーターはリスナー・オブジェクトを識別し、これは NotificationListener インターフェースを実装する必要があります。 この場合、呼び出しオブジェクトはリスナーです。 3 番目のパラメーターは、ユーザーが受け取りたい通知を指示するために使用できるフィルターです。 この値を null として残す場合、この MBean からすべての通知を受け取ります。 最後のパラメーターは、通知が発行される際に、JMX API をユーザーに戻るように設定するために使用できる handback オブジェクトです。

    アプリケーション・サーバーが提供する他の拡張機能は、1 回の呼び出しで、複数の MBean の通知リスナーとして登録する機能です。 この登録は、標準 JMX addNotificationListener メソッドの拡張機能である AdminClient インターフェースの addNotificationListenerExtended メソッドを通じて実行されます。 この拡張機能メソッドにより、現在は活動中でない MBeans に登録することもできます。 管理クライアント・プログラムの存続期間中に停止および再開できるリソースからイベントをモニターしたい状況では、この登録は重要になります。

  5. イベントを処理します。

    オブジェクトは、handleNotification メソッドを介して JMX イベント通知を受信します。このメソッドは NotificationListener インターフェースによって定義され、すべてのイベント受信側に実装されなければなりません。 以下の例は、 受信する通知をレポートする handleNotification メソッドの実装です。

    public void handleNotification(Notification n, Object handback)
    {
         System.out.println("***************************************************");
         System.out.println("* Notification received at " + new Date().toString());
         System.out.println("* type      = " + ntfyObj.getType());
         System.out.println("* message   = " + ntfyObj.getMessage());
         System.out.println("* source    = " + ntfyObj.getSource());
         System.out.println(
         "* seqNum    = " + Long.toString(ntfyObj.getSequenceNumber()));
         System.out.println("* timeStamp = " + new Date(ntfyObj.getTimeStamp()));
         System.out.println("* userData  = " + ntfyObj.getUserData());
         System.out.println("***************************************************");
    }

結果

管理クライアントは、MBean から送出されたイベント通知を処理することができます。

問題の回避: クライアント・プログラムが RMI または JSR160RMI コネクターを介して通知リスナーを登録し、ORB スレッドが実行を停止しないために Java 仮想マシンが終了しない場合は、 System.exit() ステートメントをクライアント・プログラムに追加します。 ORB は、クライアントへの通知伝搬を処理するスレッドを開始します。 このスレッドは、クライアントのメイン・スレッドに System.exit() ステートメントが含まれないと、メイン・スレッドで自動的に終了しません。 クライアント・プログラム内の場所に、ORB スレッドとメイン・スレッドが処理を停止できるようにする System.exit() ステートメントを入れてください。 例えば、クライアント・プログラムのメインの try ブロックの catch または finally 節に、 System.exit() ステートメントを入れます。

例: 管理クライアント・プログラム

この例では、ノード・エージェント・サーバーへの接続方法を紹介しますこの方法は、ご使用の製品では使用できません。 ただし、ホストとポートの値を変更することにより、サーバーに接続することができます。 ご使用のサーバーを、ノード・エージェント・サーバー参照の代わりにしてください。 NodeAgent MBean は、この製品には使用できないため、queryNames ストリングを代わりに使用して、別の MBean を検索してください。

以下の名前のファイルに内容をコピーします。AdminClientExample.java. ノード名とサーバー名を構成に適した値に変更した後、「 WebSphere Application Server 管理 Java API 」の説明に従って、それをコンパイルして実行することができます。
import java.util.Date;
import java.util.Properties;
import java.util.Set;

import javax.management.InstanceNotFoundException;
import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;

import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.AdminClientFactory;
import com.ibm.websphere.management.exception.ConnectorException;

public class AdminClientExample implements NotificationListener
{

    private AdminClient adminClient;
    private ObjectName nodeAgent;
    private long ntfyCount = 0;

    public static void main(String[] args)
    {
       AdminClientExample ace = new AdminClientExample();

       // Create an AdminClient
       ace.createAdminClient();

       // Find a NodeAgent MBean
       ace.getNodeAgentMBean("ellington");

       // Invoke launchProcess
       ace.invokeLaunchProcess("server1");

       // Register for NodeAgent events
       ace.registerNotificationListener();
        
       // Run until interrupted
       ace.countNotifications();
    }

    private void createAdminClient()
    {
        // Set up a Properties object for the JMX connector attributes
        Properties connectProps = new Properties();
        connectProps.setProperty(
        AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);
        connectProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
        connectProps.setProperty(AdminClient.CONNECTOR_PORT, "8879");
        
        // Get an AdminClient based on the connector properties
        try
        {
            adminClient = AdminClientFactory.createAdminClient(connectProps);
        }
        catch (ConnectorException e)
        {
            System.out.println("Exception creating admin client: " + e);
            System.exit(-1);
        }
        
        System.out.println("Connected to DeploymentManager");
    }
    
    
    private void getNodeAgentMBean(String nodeName)
    {
        // Query for the ObjectName of the NodeAgent MBean on the given node
        try
        {
            String query = "WebSphere:type=NodeAgent,node=" + nodeName + ",*";
            ObjectName queryName = new ObjectName(query);
            Set s = adminClient.queryNames(queryName, null);
            if (!s.isEmpty())
                nodeAgent = (ObjectName)s.iterator().next();
            else
            {
                System.out.println("Node agent MBean was not found");
                System.exit(-1);
            }
        }
        catch (MalformedObjectNameException e)
        {
            System.out.println(e);
            System.exit(-1);
        }
        catch (ConnectorException e)
        {
            System.out.println(e);
            System.exit(-1);
        }
        
        System.out.println("Found NodeAgent MBean for node " + nodeName);
    }
    
    private void invokeLaunchProcess(String serverName)
    {
        // Use the launchProcess operation on the NodeAgent MBean to start
        // the given server
        String opName = "launchProcess";
        String signature[] = { "java.lang.String" };
        String params[] = { serverName };
        boolean launched = false;
        try
        {
            Boolean b = (Boolean)adminClient.invoke(
            
nodeAgent, opName, params, signature);
            launched = b.booleanValue();
            if (launched)
                System.out.println(serverName + " was launched");
            else
                System.out.println(serverName + " was not launched");

        }
        catch (Exception e)
        {
            System.out.println("Exception invoking launchProcess: " + e);
        }
    }
    
    private void registerNotificationListener()
    {
        // Register this object as a listener for notifications from the
        // NodeAgent MBean.  Don't use a filter and don't use a handback
        // object.
        try
        {
            adminClient.addNotificationListener(nodeAgent, this, null, null);
            System.out.println("Registered for event notifications");
        }
        catch (InstanceNotFoundException e)
        {
            System.out.println(e);
            e.printStackTrace();
        }
        catch (ConnectorException e)
        {
            System.out.println(e);
            e.printStackTrace();
        }
    }
    
    public void handleNotification(Notification ntfyObj, Object handback)
    {
        // Each notification that the NodeAgent MBean generates will result in
        // this method being called
        ntfyCount++;
        System.out.println("***************************************************");
        System.out.println("* Notification received at " + new Date().toString());
        System.out.println("* type      = " + ntfyObj.getType());
        System.out.println("* message   = " + ntfyObj.getMessage());
        System.out.println("* source    = " + ntfyObj.getSource());
        System.out.println(
        "* seqNum    = " + Long.toString(ntfyObj.getSequenceNumber()));
        System.out.println("* timeStamp = " + new Date(ntfyObj.getTimeStamp()));
        System.out.println("* userData  = " + ntfyObj.getUserData());
        System.out.println("***************************************************");

    }
    
    private void countNotifications()
    {
        // Run until killed
        try
        {
            while (true)
            {
                Thread.currentThread().sleep(60000);
                System.out.println(ntfyCount + " notification have been received");
            }
        }
        catch (InterruptedException e)
        {
        }
    }
    
}