ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Service Bus管理者ガイド
11g リリース1 (11.1.1.6.2)
B61436-05
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

D JMXモニタリングAPI

この章では、OSBモニター・データへの外部アクセスを提供するOracle Service BusのJMX(Java Management Extensions)モニタリングAPIについて説明します。

JMXモニタリングAPIの主な目的は、一括操作をサポートする、効率的な低レベルのAPIを提供することです。JMXをトランスポートとして使用することでこれを行います。このAPIは、JMXベースのツールと互換性のある高レベルのAPIではありません。ただし、クライアント・ソフトウェアを開発する場合は、JMXベースのツールをサポートする高レベルのJMX APIを開発することもできます。

D.1 説明

JMXモニタリングAPIは、トランスポートとしてのみJMXを利用します。

任意のモニター対象サービスとそのコンポーネントのモニター・データ(統計情報)を取得するために必要なすべての操作を提供する公開MBeanを公開します。

また、MBeanによって提供される操作を実行するために必要な、一連の公開POJOオブジェクトも公開します。

サード・パーティ製クライアント・ソフトウェアが、Oracle Service Busのモニター・システムに格納されている統計情報の階層構造の詳細を認識する必要はありません。

これらのAPIを使用することで、モニター/管理システムをOracle Service Busと統合し、以下の操作を行うことができます。

D.2 概念

公開JMX APIは、モニター対象サービスをチェックし、それらからデータを取得する操作を含むServiceDomainMBeanの単一のインスタンスによってモデル化されます。

POJOの公開セットは、ServiceDomainMbeanとともに統計のモニター用の完全なAPIを提供する、追加のオブジェクトとメソッドを提供します。

次の項では、POJOおよびMBeanについて簡単に説明します。Java APIリファレンスには、詳細な説明が記載されています。また、リソースについてレポートされる統計の詳細な説明も記載されています。

この章の最後にある重要な注意事項を必ずお読みください。

D.2.1 公開POJOオブジェクト

以下のPOJOオブジェクトは、このAPIの一部として公開されています。

D.2.1.1 ResourceType

このオブジェクトは、サービスのモニターに対して有効な、すべてのタイプのリソースを示します。enum定数には、タイプSERVICEFLOW_COMPONENTURIおよびWEBSERVICE_OPERATIONを示す4種類があります。

Oracle Fusion Middleware Oracle Service Bus Java APIリファレンスcom.bea.wli.monitoring.ResourceTypeに関する項を参照してください。

D.2.1.2 ServiceResourceStatistic

このオブジェクトは、すべてのビジネス・サービスおよびプロキシ・サービスのリソース・タイプとそれらに関連付けられている統計を示します。すべてのリソースまたは指定されたリソースの統計を取得するメソッドがあります。

Oracle Fusion Middleware Oracle Service Bus Java APIリファレンスcom.bea.wli.monitoring.ServiceResourceStatisticに関する項を参照してください。

D.2.1.3 ResourceStatistic

このオブジェクトは、統計の収集がサポートされるリソースを示します。リソースの名前、タイプ、および統計を取得するメソッドがあります。

Oracle Fusion Middleware Oracle Service Bus Java APIリファレンスcom.bea.wli.monitoring.ResourceStatisticに関する項を参照してください。

D.2.1.4 StatisticValue

このオブジェクトは、リソースの統計値を示します。現在モニター・システムは、統計値の以下のタイプをサポートしています。両方ともネストされたクラスです。

  • CountStatistic

  • IntervalStatistic

  • StatusStatistic

StatisticValueは抽象クラスであるため、数および時間間隔の統計値を示す具体的なオブジェクトをそれから生成できます。これには、getName()メソッドおよびgetType()メソッドが含まれます。

Oracle Fusion Middleware Oracle Service Bus Java APIリファレンスcom.bea.wli.monitoring.StatisticValueに関する項を参照してください。

D.2.1.5 StatisticType

このオブジェクトは、統計の事前定義されたタイプを示します。STATUSCOUNTおよびINTERVALという3つのenumタイプがあります。

Oracle Fusion Middleware Oracle Service Bus Java APIリファレンスcom.bea.wli.monitoring.StatisticValueに関する項を参照してください。

D.2.2 ServiceDomainMBean

これは、公開JMX APIの一部として公開されている唯一のMBeanです。モニター対象サービスを検索したり、統計を取得およびリセットしたりするメソッドを提供します。

Oracle Fusion Middleware Oracle Service Bus Java APIリファレンスcom.bea.wli.monitoring.ServiceDomainMBeanに関する項を参照してください。

D.2.3 統計の詳細

次の項では、各リソース・タイプについてレポートされる統計の詳細について説明します。

D.2.3.1 リソース・タイプの統計の詳細 - SERVICE

サービスは、Oracle Service Bus内で構成されているインバウンド・エンドポイントまたはアウトバウンド・エンドポイントです。関連付けられているWSDL、セキュリティ設定などがある場合があります。

以下の統計が、このリソース・タイプについてレポートされます。

表D-1 SERVICE統計

統計名 種類

message-count

件数

error-count

件数

failover-count

件数

wss-error

件数

response-time

間隔

validation-errors

件数

failure-rate

件数

success-rate

件数

sla-severity-warning

件数

sla-severity-major

件数

sla-severity-minor

件数

sla-severity-normal

件数

sla-severity-fatal

件数

sla-severity-critical

件数

sla-severity-all

件数

pipeline-severity-warning

件数

pipeline-severity-major

件数

pipeline-severity-minor

件数

pipeline-severity-normal

件数

pipeline-severity-fatal

件数

pipeline-severity-critical

件数

pipeline-severity-all

件数

throttling-time

間隔

uri-offline-count

件数

hit-count

件数


統計sla-severity-warningsla-severity-majorsla-severity-minorsla-severity-normalsla-severity-fatalsla-severity-criticalおよびsla-severity-allは、プロキシ・サービスおよびビジネス・サービスの両方について収集されます。

統計pipeline-severity-warningpipeline-severity-majorpipeline-severity-minorpipeline-severity-normalpipeline-severity-fatalpipeline-severity-criticalおよびpipeline-severity-allは、プロキシ・サービスのみについて収集されます。


注意:

統計「wss-error」は、Webサービスのセキュリティ違反数を示します。ビジネス・サービスおよびプロキシ・サービスの両方に適用されます。

統計「検証エラー数」は、プロキシ・サービスのみに適用され、ビジネス・サービスについては返されません。

統計「failover-count」は、ビジネス・サービスのみに適用され、プロキシ・サービスについては返されません。

ServiceDomainMBeanを使用して、クラスタ・ドメインから管理対象サーバーの統計を取得する場合、プロキシ・サービスについての統計には、sla-severity-normalsla-severity-minorsla-severity-majorsla-severity-warningsla-severity-criticalsla-severity-fatalsla-severity-allは含まれません。


D.2.3.2 リソース・タイプの統計の詳細 - FLOW_COMPONENT

統計は、プロキシ・サービスのフロー定義に示される以下の2つのタイプのコンポーネントについて収集されます。

  • パイプライン・ペア・ノード

  • ルート・ノード

パイプラインは、現在のメッセージに対して順次実行されるステージで構成される、一方向の処理の流れです。ステージは、トランスフォーメーション、ロギング、およびパブリッシュなどのアクティビティの実行に使用されます。

パイプラインには、リクエスト、レスポンス、およびエラーの3つのカテゴリがあります。

パイプライン・ペア・ノードは、1つのリクエスト・パイプラインと1つのレスポンス・パイプラインを1つの最上位要素に結び付けたものです。

ルーティング・ノードは、一連のルートで構成されます。ルートは、ターゲット・サービスを特定し、そのサービスへメッセージをパッケージ化し、送信する方法を決定する追加の構成オプションを含みます。ルーティング・ノードは、リクエスト処理の一部として選択されている1つのルートになります。

以下の統計が、このリソース・タイプについてレポートされます。

表D-2 FLOW_COMPONENT統計

統計名 種類

elapse-time

間隔

message-count

件数

error-count

件数



注意:

パイプラインおよびルート・ノードの統計は、フロー・コンポーネントの統計として返されます。enumResourceType.FLOW_COMPONENTは、パイプラインおよびルート・ノードの両方を示します。そのため、クライアントは、返されたフロー・コンポーネントがパイプラインであるかルート・ノードであるかを確認することはできません。ただし、フロー・コンポーネントの名前が、タイプを示唆する場合があります。


D.2.3.3 リソース・タイプの統計の詳細 - WEBSERVICE_OPERATION

このリソース・タイプは、WSDL操作に関連する統計情報を提供します。統計は、それぞれの定義された操作についてレポートされます。

以下の統計がレポートされます。

表D-3 WEBSERVICE_OPERATION統計

統計名 種類

elapse-time

間隔

message-count

件数

error-count

件数


D.2.3.4 リソース・タイプの統計の詳細 - URI

このリソース・タイプは、ビジネス・サービスのエンドポイントURIに関連する統計情報を提供します。統計は、それぞれの定義されたエンドポイントURIについてレポートされます。以下の統計がレポートされます。

表D-4 エンドポイントURIの統計

統計名 種類

message-count

件数

error-count

件数

response-time

間隔

status

ステータス


D.2.4 注意事項

次に注意してください。

  • クライアント・プログラムは、定期的に変更を確認しない限り、モニターが有効になっている新しく追加されたサービス、またはモニターが有効に変更されたサービスを認識しません。

  • リセット・オプションは頻繁に実行しません。リセットの実行には15分を超える間隔を空けることをお薦めします。

  • 複数のスレッドまたはプロセスを同時に実行している場合は、このAPIの使用は推奨されません。1つのスレッドまたはプロセスで実行されたリセットを、それ以外のスレッドまたはプロセスが認識できないためです。この注意事項は、Oracle Service Bus管理コンソールのモニターのダッシュボードから実行されたリセットにも当てはまります(このリセットを、このAPIが認識できないためです)。

D.2.5 パフォーマンス

パフォーマンスは、Oracle Service Bus管理コンソールのモニターのダッシュボードで計測されるパフォーマンスよりも高いか、または同等です。

D.3 APIの使用方法の例

この項のサンプル・プログラムは、JMXモニタリングAPIの使用方法について説明しています。

以下の手順は、モニターが有効になっているプロキシ・サービスについて、統計を取得する方法について説明しています。

  1. MBeanサーバーからServiceDomainMBeanを取得します。

  2. ServiceDomainMBeangetMonitoredProxyServiceRefs操作を使用して、モニターされるプロキシ・サービスの参照を取得します。

  3. 取得した参照から必要なプロキシ・サービスの参照を識別します。

  4. 必要なプロキシ・サービスのServiceDomainMBeangetProxyServiceStatistics操作を使用して、ServiceResourceStatisticsを取得します。

  5. ServiceResourceStatisticの操作を使用して、すべてのResourceStatisticオブジェクトを取得します。

  6. 取得したResourceStatisticオブジェクトごとに、getStatistics操作を使用して、StatisticValueオブジェクトを取得し、統計情報を出力します。

  7. 必要に応じてプロセスを繰り返します。

D.3.1 サンプル・プログラム

以下のサンプル・プログラムでは、次のことを行う方法について説明します。

  1. モニターが有効になっているサービスをタイプに応じて検索します。

  2. リソース・タイプ・フィルタを設定します。

  3. 1つまたは複数のサービスの統計をタイプに応じて取得します。

  4. ServiceResourceStatisticsオブジェクトから統計を抽出します。

  5. 取得した統計を適切な形式で保存します。

  6. 1つまたは複数のサービスの統計をリセットします。

このプログラムを実行するには、次のJARファイルをクラス・パスに含めます。 

  • weblogic.jar

  • sb-kernel-api.jar

  • com.bea.common.configfwk_version.jar

  • com.bea.core.management.core_version.jar

  • com.bea.core.management.jmx_version.jar

お使いの環境に合せて、次のコードに含まれるSERVER_NAME、HOSTNAMEPORTUSERNAMEおよび/またはPASSWORDのデフォルト値をリセットする必要がある場合があります。


注意:

ビジネス・サービスのエンド・ポイントごとのステータス統計を取得する必要がある場合は、クラスタ環境でSERVER_NAME属性を設定してください。単一のノードで実行している場合は、このプロパティを設定しない場合でもステータス統計が返されます。


パフォーマンス上の理由から、大量のサービスの統計を頻繁に抽出したりリセットしたりしないでください。D.2.4項「注意事項」を参照してください。サンプル・プログラムは、例D-1を参照してください。

例D-1 モニターが有効になっているプロキシ・サービスについての統計を取得するサンプル・プログラム

package tests.monitoring;

import com.bea.wli.config.Ref;
import com.bea.wli.monitoring.*;
import weblogic.management.jmx.MBeanServerInvocationHandler;

import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.util.*;
import java.text.SimpleDateFormat;

/**
   * This class provides sample code showing how to use
   * ServiceDomainMBean.
   * It shows how to:
   * 1. Find business and proxy services enabled for monitoring.
   * 2. Get statistics for one or more business and proxy services.
   * 3. Perform reset operation on one or more business and proxy services.
   * 4. Handle exceptions.
   * It uses a timer to retrieve statistics, save them in a file, and
   * perform resets in a recursive manner.
*/

public class ServiceStatisticsRetriever {
     private ServiceDomainMBean serviceDomainMbean = null;
     private String serverName = null;

     /**
       * Retrieve statistics for all business services being monitored in the
      * domain and reset statistics for the same.
      * @throws Exception
      */

     void getAndResetStatsForAllMonitoredBizServices() throws Exception {
          Ref[] serviceRefs =
               serviceDomainMbean.getMonitoredBusinessServiceRefs();

          // Create a bitwise map for desired resource types.
          int typeFlag = 0;
          typeFlag = typeFlag | ResourceType.SERVICE.value();
          typeFlag = typeFlag | ResourceType.WEBSERVICE_OPERATION.value();
          typeFlag = typeFlag | ResourceType.URI.value();

          HashMap<Ref, ServiceResourceStatistic> resourcesMap = null;
          HashMap<Ref, ServiceResourceStatistic> resourcesMapOnSingle
               Server = null;
          // Get cluster-level statistics.
          try {
               // Get statistics.
               System.out.println("Now trying to get statistics for -" +
                    serviceRefs.length + " business services...");
               resourcesMap =
                    serviceDomainMbean.getBusinessServiceStatistics
                         (serviceRefs, typeFlag, serverName);
               // Reset statistics.
               long resetRequestTime =
                    serviceDomainMbean.resetStatistics (serviceRefs);

               // Save retrieved statistics.
               String fileName = "BizStatistics_" +
                    new SimpleDateFormat("yyyy_MM_dd_HH_mm").
                         format(new Date(System. currentTimeMillis()))
                              + ".txt";
               saveStatisticsToFile(resourcesMap, resetRequestTime,
                    fileName);
          }
          catch (IllegalArgumentException iae) {
               System.out.println("===============================\n");
               System.out.println("Encountered IllegalArgumentException...
                    Details:");
               System.out.println(iae.getMessage());
               System.out.println("Check if proxy ref was passed OR
                    flowComp " +
                    "resource was passed OR bitmap is invalid..." +
                    "\nIf so correct it and try again!!!");
               System.out.println("==================================\n");
               throw iae;
          }
          catch (DomainMonitoringDisabledException dmde) {
               /** Statistics not available as monitoring is turned off at
                    domain level.
                */
               System.out.println("==================================\n");
               System.out.println("Statistics not available as
                    monitoring " +
               "is turned off at domain level.");
               System.out.println("==============================\n");
               throw dmde;
          }
          catch (MonitoringException me) {
               // Internal problem... May be aggregation server is
                    crashed...
               System.out.println("================================\n");
               System.out.println("ERROR: Statistics is not available...
                   " +
                    "Check if aggregation server is crashed...");
               System.out.println("=================================\n");
               throw me;
          }
     }
     /**
      * Retrieve statistics for all proxy services being monitored in the
      * domain and reset statistics for the same.
      * @throws Exception
      */
     void getAndResetStatsForAllMonitoredProxyServices() throws Exception {
          Ref[] serviceRefs =
               serviceDomainMbean.getMonitoredProxyServiceRefs();
          // Create a bitwise map for desired resource types.
          int typeFlag = 0;
          typeFlag = typeFlag | ResourceType.SERVICE.value();
          typeFlag = typeFlag | ResourceType.FLOW_COMPONENT.value();
          typeFlag = typeFlag | ResourceType.WEBSERVICE_OPERATION.value();

          HashMap<Ref, ServiceResourceStatistic> resourcesMap = null;
          
          // Get cluster-level statistics.
          try {
               // Get statistics.
               System.out.println("Now trying to get statistics for -" +
                    serviceRefs.length + " proxy services...");
               resourcesMap = serviceDomainMbean.getProxyServiceStatistics
                    (serviceRefs,typeFlag, null);

               // Reset statistics.
               long resetRequestTime =
                    serviceDomainMbean.resetStatistics(serviceRefs);

               // Save retrieved statistics.
               String fileName = "ProxyStatistics_" +
                    new SimpleDateFormat("yyyy_MM_dd_HH_mm").
                         format(new Date(System.currentTimeMillis())) +
                              ".txt";
               saveStatisticsToFile(resourcesMap, resetRequestTime,
                    fileName);
          }
          catch (IllegalArgumentException iae) {
               System.out.println("===================================\n");
              System.out.println("Encountered IllegalArgumentException...
                    Details:");
              System.out.println(iae.getMessage());
                  System.out.println("Check if business ref was passed OR bitmap
                    is " + "invalid...\nIf so correct it and try again!!!");
               System.out.println("===================================\n");
                    throw iae;
          }


          catch (DomainMonitoringDisabledException dmde) {
               /** Statistics not available as monitoring is turned off at the
              * domain level.
              */
               System.out.println("===================================\n");
              System.out.println("Statistics not available as monitoring
                   " +
                    "is turned off at domain level.");
               System.out.println("===================================\n");
              throw dmde;
          }
          catch (MonitoringException me) {
               // Internal problem ... May be aggregation server is
                    crashed ...
               System.out.println("===================================\n");
                System.out.println("ERROR: Statistics is not available... " +
                    "Check if aggregation server is crashed...");
               System.out.println("===================================\n");
              throw me;
          }
     }

     /**
      * Saves statistics of all services from the specified map.
      * @param statsMap Map containing statistics for one or more services
      * of the same type; i.e., business or proxy.
      * @param resetReqTime Reset request time. This information will be
      * written at the end of the file, provided it is not zero.
      * @param fileName Statistics will be saved in a file with this name.
      * @throws Exception
      */
     private void saveStatisticsToFile(
          HashMap<Ref, ServiceResourceStatistic> statsMap,
               long resetReqTime, String fileName) throws Exception {
          if (statsMap == null) {
               System.out.println("\nService statistics map is null...
                    Nothing to save.\n");
          }
          if (statsMap.size() == 0) {
               System.out.println("\nService statistics map is empty...
                    Nothing to save.\n");
          }
          FileWriter out = new FileWriter(new File(fileName));

          out.write("*********************************************\n");
          out.write("This file contains statistics for " + statsMap.size()
               + " services.\n");
          out.write("***********************************************\n");

          Set<Map.Entry<Ref, ServiceResourceStatistic>> set =
               statsMap.entrySet();
          
          System.out.println(new StringBuffer().append("\nWriting stats to
               the file - ").append(fileName).append("\n").toString());

          // Print statistical information of each service
          for (Map.Entry<Ref, ServiceResourceStatistic> mapEntry : set) {
               out.write(new StringBuffer().
                        append("\n\n======= Pirnting statistics for service ").
                    append(mapEntry.getKey().getFullName()).
                    append("=======\n").toString());

                   ServiceResourceStatistic serviceStats = mapEntry.getValue();
               out.write(new StringBuffer().
                    append("Statistic collection time is - ").
                    append(new Date(serviceStats.getCollectionTimestamp
                         ())).
                    append("\n").toString());

               ResourceStatistic[] resStatsArray = null;
               try {
                    resStatsArray = serviceStats.getAllResourceStatistics
                         ();
               }
               catch (MonitoringNotEnabledException mnee) {
                    // Statistics not available
                    out.write("WARNING: Monitoring is not enabled for  " +
                         "this service... Do someting...");
                    out.write("=====================================\n");
                    continue;
               }
               
               catch (InvalidServiceRefException isre) {
                    // Invalid service
                    out.write("ERROR: Invlaid Ref. May be this service is
                         " +
                         "deleted. Do something...");
                    out.write("======================================\n");
                    continue;
               }

               catch (MonitoringException me) {
                    // Statistics not available
                    out.write("ERROR: Failed to get statistics for this
                         service... " + "Details: " + me.getMessage());
                    me.printStackTrace();
                    out.write("======================================\n");
                    continue;
               }
               for (ResourceStatistic resStats : resStatsArray) {
                    // Print resource information
                    out.write("\nResource name: " + resStats.getName());
                    out.write("\tResource type: " +
                         resStats.getResourceType().toString());

                    // Now get and print statistics for this resource
                          StatisticValue[] statValues = resStats.getStatistics();
                    for (StatisticValue value : statValues) {
                         out.write("\n\t\tStatistic Name - " +
                              value.getName ());
                         out.write("\n\t\tStatistic Type - " +
                              value.getType().toString());

                         // Determine statistics type
                           if ( value.getType() == StatisticType.INTERVAL ) {
                              StatisticValue.IntervalStatistic is =
                               (StatisticValue.IntervalStatistic)value;

                              // Print interval statistics values
                              out.write("\n\t\t\t\tCount Value
                                    - " + is.getCount());
                              out.write("\n\t\t\t\tMin Value - " +
                                    is.getMin());
                              out.write("\n\t\t\t\tMax Value - " +
                                    is.getMax());
                              out.write("\n\t\t\t\tSum Value - " +
                                    is.getSum());
                              out.write("\n\t\t\t\tAve Value - " +
                                    is.getAverage());
                         }
                         else if ( value.getType() == StatisticType.
                              COUNT ) {
                              StatisticValue.CountStatistic cs =
                                   (StatisticValue.CountStatistic)
                                        value;

                              // Print count statistics value
                              out.write("\n\t\t\t\tCount Value - " +
                                    cs.getCount());
                         }
                         else if ( value.getType() == StatisticType.STATUS
                              ){
                              StatisticValue.StatusStatistic ss =
                                   (StatisticValue.StatusStatistic)value;
                              // Print count statistics value
                              out.write("\n\t\t\t\t Initial Status - " +
                                    ss.getInitialStatus());
                              out.write("\n\t\t\t\t Current Status - " +
                                    ss.getCurrentStatus());

                         }
                    }
               }
               out.write("\n=========================================\n");
          }
          if (resetReqTime > 0) {
               // Save reset request time.
               out.write("\n*****************************************\n");
                 out.write("Statistics for all these services are RESET.\n");
               out.write("RESET request time is " +
                    new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").
                         format(new Date(resetReqTime)));
               out.write("\n****************************************\n");
          }

          // Flush and close file.
          out.flush();
          out.close();
     }

     /**
      * Init method.
      *
      * @param props Properties required for initialization.
      * @throws Exception
      */
     private void init(HashMap props) throws Exception {
          Properties properties = new Properties();
          properties.putAll(props);
          getServiceDomainMBean(properties.getProperty("HOSTNAME"),
               Integer.parseInt(properties.getProperty("PORT", "7001")),
               properties.getProperty("USERNAME"),
               properties.getProperty("PASSWORD"));
          serverName = properties.getProperty("SERVER_NAME");
     }


     /**
       * Gets an instance of ServiceDomainMBean from the weblogic server.
       *
       * @param host
       * @param port
       * @param username
       * @param password
       * @throws Exception
       */
     private void getServiceDomainMBean(String host, int port, String
               username, String password) throws Exception {
          InvocationHandler handler =
               new ServiceDomainMBeanInvocationHandler(host, port,
                    username,password);
          Object proxy = Proxy.newProxyInstance(
               ServiceDomainMBean.class.getClassLoader(),
               new Class[]{ServiceDomainMBean.class}, handler);
          serviceDomainMbean = (ServiceDomainMBean) proxy;
     }

     /**
      * Invocation handler class for ServiceDomainMBean class.
      */
     public static class ServiceDomainMBeanInvocationHandler
               implements InvocationHandler {
          private String jndiURL =
               "weblogic.management.mbeanservers.domainruntime";
          private String mbeanName = ServiceDomainMBean.NAME;
          private String type = ServiceDomainMBean.TYPE;
     
          private String protocol = "t3";
          private String hostname = "localhost";
          private int port = 7001;
          private String jndiRoot = "/jndi/";

          private String username = "weblogic";
          private String password = "weblogic";

          private JMXConnector conn = null;
          private Object actualMBean = null;

          public ServiceDomainMBeanInvocationHandler(String hostName, int
               port, String userName, String password) {
               this.hostname = hostName;
               this.port = port;
               this.username = userName;
               this.password = password;
          }

          /**
            * Gets JMX connection
            * @return JMX connection
            * @throws IOException
            * @throws MalformedURLException
            */
          public JMXConnector initConnection()
                    throws IOException, MalformedURLException {
               JMXServiceURL serviceURL = new JMXServiceURL(protocol,
                    hostname, port, jndiRoot + jndiURL);
               Hashtable<String, String> h = new Hashtable<String,
                    String>();

               if (username != null)
                    h.put(Context.SECURITY_PRINCIPAL, username);
               if (password != null)
                    h.put(Context.SECURITY_CREDENTIALS, password);

               h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
                    "weblogic.management.remote");
               return JMXConnectorFactory.connect(serviceURL, h);
          }

          /**
            * Invokes specified method with specified params on specified
            * object.
            * @param proxy
            * @param method
            * @param args
            * @return
            * @throws Throwable
            */
          public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
               try {
                    if (conn == null) {
                         conn = initConnection();
                         }
                    if (actualMBean == null) {
                         actualMBean =
                              findServiceDomain(conn.getMBeanServer
                              Connection(),mbeanName, type, null);
                     }
                    Object returnValue = method.invoke(actualMBean, args);

                    return returnValue;
               }
               catch (Exception e) {
                    throw e;
               }
          }
          /**
           * Finds the specified MBean object
           *
           * @param connection - A connection to the MBeanServer.
           * @param mbeanName - The name of the MBean instance.
           * @param mbeanType - The type of the MBean.
           * @param parent - The name of the parent Service. Can be NULL.
            * @return Object - The MBean or null if the MBean was not found.
           */




          public Object findServiceDomain(MBeanServerConnection connection,
               String mbeanName,
               String mbeanType,
               String parent) {
               ServiceDomainMBean serviceDomainbean = null;
               try {
               ObjectName on =
                    new ObjectName(ServiceDomainMBean.OBJECT_NAME);
               serviceDomainbean = (ServiceDomainMBean)
                    MBeanServerInvocationHandler.
                         newProxyInstance(connection, on);
               }
               catch (MalformedObjectNameException e) {
                    e.printStackTrace();
                    return null;
               }
               return serviceDomainbean;
          }
     }
     /**
      * Timer task to keep retrieving and resetting service statistics.
      */
     static class GetAndResetStatisticsTask extends TimerTask {
          private ServiceStatisticsRetriever collector;

          public GetAndResetStatisticsTask(ServiceStatisticsRetriever col
               ){collector = col;
          }

          public void run() {
                  System.out.println("\n**********************************");
                System.out.println("Retrieving statistics for all monitored
                    " + "business services.");





               try {
                         collector.getAndResetStatsForAllMonitoredBizServices();
                   System.out.println("Successfully retrieved and reset
                         statistics for " +
                         "all monitored \n business services at " +
                         new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").
                                format(new Date(System.currentTimeMillis())));
               } catch (Exception e) {
                    System.out.println("Failed to retrieve and reset
                         statistics for all " + "monitored business
                         service...");
                    e.printStackTrace();
               }
               System.out.println("**********************************\n");

               System.out.println("\n**********************************");
               System.out.println("Retrieving statistics for all
                    monitored proxy services.");
               try {
                    collector.getAndResetStatsForAllMonitoredProxy
                         Services();
                    System.out.println("Successfully retrieved and reset
                         statistics " +
                         "for all monitored \nproxy services at " +
                         new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").
                                format(new Date(System.currentTimeMillis())));
               } catch (Exception e) {
                    System.out.println("Failed to retrieve and reset
                         statistics " + "for all monitored proxy service
                              ...");
                    e.printStackTrace();
               }
               System.out.println("*********************************\n");
          }
     }



     /**
        * The main method to start the timer task to extract, save, and reset
       * statistics for all monitored business and proxy services. It uses
       * the following system properties.
       * 1. hostname - Hostname of admin server
       * 2. port - Listening port of admin server
       * 3. username - Login username
       * 4. password - Login password
       * 5. period - Frequency in hours. This will be used by the timer
       * to determine the time gap between two executions.
       *
       * @param args Not used.
       */
     public static void main(String[] args) {
          try {
               Properties p = System.getProperties();

               HashMap map = new HashMap();

               map.put("HOSTNAME", p.getProperty("hostname","localhost"));
               map.put("PORT", p.getProperty("port", "7001"));
               map.put("USERNAME", p.getProperty("username", "weblogic"));
               map.put("PASSWORD", p.getProperty("password", "weblogic"));
               //set a server name if you want to get the uri status
                    statistics
                    in a cluster
               map.put("SERVER_NAME", p.getProperty("server_name","AdminServer"));
               
               ServiceStatisticsRetriever collector =
                    new ServiceStatisticsRetriever();
               String periodStr = p.getProperty("period", "1");
               int periodInHour = Integer.parseInt(periodStr);
               long periodInMilliSec = periodInHour * 60 * 60 * 1000;
 




               collector.init(map);

               // Start timer.
               Timer timer = new Timer();
               timer.scheduleAtFixedRate(
                    new GetAndResetStatisticsTask(collector),
                    0, periodInMilliSec);
          }
          catch (Exception e) {
               e.printStackTrace();
          }
     }
}