2012年8月31日

[Cloud] Cloud Infrastructure has a new standard

原文はこちら。
https://blogs.oracle.com/mmm/entry/cloud_infrastructure_has_a_new

クラウド管理標準を作成する使命を負うDMTF(Distributed Management Task Force, Inc.)ワークグループで2年以上作業をしてきました。その作業が本日のDMTFによるCloud Infrastructure Management Interface (CIMI) version 1.0のリリースで結実しました。
Cloud Infrastructure Management Interface 5 (CIMI) Model and RESTful HTTP-based Protocol 6
An Interface for Managing Cloud Infrastructure
http://dmtf.org/sites/default/files/standards/documents/DSP0263_1.0.0.pdf
CIMIはクラウド利用者が複数のクラウドのクラウドインフラを管理するために利用できる単一のインターフェースです。CIMIをクラウドベンダーが採用していると、クライアントコードをこうした複数のベンダーからのプロプライエタリなインターフェースに合わせる必要はなくなります。

通常あるベンダーがインターフェースの変更権を持っていて、その他の面々はリバースエンジニアリングの上で内部の仕組みを知る必要があるデファクトスタンダードとは異なり、CIMIはデジュールスタンダード(標準化団体が変更を管理する)です。標準策定に2年かかった理由の一つは、ユースケース、要件、および複数のベンダーから寄贈されたAPIを考慮に入れていたからです。これらのベンダーは現在リリースしている製品を持っているため、結果としてCIMIは現実世界の経験で強力な基盤を持っています。

What does CIMI allow?

CIMIは、クラウド内のリソースのためのモデル(コンピューティング、ストレージ、ネットワーキング)ならびにHTTPバインディングのRESTfulプロトコルの両方です。これは、例えばマシン(ゲストVM)を作成するために、クライアントは、マシン·リソースを表すドキュメントを作成し、HTTPを使用してサーバに送信することを意味します。CIMIを使うとリソースをJavaScript Object Notation(JSON)またはeXentsible Markup Language(XML)でエンコードできます。

CIMIは、市場で提供している既存のクラウドインフラにマッピング可能なリソースのモデルを提供します。CIMIには、全てのクラウドでサポートされているわけではないいくつかの機能がありますが、CIMIはどの機能が実装されているかの探索をもサポートしています。これが意味するのは、複数のクラウド間で動作し、それぞれのクラウドの機能を完全に活用することができるクライアントを持つことができる、ということです。

Isn’t it too early for a standard?

この標準の主要機能は、インターフェース自体のコアフレームワーク内で生じる互換性のある拡張機能を考慮に入れていることです。CIMIの機能である(メタデータを介した)探索を使って、ベンダー固有の可能性がある追加機能を実装したことをクライアントに伝達します。複数のベンダーがこのような機能を実装すると、これらの機能がCIMIの将来のバージョンに追加される可能性があります。

したがって、仕様の最小公分母の種類で減速されることなく、クラウド空間でイノベーションが継続できます。CIMIがすでにインフラのクラウドを実装している利害関係者数十人でオープンに開発されて以来、私は、来る1年あるいは2年にわたって、これらの同じ会社やその他の会社にCIMIが採用されることを期待しています。この規格の利点がわかるクラウド利用者は、ロードマップにCIMIの実装を示すために、クラウド·ベンダーにベンダーのCIMI実装の予定を尋ねはじめるべきでしょう。

CIMIやDMTFのクラウドに関する他の成果は、以下のリンクからどうぞ。
Cloud Management Initiative
http://dmtf.org/cloud
http://www.dmtf.org/jp/technology/cloud(日本語)

[Java] Oracle releases Java SE 7 Update 7, and Java SE 6 Update 35

原文はこちら。
https://blogs.oracle.com/henrik/entry/oracle_releases_java_se_7

今朝OracleはJDK 6とJDK 7のアップデートをリリースしました。このリリースに関する詳細は、以下のリンクをどうぞ。
Oracleとしては、みなさまがこれらのアップデートを速やかに適用されることを推奨します。Oracle JRE 6とJRE 7 for Windows (32-bit)、 Mac OSX (64-bit)用の最近のリリースのJRE 7をお使いのお客様であれば、自動でアップデートされます。詳細はこちらのエントリをどうぞ。
Security Alert for CVE-2012-4681 Released
https://blogs.oracle.com/security/entry/security_alert_for_cve_20121

2012年8月30日

[Java] GlassFish Server 3.1.2.2 Maven Coordinates

原文はこちら。
https://blogs.oracle.com/theaquarium/entry/glassfish_server_3_1_21

GlassFish Server 3.1.2.2が数週間前にリリースされました。
GlassFish Server 3.1.2.2 Now Available
https://blogs.oracle.com/theaquarium/entry/glassfish_server_3_1_2
このリリースではいくつかの重要なバグ修正がなされています。一つはJAX-WS (JAX-WS-1059) に関するもの、もう一つはJK listenerとApache、mod_ajp_proxyに関するものです(GLASSFISH-18446)。このリリースは既にNetBeans 7.2に統合されていますし、個別にも以下のリンクからダウンロードできます。
NetBeans IDE 7.2 ダウンロード
http://netbeans.org/downloads/index.html
GlassFish Server Open Source Edition - 3.1.2.2
http://glassfish.java.net/downloads/3.1.2.2-final.html
このビルドのMaven coordinatesの説明がダウンロードページに記載されています。pom.xmlの以下のスニペットを使うと、embedded-glassfish:runやembedded-glassfish:deployなどのコマンドを実行できます。

    org.glassfish.embedded
    maven-embedded-glassfish-plugin
    3.1.2.2

GlassFish Embedded Serverガイドではセットアップ等の詳細な説明があります。
Oracle GlassFish Server Embedded Server Guide Release 3.1.2 http://docs.oracle.com/cd/E26576_01/doc.312/e24932/toc.htm
同様に、GlassFishのフルプラットフォーム、Web Profile実装を一つのJarファイルとして含んでいます。

    org.glassfish.main.extras
    glassfish-embedded-web
    3.1.2.2

当然ながら、フルプラットフォームが必要な場合、"glassfish-embedded-web"を"glassfish-embedded-all"に変更する必要があります。
ダウンロードページでは様々なバンドルや完全なmaven coordinatesの詳細が記載されています。シンプルなzipバンドルを使ってはじめることもできます。

2012年8月29日

[Java] jrunscript as a cross platform scripting environment

原文はこちら。
https://blogs.oracle.com/nishigaya/entry/jrunscript_as_a_cross_platform

「Windows、UNIX系OSでできるだけ共通したスクリプトを作るための一案として、jrunscriptを使うのはどうよ」というエントリです。
詳細は日本語の原文をどうぞ。

2012年8月28日

[GoldenGate] It was worth the wait… Welcome Oracle GoldenGate 11g Release 2

原文はこちら。
https://blogs.oracle.com/dataintegration/entry/it_was_worth_the_wait

複数の分野にて新しい機能がたくさんいっぱい詰まっていますので、確かに、Oracle GoldenGate 11gR2の登場を待った甲斐がありました。実際、このリリースでは、これまでのOracle GoldenGateの歴史の中で、新機能のリストが最長になっており、かつ最強の新機能が詰まっています。この新リリースでは、グローバルな実装および異種システムのサポートを拡大しつつも、GoldenGateとOracle Databaseがより緊密になっており、より安全、より柔軟かつより高速な伝送が可能になっています。
プレスリリースでOracle GoldenGate 11gR2のリリースを発表しました。まだご覧でないなら是非チェックして下さい。この発表で言及しているように、様々な改善が製品に対して施されています。
Oracle GoldenGate
http://www.oracle.com/us/products/middleware/data-integration/goldengate/overview/index.html (英語)
http://www.oracle.com/jp/products/middleware/data-integration/goldengate/overview/index.html (日本語)
Oracle Database
http://www.oracle.com/us/products/database/overview/index.html (英語)
http://www.oracle.com/jp/products/database/overview/index.html (日本語)
Oracle GoldenGate 11g Release 2 Now Available
http://www.oracle.com/us/corporate/press/1834528
  • Oracle Database向けの統合されたキャプチャにより、Oracle GoldenGateのキャプチャプロセスがよりOracle Databaseエンジンと緊密になり、様々なメリットの中でも、特にAdvanced Compressionをサポートするようになりました。
  • 競合検出および競合解決の機能が改善されました。この結果、 Active-Active構成での 競合検出や競合解決プロセスが高速かつシンプルになります。
  • グローバル対応: Oracle GoldenGateをマルチバイト/Unicodeキャラクタセットを使うデータベース向けに展開できます。
  • セキュリティや性能が改善されました。これにはFederal Information Protection Standard (FIPS)のサポートを含みます。
  • 拡張性が増大しました。トランザクションログやTrailファイルのイベントレコードを元にしてアクションを開始することができます。
  • Oracle GoldenGate Monitorに加えてOracle Enterprise Manager 12cと統合しています。
    Oracle Enterprise Manager 12c
    http://www.oracle.com/us/products/enterprise-manager/index.html (英語)
    http://www.oracle.com/jp/products/enterprise-manager/index.html (日本語)
  • IBM DB2 for i on iSeries (AS/400) からのキャプチャとPostgresへの配信を含む、サポート対象の異種データベースが拡大しています。
来るローンチWebcastでこれらの新機能について詳しくご紹介します。
Harness the Power of the New Release of Oracle GoldenGate 11g
開始日時
9月12日 PDT 午前8時もしくは10時から
9月13日 JST 午前0時もしくは2時から

これらの新機能についての詳細を知っていただけるだけでなく、ウェブキャストでは、ライブのQ&Aセクションで製品管理部門質問していただけます。そんなわけで、Oracle GoldenGate 11gの新リリースを知っていただき、エンタープライズクラスのリアルタイムデータ統合ソリューションを知ってもらう、この機会を逃して欲しくありません。

GoldenGateの新機能を発表するWebcastを楽しみにしています。

[Java, Solaris] How to Trace a Java Application Running on Oracle Solaris

原文はこちら。
http://www.oracle.com/technetwork/articles/servers-storage-dev/java-tracing-1612018.html

著者(Amit Hurvitz)について
Amit HurvitzはOracleのハードウェアエンジニアリング(旧Sun Microsystems)のISV Engineeringチームで10年働いてきました。その前は、Cコンパイラ最適化に取り組み、C++/Java EEの開発者でもありました。

Oracle SolarisのDTraceは、Oracle Solaris 10以後(もしくはDTraceを採用している別のOS)が動作しているコンピュータで起こっていることのほとんど全てを見るという機能があることで知られています。JavaアプリケーションをDTraceでトレースできますが、Javaコードをトレースする上で制限や制約がありました。

Java用の優れたトレースツールがたくさんあります。例えば、JDKに含まれるjvisualvmは、非常に便利であり、豊富な機能を提供しています。それでも、これらのツールのほとんどは、DTraceフレームワークの比類無きダイナミズム、埋め込まない構成といった広範な機能の組み合わせをとることができません。

Java Statically Defined Tracing (JSDT)という、C/C++コード用のUser-level Statically Defined Tracing (USDT) のようなツールを使うと、プログラマーが静的にプローブをコードに追加することができます。これらのプローブはアクティベートされていない状態では何らアプリケーションの性能に影響しませんが、アクティベートされても性能への影響を最小限にするように設計されています。これは幅広いDTraceの観測スコープや最適な集約機能の門戸を開くものです。

他にも潜在的な問題があり、こうしたプローブをコード(JSDTの場合はJavaのコード)に追加しなければなりません。しかしJavaにはネイティブ言語にはない新たな機能があります。例えば、プログラムのクラスを実行中に再定義できますし、Java SE 6からはAttach APIを使って任意の実行中のJava SE 6以後のJVMにアタッチでき、そのJVM内でエージェントを動的に初期化、実行することができます。これらを組み合わせると、理論的にはJavaコードでJSDTプローブが動的にトレースを採取できることになります。これがこの記事のトピックです。

What We Want to Do
図1は、アイデアを説明するための例です。この例は、アプリケーションを停止したりコードを変更したり、アプリケーションの再コンパイルをしたりせずに挙動を調べたい、というものです。
Figure 1: Exploring the Behavior of a Java Application
図1 Javaアプリケーションの挙動を調べる例

Current Requirements, Limitations, and Caveats
JSDTはJava HotSpot VM 1.7をサポートしています。最初のプロバイダの作成に失敗しないよう、JDK 1.7.0_04を使いましょう(訳注:最新版を使いましょう)。このエントリで説明した手順はOracle Solaris 11でテストしており、全て正常に動作していますが、DTraceをサポートしている他のOSでは確認していませんし、他のJVMでも確認していません。
BTraceクライアントのターゲットアプリケーションへの接続の初期化が時々失敗しますので、接続に失敗する場合は何度か試してみて下さい。
BTraceは現在のところトレース採取用のクラスをクリーン("de-instrument")にはしません。単にプローブを不活化するだけです。この挙動のため、同一プローブや同一クラスの繰り返しのトレース採取はできません。クリーニング機能が実行されるといいのですが。

JSDT Basics
JSDTプローブの定義は難しくありませんが、簡単な初期化が必要です。まず、各プロバイダのJavaインターフェース(extends com.sun.tracing.Provider)を定義します。インターフェースのメソッドはDTraceのプローブ名にも対応しています(コード1)。

コード1. Javaインターフェースの定義
public interface MyProvider extends com.sun.tracing.Provider {
  void startProbe();
  void workProbe(int intData, String stringData);
  void endProbe();
  }
  
// Use a static factory to create a provider
import com.sun.tracing.ProviderFactory;

public static MyProvider provider;

  ProviderFactory factory = ProviderFactory.getDefaultFactory();
  
  provider = factory.createProvider(MyProvider.class);
  
  // Call the provider methods from inside your code to trigger
  // the corresponding DTrace probes.
  Provider.startProbe();
  ...
  Provider.workProbe(i, str);
   ...
  Provider.endProbe();

How to Dynamically Instrument JSDT Probes
ソースコードにプローブを追加することで、プローブを静的に定義できることがわかりました。では、ソースコードを変更せずに同じことをやってみましょう。To use the Attach APIとJavaコードのトレース採取機能を使うために、素晴らしいBTraceパッケージを利用することができます。このパッケージは、JavaアプリケーションをトレースしながらDTraceの標準に従う動的なトレース採取機能を豊富に提供しています。BTrace自体に価値があるのですが、ここでは実行中のアプリケーションのトレースを採取するためのJSDTと共に使うだけにします。

BTrace Basics
BTraceは、効率的なASMバイトコードフレームワークで構築されたツールです。 BTraceは特別なJavaアノテーションを使用して、実行中のJavaアプリケーションのクラスを動的にトレース採取することができます。アノテーションは、対象アプリケーションのどこにトレースするコードを挿入するかを指示するものとして機能します。例えば…
@OnMethod(clazz="java.lang.Thread",method="start",location=@Location(Kind.Return))
BTraceは、(Attach APIを通じて)対象のJVMでエージェントを作成し、起動します。そして必要であればトレース採取を実行し、出力トレースデータを取得するためにそのエージェントと通信するクライアントを使用します。
そのデフォルトの"safe"モードでは、BTraceは挿入したコードを制限して、対象のJVMへの潜在的な望ましくない副作用を回避しようとしています。主要な制約の1つはBTraceライブラリのメソッド以外は呼び出せない、というものです(BTraceはそのutilsパッケージ内にたくさんのメソッドを提供しています)。今回のケースでは、"unsafe"モードを使用するので、DTraceプロバイダクラスのメソッドを定義し、呼び出すことができます。
コード2はBTraceスクリプトの"Hello World"のようなもので、 Thread.start() メソッドエントリのトレースを採取し、メッセージを出力します。このスクリプトはBTrace以外のメソッドを呼ばないので、セーフモードでコンパイルできます。しかし、クラスメソッドを提供するためにJSDTを呼び出す場合はアンセーフモードを使わなければなりません。

コード2. BTraceスクリプトのサンプル
// import all BTrace annotations
import com.sun.btrace.annotations.*;
// import statics from BTraceUtils class
import static com.sun.btrace.BTraceUtils.*;

// @BTrace annotation indicates that this is a BTrace program
@BTrace
class HelloWorld {
// @OnMethod annotation indicates where to probe.
// In this example, we are interested in the entry
// into the Thread.start() method.
  @OnMethod(
    clazz="java.lang.Thread",
    method="start"
  )
  void func() {
    sharedMethod(msg);
  }
  void sharedMethod(String msg) {
    // println is defined in BTraceUtils
    println(msg);
  }
}
BTrace環境が適切であれば、任意のJavaプロセスを監視するBTraceスクリプトを実行できます。
$ btrace <target-java-pid> HelloWorld.java
BTraceに関する詳細情報は、BTraceプロジェクト、特にBTrace User's Guideをご覧下さい。
BTrace — Project Kenai
http://kenai.com/projects/btrace
BTrace User's Guide
http://kenai.com/projects/btrace/pages/UserGuide
DTraceプロバイダクラスはBTraceスクリプトのコンパイルと対象のアプリケーションランタイムの両方に必要です。プロバイダは、プロバイダメソッドの最初の呼び出し前に初期化する必要がありますが、クラスのトレース採取の間にプロバイダを初期化するのが一番よいでしょう。静的な初期化が可能です。我々が定義するBTraceクラスに含まれる静的初期化は正常に動作しませんが、静的な初期化機能をもつファクトリクラスをインポートすると、少なくとも遅延して初期化されます。静的に初期化するプロバイダ·ファクトリ·クラスはコード3のような感じです。

コード3. 静的初期化するプロバイダファクトリクラス
import com.sun.tracing.*;

public class MyProviderFactory {

  private static ProviderFactory factory;
  public static MyProvider provider;
  
  static {
    factory = ProviderFactory.getDefaultFactory();
    provider = factory.createProvider(MyProvider.class);
  }
  public static void probeName1();
  public static void probeName2(String s, int i);
}
この静的コードは、少なくとも最初のプローブメソッドの直前に遅延初期化されます。

Triggering the Probes from a BTrace Script
JSDTプローブをBTraceコード(BTrace 1.2で)から起動するためには、以下のような設定・調整が必要です。
  1. Change to BTrace unsafe mode by editing the <Btrace-install-dir>/bin/btrace スクリプトを  -Dcom.sun.btrace.unsafe=false から -Dcom.sun.btrace.unsafe=true に編集して、BTrace unsafeモードを変更します。
  2. <Btrace-install-dir>/bin/btrace のJava VM起動コマンドの -cp チェーンに プロバイダのJARファイルを追加して、 BTraceのコンパイルクラスパスにプロバイダを追加します。BTraceスクリプト内で他のクラス(参照したいターゲットアプリケーションのクラスなど)を使用している場合は、そのクラスも追加しておきましょう。
  3. トレース対象のJavaアプリケーションはブートクラスローダでプロバイダをロードしますので、プロバイダがブートクラスローダから到達可能である必要があります。ブートクラスローダに何か特別なことをしていなければ、ブートクラスパスに追加するために以下のオプションがあります。
    • ターゲット·アプリケーションにフラグを追加する必要がない最も簡単な方法は、プロバイダクラスをJREの下のclassesディレクトリ(jre/classes)に追加することです(例: /home/ahurvitz/java/jdk1.7.0_04/jre/classes)。classesディレクトリが存在しない場合は作成します。ターゲット·アプリケーションのクラスパスがこのディレクトリをデフォルトでブートクラスパスに含んでいることを確認するためには、次のようにJDKのjinfoコマンドを以下のように実行します。
      $ jinfo -sysprops <target-java-pid> | grep "sun.boot.class.path"
      
    • 他の方法では、Javaオプション(フラグ)をトレース対象のアプリケーションに追加する必要がありますので、ちょっと面倒です。この方法で実施する場合、 -Dsun.boot.class.path=<current-boot-class-path>:<providers-jar> フラグを対象アプリケーションに追加します。sun.boot.class.path プロパティの値で <current-boot-class-path> を置き換えます。以下のコマンドを実行するとプロパティ値を抽出することができます。
      $ jinfo -sysprops <target-java-pid> | grep "sun.boot.class.path" 
      
Downloading What's Needed, Installing, and Running: A Step-by-Step Example
以下の例では、非常に簡単なJavaプログラム(コード4)をトレース対象のアプリケーションとして利用します。makeOneIteration()メソッドの全ての入出力のためのDTraceプローブを起動し、パラメータとしてカウンターオブジェクトを渡そうとしています。

コード4. トレース対象のコード
package tracetarget;

public class TraceTarget {

    private String strProp;
    private int intProp;
    
    public static void main(String[] args) {
        TraceTarget me = new TraceTarget();
        String runTimeId = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
        System.out.println(runTimeId);
        me.work();
    }
    
    public TraceTarget() {
        strProp = "I am a tracing target";
        intProp = 17;
    }

    public int getIntProp() {
        return intProp;
    }

    public String getStrProp() {
        return strProp;
    }

    private void makeOneIteration(Counter c) {
        c.count();
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
        }
    }

    public void work() {
        Counter counter = new Counter();
        while (true) {
            makeOneIteration(counter);
        }
    }
}


package tracetarget;

public class Counter {
    private int counter;

    Counter() {
        counter = 0;
    }

    public int getCounter() {
        return counter;
    }

    public void count() {
        counter++;
    }
}
プログラムをコンパイルして実行しましょう。プログラムは自身のプロセスID(pid)を次のステップのために出力してくれます。このpidは <target-java-pid> で、 btraceを実行する際に参照するものです。トレースするプログラムを使って始めてみましょう(まだ何もインストールしていない前提です)。
  1. BTrace version 1.2.1のバイナリファイル(btrace-bin.tar.gz)を以下のリンクからダウンロードします。
    BTrace Downloads
    http://kenai.com/projects/btrace/downloads/directory/releases/current
    このファイルはLinuxとMac OS用ですが、Oracle Solarisでも動作します。
  2. ファイルを解凍、展開します。
    # gunzip < btrace-bin.tar.gz | tar xf -
    
  3. 環境変数JAVA_HOMEが正しくJDK (JDK 7 update 4 or higher)を指すように設定します。JAVA_HOMEはBTraceのバイナリで利用します。
  4. BTraceのbinディレクトリのパスを通します。
  5. DTraceプロバイダを定義し、プロバイダのクラスをコンパイルし、JARファイルにまとめましょう。この例では、MyProviderはプロバイダ名であり、startMethod()finishMethod()はプローブ名です。
    package jsdttest;
    
    import com.sun.tracing.*;
    
    public interface MyProvider extends Provider {
    
      public void startMethod(String methodName);
      public void startMethod(String methodName, String str, int i);
      public void finishMethod(int result);
    }
    
  6. プロバイダファクトリをコード5のように定義します。

    コード5. プロバイダファクトリの定義
    package jsdttest;
    
    import com.sun.tracing.*;
    
    public class MyProviderFactory {
    
      private static ProviderFactory factory;
      public static MyProvider provider;
    
      static {
        factory = ProviderFactory.getDefaultFactory();
        provider = factory.createProvider(MyProvider.class);
      }
      public static void probeName1() {}
      public static void probeName2(String s, int i);
    }
    
  7. プロバイダの初期化を指示したり、必要なプローブを起動するBTraceスクリプトを作成します(以下は例です)。

    コード6. Trace.java
    import com.sun.btrace.annotations.*; 
    // import statics from BTraceUtils class 
    import static com.sun.btrace.BTraceUtils.*;
    import com.sun.tracing.*;
    import com.sun.btrace.AnyType;
    import jsdttest.MyProvider; 
    import jsdttest.DummyProvider; 
    import jsdttest.MyProviderFactory; 
    import tracetarget.TraceTarget;
    import tracetarget.Callee;
    
    // @BTrace annotation indicates that this is a BTrace program
    
    @BTrace class Trace {
    
    // @OnMethod annotation indicates where to probe.
    // In this example, we are interested in entry 
    // into the Thread.start() method. 
    @OnMethod(
        clazz="tracetarget.TraceTarget",
        method="/.*/"
    )
    
        void mEnrty(@Self Object self, @ProbeClassName String probeClass, @ProbeMethodName 
     String probeMethod, AnyType[] args) {
     MyProvider provider = MyProviderFactory.provider;
            provider.startMethod(probeMethod);
            provider.startMethod(probeMethod, ((TraceTarget)self).getStrProp(), ((Callee)args[0]).getCounter());
        }
    
    @OnMethod(
        clazz="tracetarget.TraceTarget",
        method="/.*/",
        location=@Location(Kind.RETURN)
    )
        void mReturn(@ProbeClassName String probeClass, @ProbeMethodName String probeMethod) {
     MyProvider provider = MyProviderFactory.provider;
            provider.finishMethod(19);
        }
    }
    
  8. Configure BTrace by editing <Btrace-install-dir>/bin/btraceファイルを編集して以下のようにBTraceを設定します(編集前にバックアップを取っておくことをお勧めします)。
    1. unsafe modeをfalseからtrueに変更します。
      ${JAVA_HOME}/bin/java ... -Dcom.sun.btrace.unsafe=true ...
      
    2. プロバイダJARファイルやBTraceスクリプトで利用している他のクラスファイルを追加します。例えば、参照しているオブジェクトをブートクラスパスに配置します。以下の例では、BTraceスクリプトでオブジェクトを参照しているためTraceTargetクラスも追加しています。
      ${JAVA_HOME}/bin/java ... -cp ${BTRACE_HOME}/build/btrace-client.jar:${TOOLS_JAR}:/usr/share/lib/java/dtrace.jar:
      /home/ahurvitz/NetBeansProjects/jsdtTest/dist/jsdtTest.jar:/home/ahurvitz/NetBeansProjects/TraceTarget/dist/TraceTarget.jar ...
      
  9. BTraceを実行してターゲットアプリケーションのトレースを取ります。

    $ btrace <target-java-pid> Trace.java
    
  10. Check the DTrace probes using dtrace -l | grep <provider-name>, for example:

    $ dtrace -l | grep MyProvider
    
  11. コード7のように全てのテストを実施するためのちょっとしたDTraceスクリプトを書き、スクリプトを呼び出します。

    コード7. テストスクリプト(my_provider.d)
    #!/usr/sbin/dtrace -Cs
    
    BEGIN
    {
        start_timestamp = timestamp;
    }
    
    MyProvider$target:::startMethod
    {
        @starts[pid] = count();
        printf("started method, arg0 = %s\n", copyinstr(arg0));
        printf("arg1 = %s\n", arg1 ? copyinstr(arg1) : "null");
        printf("arg2 = %d\n", arg2);
    }
    
    MyProvider$target:::finishMethod
    {
        @ends[pid] = count();
        printf("finished method, arg0: %d\n", arg0);
    }
    
    tick-5sec
    {
        printf("stats:\n******\n");
        printa(@starts);
        printa(@ends);
    }
    
  12. DTraceテストスクリプトを実行します。
    # dtrace my_provider.d -p <target-java-pid>
    
まとめ
DTrace、JSDT、BTraceを使うと、DTraceのプローブを使ってJavaアプリケーションを簡単かつ動的にトレースを採取できます。このプローブはOracle Solaris 10以後で動作するJavaアプリケーションのアドホックな探査のための多くの可能性を切り開きます。

参考

2012年8月27日

[Java] Project Jigsaw: Late for the train: The Q&A

原文はこちら。
http://mreinhold.org/blog/late-for-the-train-qa

最近、一般のJavaコミュニティと、特にJava SE 8(JSR337)専門家グループに対し、Java 8からJava 9へProject Jigsawを延期することを提案しました。と同時に、通常の2年間のリリースサイクルを今後のために明示的に目指すことを提案しました。
以下はこうした提案に対する主要な質問とその回答をまとめたものです。
Project Jigsaw: Late for the train
http://mreinhold.org/blog/late-for-the-train
Java SE 8 Platform Umbrella JSR (337)
http://openjdk.java.net/projects/jdk8/spec/
Modularity in Java SE 8
mail.openjdk.java.net/pipermail/java-se-8-spec-observers/2012-July/000001.html
Project Jigsaw
http://openjdk.java.net/projects/jigsaw/
Making the decision
質問回答
Java Se 8専門家グループ(EG)はモジュールシステムの追加とプラットフォームのモジュール化をJava SE 9に引き延ばすか否かを決定したのですか?いいえ、まだ決定していません。
いつまでにEGにこの決定をしてもらいたいですか?来月中ぐらいには。
自分の提案がどのように反映されているか確認するにはどうすればいいでしょう?EGは、幅広くコミュニティから、関連するすべての入力を検討します。著名なブログやコラム、他の通信チャネルをお持ちなら、すでにあなたの意見を見ている可能性があります。そうでない場合は、EGの公式フィードバックチャネルであるJava SE8コメントリストに投稿してください。
受けとったフィードバックの全体的なトーンはどのようなものですか?フィードバックは、Java 8をJigsawのために遅らせるべきという意見と、JigsawをJava 9に延期すべきという意見、その他の意見と、およそ均等に分かれていました。通常はあまり現実的でない選択肢が取られるのですが。

Project Jigsaw
質問回答
Project Jigsawに時間がかかっている理由は?Project Jigsawは、2008年8月にSunで始まりました。Sunの最後の年は、多くの場合と同様でスタッフが不足していました。Jigsawは当初一握りのほとんど非常勤エンジニアばかりで自転車操業していたので進歩は遅かったのです。SunがOracleに統合される間、Jigsawの全ての作業はしばらく中断しましたが、代替策の徹底した検討の後にプロジェクトは再開されました。Project Jigsawは約一年前に本当に十分なスタッフが配属されました。Java 7が出荷された頃です。我々は、それ以来、チームに数人のエンジニアを追加しましたが、初期の頃の不十分な人員リソースと移行中に失われた時間を補うことができないでいます。
では、本当に人員の制限や企業統合のごたごたの問題なのでしょうか。こうした難題はさておき、プロジェクトの遅延に関する他の主要な要因は、JDKのモジュール化に関する純粋に技術的な問題です。
JDKのモジュール化がそんなに大変なのはなぜですか?大きな理由が2個あります。まず、JDKのコードベースが、APIと実装の両方のレベルで深く相互接続されているためです。それは主としてモノリシックなソフトウェアシステムのスタイルで長年にわたって構築されたためです。できるだけ多くのAPIや実装の依存性を排除したり、少なくともシンプルにして、プラットフォームおよびその実装の両方を相互に依存したモジュールの集約として提示できるように、膨大な労力を費やしてきましたが、特に厄介なケースが残っています。
2番目の理由は?既存のクラスパスベースのアプリケーションだけでなく、実現可能な範囲内で、モジュールで構成されたアプリケーションのために、可能な限り、以前のリリースとの互換性を維持したいと考えているためです。
JDKのモジュール化は必要なのでしょうか。大きなモジュールにまとめてしまえないんですかね?JDKのモジュール化、より具体的にはJava SEプラットフォームのモジュール化により、標準の柔軟なJavaランタイム構成を大規模なサーバーから小型の組込み機器へスケールダウンできるようになります。長期的にはハイエンドのJava MEプラットフォームとJava SEの収束が可能になるでしょう。
Project Jigsawとは単にJDKをモジュール化するだけなのですか?元々の認識では、Project Jigsawは確かに主としてJDKのモジュール化に注力していましたが、プラットフォーム自体のためだけでなく、その上に構築されたライブラリやアプリケーションに対しても使えるということで、Javaプラットフォームのための真の標準モジュールシステムに対する需要が高まった結果、後でスコープが拡大することになりました。
開発者がProject Jigsawに注目すべき理由は?モジュール化されたJavaプラットフォームの導入により、長期的には、Javaの実装やライブラリ、フレームワーク、ツール、アプリケーションの設計、ビルド、デプロイ方式が根本的に変わるでしょう。
これまでのProject Jigsawの進捗は?着実に進んでいます。モジュールシステムのコア機能の多くのプロトタイプを作成し、コンパイル時と実行時の両方で動作しています。モジュール宣言を使用してJavaプログラミング言語を拡張し、モジュラーソースツリーとそれに対応するコンパイルされたクラスツリーの構造を編み出して、これらの機能をjavacに実装しました。
効率的なモジュール・ファイル・フォーマットを定義し、モジュラーJREを起動するようJVMを拡張し、予備的なAPIを設計、実装してきました。モジュールシステムを使ってJDKとJava SE APIを意味のあるモジュールの集合体に分割する上での最初の切り込みを入れました。特に現在、ためにjava.util.ServiceLoader APIを改造して、モジュラーサービスをサポートするようにしています。
お手伝いしたいんですが、どうすればいいですか?プロジェクトのページで、要件のドラフト設計概要の文書をお読み下さい。最新のプロトタイプビルドをダウンロード実行して下さい。あなたの考えを教えて下さい。jigsaw-devのメーリングリストで、リアルタイムに現在の残りの作業を追うことができます。

The Java Platform Module System JSR
質問回答
Project Jigsawと最終的なJavaプラットフォームモジュールシステムのJSRとの関係は?ハイレベルで見ると、Project Jigsawには2フェーズあります。第1フェーズではこれまでのJavaのモジュール方式のソリューションとは著しく異なるモジュール方式を模索しています。 我々は、Javaプログラミング言語、仮想マシン、およびAPIの変更が可能と仮定しました。そうすることで、コンパイルから、デプロイ、実行まで、すべてのプログラムの段階でモジュールの境界を強く強制できる設計が可能になります。これは、順番に、使い勝手、診断のしやすさ、セキュリティ、およびパフォーマンスの向上につながります。第1フェーズの究極の目標は、モジュールシステムJSR EGの成果を知らせることができるプロトタイプを生成することです。
Project Jigsawの第2フェーズではどうなるの?第二フェーズでは、モジュールシステムJSR EGが作成する仕様の参照実装を作成する予定です。 EGは、現在模索しているものとは全く異なるアプローチを最終的に選択する場合があります。その場合、Project Jigsawは必要に応じて筋道が変わる可能性がありますが、いずれにせよ最終的な結果はいいものになるでしょう。

Maven & OSGi
質問回答
なぜMavenを使わないの?Mavenはプロジェクト管理ソフトウェアで包括的なツールです。ビルド時のモジュールシステムであって、実行時のモジュールをサポートしないからです。
なぜOSGiを採用しないの?OSGiは、リッチな動的コンポーネントシステムで、モジュール化されたシステムだけでなく、ライフサイクルモデルと動的なサービスレジストリを含んでいます。後者の二つのファシリティは、ある種の高度なアプリケーションにとって有用ですが、これらがJava SEプラットフォームの標準化にそれほど関心がないように思われるからです。
じゃあ、なぜOSGiのモジュールレイヤを採用しないの?OSGiのモジュール層は、コンパイル時には動作せず、パッケージング、デプロイ、実行時のモジュール化にのみ対応しています。さらに、現状では、ライブラリとアプリケーション·モジュールには有用ですが、厳密にはJava SEプラットフォームの上に構築されているので、プラットフォーム自体をモジュール化するために使用できません。
If Mavenがビルド時にモジュールに対応し、OSGiモジュール層がデプロイ、実行時にモジュールに対応するのであれば、なぜ両者を組み合わせて利用しないの?多くの開発者が既にやっているでしょ。MavenとOSGiの組み合わせは、現時点では確かに非常に便利です。しかし、これらのシステムは、既存のJavaプラットフォーム上に構築されています。つまりプラットフォーム自体を変更できなかったのです。これは、とりわけモジュールの境界が弱いことを意味しており、それゆえ構成エラーの診断が難しく、信頼できないコードを安全に実行できなくなっています。対照的に、プロトタイプのJigsawモジュールシステムは、プラットフォームレベルのソリューションを定義することを目的としており、言語とJVMの両方を拡張して、全てのプログラムフェーズで均一にモジュールの境界を強固にしようとしています。
EGが現在のJigsawのプロトタイプのようなアプローチを選択した場合、MavenとOSGiは廃止されるの?そんなことはありません。どんアプローチを採用したとしても、広範囲に採用されるためには、標準のJavaプラットフォームモジュールシステムがMavenとうまく連係することが不可欠です。OSGiの洗練された機能に依存するアプリケーションは今後もOSGiを使い続けることは確実で、それゆえOSGiの実装がJavaモジュールシステム上で動作できること、もし適切に修正された場合にはJavaモジュールに依存するOSGiバンドルをサポートできることが重要です。これを実現するためのアイデアを現在Project Penroseで検討しています。

Java 8 & Java 9
質問回答
Jigsawがないと、Java 8はつまらないリリースになるんじゃないの?いいえ、とんでもない!待望のProject Lambda(JSR 335)、新しいDate/Time API(JSR 310)Type Annotation(JSR 308)、その他現在進行中の小さな機能を含めることなどが計画されています。
JigsawをJava 9に延期したら、Java SEとハイエンドのJava MEプラットフォームの収束が結果として遅れないの?確かに収束が遅くなるでしょうが、止まることはないでしょう。その収束に向けて進展がJava 8でなされるために、SEプラットフォームのコンパクトな構成を構築、デプロイできる少数のProfileを指定することを検討すべきとJava SE 8 EGに提案しました。
JigsawをJava 9に延期した場合、現在Jigsawに携わっているOracleのエンジニアは、他のJava8の機能に再割り当てされ、Java 8が出荷された後に再びJigsawの作業に戻ることになるのでしょうか。いいえ、現在携わっているエンジニアはJava 9の出荷までJigsawをメインに担当します。
LambdaをやめてJigsawを完成させなかったのはなぜ?現在Lambdaに携わるエンジニアが即座Jigsawに切り替わりすぐに開発の力になる可能性があったとしても(もちろんそんなことはないのですが)、Java 8の主要機能の開発に残された時間は9ヶ月もありません。こうしたJavaプラットフォームへの根本的な変更が必要な広範なレビューやテスト、フィードバックのための時間はありません。
なぜJava 8でモジュールシステムを出荷しないのでしょう。そして、Java 9でプラットフォームのモジュール化がなされるのでしょうか。あるリリースでモジュールシステムを提供しても、あるリリースまでそのモジュールシステムを使ってJDKをモジュール化しない場合、根本的に勘違いする大きなリスクを冒すことになります。そうなった場合、後のリリースで修正する必要があり、根本的な設計上の問題を修正した結果、ほぼ確実に粗悪な結果につながります。
8.5リリース、つまりJava 8リリース後2年以内にJigsawを出荷するというのはどうでしょう。隔年ではなく、毎年新リリースを出すというのはどうですか?今日、数年前よりもずっと多くの開発者がJDKに携わっていますが、それはOracleの投資が劇的に増加したこと、そして他の企業や個人がOpenJDKコミュニティに参加したことが理由です。しかし、総じて、リリースに必要な余力がないため、およそ2年ごとよりも頻度を多く、JDKのメジャーリリースの長期にわたるサポートを提供することはできません。
2年のリリースサイクルの提案に対するフィードバックは?新機能が早く利用できるよう、より頻繁にリリースすべきというコメントもあれば、ミッションクリティカルなアプリケーションをリリースする企業開発者の大規模チームが快適なペースで移行できるよう、リリースサイクルが遅くしてほしい、という問い合わせもあります。

2012年8月24日

[Java] Java Summer Workshop in Tokyo

原文はこちら。
https://blogs.oracle.com/VDIpier/entry/java_summer_workshop_in_tokyo

今回はオラクル青山センターで開催されたJava Summer Workshop 2012(原文ママ)に参加してきました。

イベントは主に日本語で開催されましたが、Arun GuptaとBert Ertmanのリンクは英語でした。

Arun Gupta
https://blogs.oracle.com/arungupta/
Bert Ertman
http://bertertman.wordpress.com/ 

Arun Guptaがダイナミックなプレゼンテーションで、EJB、JMS、JSF、そして興味深いWebSocketも含めた変更点を例示し、Java EE 7の世界を紹介しました。Java EE 7の詳細情報は以下のリンクからどうぞ。
Java EE Platform Specification
https://javaee-spec.java.net/ 


Bert ErtmanはSpringと、古いSpringからJava EE 6への移行について説明しました。
彼のプレゼンテーションは、スライド内のピンボード上のノート(の画像)を使っていて、非常に魅力的でした。私はもうアプリケーションサーバにのめり込んでいませんが、彼の話を聞き、自分自身がそれほど時代遅れではないことがわかり、すっきりしました。

2012年8月22日

[VirtualBox] VirtualBox 4.2 Release Candidate 1 is available for testing

原文はこちら。
https://blogs.oracle.com/bobn/entry/virtualbox_4_2_release_candidate

VirtualBox 4.2のRelease Candidate 1がテスト目的でご利用頂けます。このリリースはテスト担当者や早期利用者向けで、本番環境やクリティカルなシステムでの利用はおやめ下さい。
バージョン4.2はメジャーアップデートで、以下の新機能を含んでいます。
  • Windows 8のサポートを強化(特に多くの3D関連の修正を含む)
  • VMのグループ化機能
  • Wizardのエキスパートモード
  • ゲストOS実行時に変更可能な設定項目が増加
  • 最大36個のNICをサポート
  • ネットワークI/Oの帯域幅を制限可能に
  • Linux、OS X、Windowsのシステムブート中にVMの起動が可能に
  • ホストからゲストLinuxへのドラッグアンドドロップを新たに実験的にサポート。他のゲストOSのサポートや、ゲストOSからホストOSへのドラッグアンドドロップは現在計画中 (bug #81)
  • Windowsプラットフォームにて、ホストのパラレルポートをパススルー可能に
新機能に加えて、最新のベータリリース以後で修正されている不具合は以下の通りです。
  • Mac OS X hosts
    • アプリケーションやインストーラに署名し、Mountain Lionでの警告を回避
  • VMM
    • Intel CPUがネステッドページングを使用時のコンテキストスイッチのパフォーマンスを改善
    • AMD社製CPU(Bulldozer以後)のFlushByASID機能をサポート
    • VT-x機能を持つ古いCPUで取り扱うUnrealモードの改善 (gPXE, Solaris 7/8/9; bug #9941)
    • 昔のSMPゲスト(例:古い OS/2 リリース)に関連するI/O APIC割り込みルーティングを決めるMPテーブルの修正
    • 最新のVIA CPUをサポート (bug #10005)
  • GUI
    • ネットワークオペレーションマネージャ
    • 現在のVMウィンドウの内容のスクリーンショットを撮ることが可能に
    • VMリストの自動並べ替えが可能に
    • GUIからHeadless VMを起動可能に
    • マネージャウィンドウからリセット、シャットダウン、電源Offが可能に
    • ゲストOSの最大画面解像度に全体的な制限を設けることが可能に
    • 最近使用したISOイメージのリスト上にマウスを移動させるとメディア部分を完全に見せるように
    • 新規マシンの名前に区切り文字が入っている場合に 追加フォルダを作成しないように (bug #6541)
    • 設定ダイアログが開いたままで終了したときにクラッシュしないようにした (bug #9973)
  • Snapshots
    • VM停止時に古いスナップショットをリストアした場合クラッシュしたのを修正 (bug #10491)
  • 設定
    • VMフォルダの名前や設定ファイルをサニタイズ(bug #10549)
    • iSCSIイニシエータを暗号化した状態で保存可能に
  • E1000
    • 802.1q VLAN のサポート
  • ストレージ
    • パススルーモードでのオーディオCDの作成が可能に
    • VDIイメージ使用時、SATAやIDEのTRIM、SCSIのUNMAPで不使用のイメージブロックを廃棄可能に
    • QEDイメージのサポート
    • QCOWのサポート(v1イメージは完全サポート、v2イメージは読み込みのみサポート)。
    • VHDXイメージの読み込みをサポート
  • Solaris
    • X.org Server 1.11および 1.12のサポート
  • Windows hosts
    • VirtualBoxのアップデート後、ホストオンリーアダプタの再作成が不要に。
    • アップデートされたツールチェーン: ソースコードがVisual C++ 2010互換になり、セキュリティ関連のコンパイラオプションが有効になりました。変更や機能強化の全体をご所望の方は以下の変更履歴をどうぞ。
      VirtualBox 4.2 Release Candidate 1 released
      https://forums.virtualbox.org/viewtopic.php?f=15&t=50934

[重要]
このVirtualBox Betaリリースを本番環境で使わないで下さい。VirtualBox製品候補版は早期評価およびテスト目的に利用して下さい。

不具合や問題点があれば、以下のフォーラムへどうぞ。
VirtualBox Beta/Release Candidate Feedback
http://forums.virtualbox.org/viewforum.php?f=15

2012年8月21日

[Hardware] Oracle Hardware Virtual Tour now available on Apple Store

原文はこちら。
https://blogs.oracle.com/emeavadnews/entry/oracle_hardware_virtual_tour_now

Apple StoreからダウンロードしiPhoneやiPadにインストールできるアプリケーションで、Oracleのハードウェアポートフォリオ全体を取り上げています。このアプリケーションは、手早く簡単にOracleのハードウェアの機能を3Dデモとともに紹介してくれます。インストールだけで設定は不要です。iTunesのアプリケーションに是非アクセスして下さい。
Oracle Hardware Virtual Tour
http://itunes.apple.com/gr/app/oracle-hardware-virtual-tour/id535920742 

2012年8月16日

[FMW, Security] .NET interoperability, Kerberos, SPNEGO, Id Propagation - All things Microsoft! - OWSM 11g

原文はこちら。
https://blogs.oracle.com/owsm/entry/net_interoperability_kerberos_spnego_id

最も多く頂く質問の中に、OWSMと.NET/WCFとの相互運用に関するものがあります。まず、公式にOWSMは.NETとの相互運用シナリオを検証しています。これらはOracle Web Services Manager相互運用ガイドに記載があります。
Oracle® Fusion Middleware Interoperability Guide for Oracle Web Services Manager 11g Release 1 (11.1.1.6)
Interoperability with Microsoft WCF/.NET 3.5 Security Environments
http://docs.oracle.com/cd/E23943_01/web.1111/e16098/interop_net.htm#BIIEHFFD
Oracle® Fusion Middleware Oracle Web Services Manager相互運用ガイド 11gリリース1 (11.1.1.6)
Microsoft WCF/.NET 3.5のセキュリティ環境との相互運用性
http://docs.oracle.com/cd/E28389_01/web.1111/b61391/interop_net.htm#BIIEHFFD
相互運用で検証済みの主要なシナリオは、ユーザ名トークン、X.509トークン、 WS-Security Kerberos Token Profileを用いたKerberosトークンです。
次に、頂く質問は、.NET環境とのIDの伝播をどうすればよいか、というものです。

シナリオ1: KerberosとSAML、OSBをアクティブな仲介者として使用して、WCFクライアントとOWSM/Fusion Middleware間のID伝播を実現する

[注意] OSBの代わりに、SOA Suiteを使うことも可能です

シナリオ2: KerberosとSAML、OSBをパッシブな仲介者として使用して、WCFクライアントとOWSM/Fusion Middleware間のID伝播を実現する

[注意] パッシブな仲介モデルではOSB(もしくはOEG)にて実現できます。SOAはパッシブな仲介モデルをサポートしていないため、SOAでは実現できません。

シナリオ3: WCFクライアントとOWSM/Fusion Middleware、アクティブな仲介者としてのOSB間で、KerberosベースのマルチホップのID伝播を実現する

このシナリオでは、Kerberosを使ってマルチホップのID伝播を実現したいというものですが、現時点ではサポートされていません。

シナリオ4: WCFクライアントとWCFサービス、アクティブな仲介者としてのOSB間で、KerberosベースのマルチホップのID伝播を実現する

シナリオ3とシナリオ4の両方で、マルチホップエンドユーザIDの伝播のためにKerberosをつかうためには、ユーザTGT(Ticket Granting Ticket)もしくはS4U(Service-for-User)拡張のどちらかのサポートが必要です。これらのいずれも、現時点ではOWSMでサポートしていません。

シナリオ5: SAMLを使ってEnd to EndのID伝播を実現する

OSBやSOA Suiteを使ってエンドユーザIDの伝播を実現する別の方法として、SAMLがあります。WCF/.NETはSTS(Secure Token Service)と会話してKerberosトークンをSAMLトークンとの交換をサポートしています。マルチホップ間でSAMLを使うことができます。
[注意]
  1. このシナリオは明示的にOWSMで検証済みというわけではありませんが、OWSMがWS-Trustをサポートしているので動作するはずです。
  2. この図ではOracle STSを使っていますが、KerberosトークンのSAMLトークンへの交換をサポートするSTSである限り、任意のSTSを利用できます。
ここには全ての可能性のあるシナリオをリストアップしていませんが、この内容で今何が出来て、何ができないのか要点をお伝えできればうれしいです。

SPNEGO
また、SPNEGOのサポートに関する質問もたくさん見かけます。OWSMは、現在、SPNEGOをサポートしていません。以下のエントリでSPNEGOに関するすべてを知って頂けます。
SPNEGO-based Kerberos and NTLM HTTP Authentication in Microsoft Windows
http://www.rfc-archive.org/getrfc.php?rfc=4559
OWSMでSPENGOサポートを追加するカスタムアサーションを作成することができますが、SPNEGOの場合、WS-Security Kerberos Token Profileとは異なり、Kerberosトークンは、SOAP WS-SecurityヘッダではなくHTTPヘッダにあることに留意する必要があります。
Custom Assertion in OWSM - OES, OSDT (Oracle Security Developer Toolkit) & OWSM - 11g
https://blogs.oracle.com/owsm/entry/custom_assertion_in_owsm_oes
http://orablogs-jp.blogspot.jp/2012/08/custom-assertion-in-owsm-oes-osdt.html(ロジ子訳)
それゆえ、Kerberosトークンを"Negotiate"と呼ばれる認証スキームの下でHTTPヘッダにラップされています。WWW-AuthenticateとAuthorizationヘッダを使ってSPNEGOトークンをクライアント・サーバ間でやりとりします。手順は以下の通りです。
  1. クライアントはAuthorizationヘッダなしで、保護されたドキュメントへのアクセスをサーバに要求する
  2. Authorizationヘッダがリクエストにないので、サーバは401(認証拒否)とWWW-Authenticate: Negotiate を返す。
  3. クライアントはユーザ資格証明を使ってトークンを取得し、その後新しいリクエストのAuthorizationヘッダにトークンを入れてサーバへ送信する。
    [例] Authorization: Negotiate a87421000000492aa874209
  4. サーバはこのトークンをacceptSecContext() GSSAPIに渡してデコードする。コンテキストが完全ではない(Mutual Authenticationの場合)ときには、サーバは WWW-AuthenticateヘッダにGSS-APIデータを入れて、401ステータスコードを返す。
    [例] WWW-Authentiate: Negotiate 74900a2a...
  5. クライアントはこのデータをデコードし、新しいデータをサーバへ返す。このサイクルはセキュリティコンテキストが確立するまで継続する。
リクエスト/チャレンジモデルがあるので、OSB/OEGが"パッシブな仲介者"として機能している場合、通常、SPNEGOセキュリティモデルはOSB/OEGのような仲介者で実現することは困難です。アクティブな仲介モデルのほうがより適切かもしれません。
OSB自体にはSPNEGOをサポートする代替モデルがあります。A-Teamの方がOSBとSPNEGOに関する素晴らしいエントリを書いています([注意] OSB10gR3の頃の内容ですが、現時点でも利用できます)。別のエントリでもSPNEGOを取り扱っています。
Oracle Service Bus and Kerberos (Oracle Fusion Middleware Security)
http://fusionsecurity.blogspot.jp/2010/03/oracle-service-bus-and-kerberos.html
How does Kerberos actually work in the HTTP world? (Oracle Fusion Middleware Security)
http://fusionsecurity.blogspot.jp/2011/01/how-does-kerberos-actually-work-in-http.html
NTLM
よく尋ねられる次の質問はNTLMのサポートに関するものです。OWSMは現在NTLMをサポートしていません。このwikipediaの記述にあるように、NTLMは標準とは異なります。
SPNEGOの関するWikipediaのエントリ
http://en.wikipedia.org/wiki/SPNEGO
NTLMに関するWikipediaのエントリ
http://en.wikipedia.org/wiki/NTLM
おわかりの通り、MicrosoftはNTLMを推奨していません。しかし、お客様が本当にNTLMのサポートが必要ということであれば、カスタムポリシーを作ることができます。

[FMW, Security] Custom Assertion in OWSM - OES, OSDT (Oracle Security Developer Toolkit) & OWSM - 11g

原文はこちら。
https://blogs.oracle.com/owsm/entry/custom_assertion_in_owsm_oes

OES、OSDTとOWSMに関する簡単なメモです。以前のエントリで述べたように、OWSMは、カスタムポリシーとカスタムアサーションを構築するための拡張ガイドを提供しています。
そこで、「いつOWSM 11gでカスタムアサーションを作成する必要があるのか」という質問がでてきます。

簡単に答えると、OWSMが直接サポートしていない場合、ということになります。

いくつか例を挙げてみましょう。
  1. コンテンツに基づくきめの細かい認可のために、例えばOESと連係したい場合。
    このエントリ執筆のタイミングでは、OWSM 11gR1はOESとの連係を提供していませんが、OWSM 11gのカスタムアサーションを使ってOESとの連係することができます。
  2. 以下のリンクに、OWSMのカスタムアサーションを使うOWSM-OESの連係を説明するサンプルがあります。
    The new Oracle Entitlements Server (OES) and Oracle Web Services Manager (OWSM) 11g integration is finally here! (Oracle Fusion Middleware Security) http://fusionsecurity.blogspot.jp/2009/11/new-oracle-entitlements-server-oes-and.html
    OWSM拡張ガイドに別の例があります。
    Oracle® Fusion Middleware Extensibility Guide for Oracle Web Services Manager 11g Release 1 (11.1.1.6)
    http://docs.oracle.com/cd/E23943_01/web.1111/e13882/toc.htm
    Oracle® Fusion Middleware Oracle Web Services Manager拡張ガイド 11gリリース1 (11.1.1.6)
    http://docs.oracle.com/cd/E28389_01/web.1111/b66193/toc.htm
    別の例では…
  3. OAuthを使うサービスをセキュアにするためにOAuthサポートを作りたい場合。
    OWSM 11gは現時点ではOAuthをサポートしていません。ただし、サービスをOAuthで保護したい場合は同様にカスタムアサーションを作成することで実現できます。
  4. 特定の正規化メソッドを使いたい場合(例:標準のポリシーやアサーションテンプレートが当該正規化メソッドの実装の柔軟性を提供しない場合)
  5. 特定のセキュリティ変換を使いたい場合
  6. OWSMなどでLibertyをサポートしたい場合
このエントリの後半では、特定の署名や暗号化を要件とするカスタムアサーションの作成を取り上げます。

カスタムアサーション、署名、暗号化
署名や暗号化などを取り扱うカスタムアサーションを作成する際に心配しなければならない一つに、どんなXMLセキュリティツールキットを使うか、というものがあります。

お気づきかもしれませんが、OWSM拡張ガイドでは署名や暗号化などで利用可能なAPIを提供していませんが、OSDT(Oracle Security Developer Toolkit) という、署名や暗号・復号化、署名の検証などの様々なXMLセキュリティオペレーションを実現する数多くのAPIを公開しているツールが使えるのです。
OSDTのドキュメントは以下からどうぞ。
Oracle® Fusion Middleware Reference for Oracle Security Developer Tools 11g Release 1 (11.1.1)
http://docs.oracle.com/cd/E23943_01/security.1111/e10037/toc.htm
Oracle® Fusion Middleware Oracle Security Developer Toolsリファレンス 11gリリース1(11.1.1)
http://docs.oracle.com/cd/E23549_01/security.1111/b61386/toc.htm
OSDTのjavadocはこちら。
OSDTとOWSM拡張ガイドを組み合わせると、XMLセキュリティやWebサービス(SOAP)セキュリティを取り扱う様々な種類のセキュリティポリシーを構築するための非常に強力なAPIおよびツールキットになります。

[注意]
これらのAPIを使用する際には自分が何をしているかを知る必要があります。これらは、かなり低レベルのAPIであり、ドキュメントは、これらのAPIを使用する開発者がセキュリティ技術や概念、様々な低レベルのビルディングブロックの使用方法について非常に精通していることを前提として記載されています。

これが1つがOWSMカスタムアサーションやOSDTを使ってOWSMの種々のポリシーを構築する方法のガイダンスになることを願っています。

[Linux] It's Better with Btrfs

原文はこちら。
https://blogs.oracle.com/OTNGarage/entry/it_s_better_with_btrfs

Oracle LinuxのBtrfsファイルシステムの理解に役立つ2個の記事が先ごろOTNにUpされました。
How I Got Started with the Btrfs File System in Oracle Linux (Margaret Bierman)
http://www.oracle.com/technetwork/articles/servers-storage-admin/gettingstarted-btrfs-1695246.htmlスケーラビリティとボリューム管理、書き込みの方法論とアクセス、チューニングの可能性など、Btrfsファイルシステムのこうした機能をMargaretが説明しています。それに加えて、冗長構成やチェックサム、障害の分離の取扱い方なども説明しています。また、Btrfsファイルシステムの作成およびセットアップ方法を順を追って説明していますので、Btrfsファイルシステムのことが理解できるようになるでしょう。
How I Use the Advanced Features of the Btrfs File System (Margaret Bierman)
http://www.oracle.com/technetwork/articles/servers-storage-admin/advanced-btrfs-1734952.htmlBtrfsファイルシステムの作成・マウント、ファイルのコピー、削除、冗長ファイルシステムの構成方法および管理方法、ファイルシステムの完全性や残容量をチェックする方法、スナップショットの取り方やクローンの作り方など、Btrfsファイルシステムの進んだ機能について、この記事の中でMargeretが調査しています。
読後の感想やMargaretに今後書いて欲しいものを知らせて下さい。

2012年8月15日

[Java] Java SE 7 Update 6 Released

原文はこちら。
https://blogs.oracle.com/java/entry/oracle_releases_java_se_7

Oracleは先ほどJava SE 7 Update 6のリリースを発表しました。
Java SE 7 Update 6
http://www.oracle.com/technetwork/java/javase/downloads/index.html
このリリースでの注目ポイントは以下の通りです。
  • Oracle Java SEインストーラにJavaFXをマージ
  • JDK 7のフル機能がMac OSで利用可能に
  • JavaFXの2.2リリースとJavaFX Scene Builder 1.0リリース
Java SE 7 Update 6ではJava FXをOracle Java SEインストーラに統合しています。JavaFXはスタンドアロン製品でしたが、このリリースで完全に統合されています。Windowsでは、Java FXとJava Access BridgeがJRE、JREと共にインストールされます。これにより、Java FXを個別にインストール、メンテナンスする必要がなくなり、エンドユーザやシステム管理者の利便性が向上します。アプリケーション開発者にとっても、今後JavaFXランタイムライブラリがデフォルトで無数のデスクトップ上に存在することが保証されるわけです。

Oracle初のMac OS XのフルJDK/JREリリースがJava SE 7 Update 6です。他のOSで利用可能な機能・機構全てがMacでご利用頂けます。もちろんJavaFXリッチクライアントプラットフォームもです。Macを使うJava開発者はOracle Technology Network (OTN) からOracle JDK for Mac OS Xをダウンロードできます。一般ユーザは、他のOSの場合と同様に、Java.comからMac用のJREをダウンロードできます。 Oracleは、MacユーザーがJavaの最も安全なバージョンに追随できるよう、Mac版を他のJavaリリースと同時にリリースしつづける予定です。MacのOracleのJREでは、他のサポートされているプラットフォームと同時に自動更新を提供する予定です。

Oracleはまた、JavaFX開発ツール群の主要コンポーネントであるJavaFX Scene Builderのリリースも発表しています。
JavaFX Scene Builder
http://www.oracle.com/technetwork/java/javafx/tools/index.html
JavaFX Scene Builder 1.0では、ユーザがJavaFXアプリケーションのUIをコーディングせずに素早く設計できるビジュアルレイアウト環境を提供します。「Getting Started with JavaFX Scene Builder 」という動画をご覧下さい。
Getting Started with JavaFX Scene Builder
http://www.youtube.com/watch?v=rHcnsEoSK_c

さらに、改善されたアプリケーションパッケージャを使うと、開発者がJREやJavaFXランタイムライブラリをバンドルしたJavaFXアプリケーションをパッケージし、Windows、Mac OS X、Linux向けのネイティブインストーラを作成することができます。

その他のJava SE 7 Update 6のハイライトは…
  • ARM上のLinuxをサポート
  • JavaFXのタッチモニタやタッチパッドのサポート
  • Linux上でのJavaFXの追加サポート
本リリースでの機能や改善の詳細情報はリリースノートをご覧下さい。
Update Release Notes
http://www.oracle.com/technetwork/java/javase/7u-relnotes-515228.html
ダウンロード

[Java] Oracle releases JDK for Linux ARM, JRE for Mac OS X

原文はこちら。
https://blogs.oracle.com/henrik/entry/oracle_releases_jdk_for_linux

今朝JDK 7 Update 6がリリースされたことをお知らせしました。このリリースにはMac OS X版のアップデート、JDKのLinux ARM版への移植版が含まれています。
Oracle Releases New Java Updates - Java SE 7 Update 6, JavaFX 2.2 and JavaFX Scene Builder 1.0
http://www.oracle.com/us/corporate/press/1735645
Java SE Downloads
http://www.oracle.com/technetwork/java/javase/downloads/index.html
Mac OS X版Java 7の開発は長期にわたりました。OpenJDKでAppleと共に2010年11月から取り組んできた結果、多くのJDK/JREとOS Xでの成果を得ることができました。一見すると平凡ですが時間のかかるタスク(ビルド&テストのインフラの拡張やJavaとOSのリリースサイクルの分離など)の結果、多くの作業が行われました。とにかく、7u6リリースでは、最終的にデスクトップのJREを追加し終えました。そして、 java.oracle.com および(1週間ほどで) java.com 上からでダウンロードできるようにしています。
JDK7u6ではまた、(デスクトップJREではなく)JDKのLinux ARMへの汎用移植版を追加し、他のプラットフォーム用のOracle Javaと同じライセンス条件下で利用できるようにしています。このJDKリリースは、新興のARMサーバ市場を目指すことを目的としており、ボード開発に取り組んでいるコミュニティ( BeagleBoard 、 PandaBoard 、 Raspberry Pi など)向けです。この移植版では、ARMv6、v7向けの32ビットのバイナリを提供しており、ほとんどのLinuxディストリビューション上で動作する、Swing/ AWT、クライアント(C1)とサーバ(C2)のコンパイラを完全にサポートしています。一つ注意すべき点は、現在のバイナリがsoftfloat ABIだけなので、(例えば)hardfloat ABIを使用するRaspbianディストリビューションでは動作しません。我々は、今後のJDKリリースでhardfloatのサポートとARM上でのJavaFXのサポートを追加する予定にしています。

ARM移植版に関する問い合わせがたくさん届くことが予想されますので、いくつかFAQをご紹介しておきます。
  • Java SE EmbeddedとJDK for ARMとの関係は?
    Java SE Embeddedは小フットプリントデバイス向けのJava SE互換ランタイムで、複数のアーキテクチャ(ARM v5/6/7、x86、PPCを含む)で利用できます。この製品はOracleが組み込み用途で商用目的でライセンス許諾しています。
  • ARM JDKはフリー(無償)ですか、それとも商用ライセンスが必要ですか?
    全ての汎用JDK、JREバイナリと同様に、無料でARM JDKを汎用ハードウェア上での開発、運用にご利用頂けます。そして汎用コンピュータを対象とするアプリケーションと共に無料で再配布できます。正確なライセンス許諾、制限事項はエンドユーザライセンスをご覧下さい。
    Oracle Binary Code License Agreement for the Java SE Platform Products and JavaFX
    http://www.oracle.com/technetwork/java/javase/terms/license/index.html
    例を挙げると、TomcatやGlassFishが動作している、データセンターに配置されているARMサーバは汎用です。PCのように使っている場合、Raspberry Piボードも同じです。産業用コントローラやキオスクアプライアンスは汎用ではないので、両者には商用ライセンスが必要です。
  • Oracle JDKのARMへの移植版はOpenJDKで利用できますか?
    いいえ、現時点ではオープンソース化する予定はありません。
  • Raspberry Pi/BeagleBoard/PandaBoardを持っていますが、その上で動くJavaをどうやって入手すればいいですか?
    softfloat ABIを使うLinuxディストリビューションを使って、Oracle JDKをダウンロード、インストールして下さい。
  • なぜOracleはARMの移植版に投資し、無料で配布しているのでしょうか。
    極秘の戦略があります。そのアイデアとは、Javaが反映繁栄を続け、そのうちにARMサーバ上のミドルウェアを売ることができるように、Java開発者に可能性を与えることです。

2012年8月14日

[SOA] Automatically Disable Proxy Service to avoid overloading OSB

原文はこちら。
https://blogs.oracle.com/ateamsoab2b/entry/automatic_disabling_proxy_service_when

Oracle Service Bus(OSB)の利用に関する質問でよく尋ねられるのは、「エンドポイントが一時的に接続できなくなったときに、OSBに過負荷がかからないようにするには?」というものです。エンドポイントが想定ほど素早く応答せず、最悪の場合徐々に応答時間が悪化する場合にはどうすればいいのか、という質問も、同じぐらい頂きます。関心はOSBが止まるという潜在的リスク 関連するプロキシサービスが呼び出し側からのリクエストを受信し続けた場合に、OSBが止まるという潜在的リスクに対する懸念があるのです。
設計プラクティスの観点からすると、エンドポイントの可用性を高くしておくことが常に推奨されています。複数のエンドポイントに対するロードバランサやOSBのフェイルオーバ機能を使って、OSBをより安全に、エンドポイントのエラー由来の脆弱性を減らすことができます。さらに、ワークマネージャを構成してプロキシサービスに割当て、ビジネスサービスの流量制御を有効にするという、OSBのベストプラクティスを実装するべきでしょう。これらの2個の機能の詳細はこのエントリでは取り扱いませんので、OSBでのワークマネージャの使用の詳細、流量制御については、以下のリンクから確認して下さい。
Oracle® Fusion Middleware Administrator's Guide for Oracle Service Bus 11g Release 1 (11.1.1.6.3)
Using Work Managers with Oracle Service Bus
http://docs.oracle.com/cd/E23943_01/admin.1111/e15867/modelingmessageflow.htm#OSBAG1428
Throttling
http://docs.oracle.com/cd/E23943_01/admin.1111/e15867/throttling.htm

Oracle® Fusion Middleware Oracle Service Bus管理者ガイド 11g リリース1(11.1.1.6.0) Oracle Service Busでのワーク・マネージャの使用
http://docs.oracle.com/cd/E28389_01/admin.1111/b61436/modelingmessageflow.htm#BACDDGHB
スロットル
http://docs.oracle.com/cd/E28389_01/admin.1111/b61436/throttling.htm
しかし、これはストーリーの全体図ではありません。予期しない問題がエンドポイントで発生したら、その事象を通知して欲しいでしょうし、その事象に対する適切なアクションを取りたいと考えることでしょう。特に唯一のエンドポイントもしくはエンドポイントを管理するシステムが外部にあって管理できない場合はなおさらです。それでは、エンドポイントで以下の2個の頻出する問題が発生したときの通知方法を見ていきましょう。
  • エンドポイントが到達不能になる
  • エンドポイントは生きているが、レスポンスが遅くなりSLAに抵触する
OSBには通信エラーでレスポンスのないエンドポイントURIをオフラインにする、すてきな機能があります。Service Level Agreement (SLA) のルールを定義して、エンドポイントURIがオフラインになったときにアラートを発行することができます。レスポンス時間に関するSLAを定義することもできます。レスポンス時間が定義した時間よりも長い場合、OSBがアラートを自動的に発行することができます。
アラートが発行されれば、取るべき適切なアクションが何かを決定する必要があります。エンドポイントの問題が継続し、迅速に解決できない場合には、取り得るアクションは、問題が切り分けられるまでリクエストを受け付けないプロキシサービスを停止することです。OSB管理コンソールから手作業でプロキシサービスを無効にすることができますし、WLSTでも実現可能です。このエントリでは、エンドポイントの異常でSLAに抵触したときに、プロキシサービスを自動的に無効にする、OSBのJava APIを使った代替手段をご紹介します。
実装手順はおおよそ以下のようになります。
  1. レスポンス時間が想定値を上回る場合、もしくはエンドポイントが到達不能になった場合にアラートを発行するSLAルールを作成する
  2. アラートを指定のJMS Queueに送るよう設定する
  3. JMS Queueを監視する 「管理用」のプロキシサービスを作成する
  4. アラートをJMS Queueから受けた際に関連するプロキシサービスを無効にする Javaコールアウトを 「管理用」プロキシサービス内に作成する
詳細は以下の通りです。

指定したJMS Queueにアラート送るためのアラートの送り先を作成します。

ビジネスサービスを作成し、オフラインになっているエンドポイントURIを有効にします。エンドポイントURIが到達不能であれば、OSBは自動的にステータスをオフラインになります。

SLAを定義します。レスポンス時間の最大値が5000ms(5秒)を超える場合、もしくはエンドポイントがオフラインとマークされた場合に、アラートを発行します。

指定のJMS Queueをチェックする「管理用」プロキシサービスを作成します。

アラートメッセージを受け取ると、アラートをJMS Queueへ送信時にOSBが設定したJMSヘッダーを、プロキシサービスが取得します。このエントリでは、単にアラートメッセージのサービス名ヘッダを使って、このアラートを発行したビジネスサービスを発見することにしています。これを実現するためのXPath式は以下のようになります。
$inbound/ctx:transport/ctx:request/tp:headers/tp:user-header[@name="ServiceName"]/@value
ビジネスサービスの名前に基づいて、どのプロキシサービスが無効なのかを発見するためのパラメータを構成します。最後に、プロキシサービスを無効にするJavaコールアウトを作成します。このエントリではプロキシサービスをハードコーディングで決めうちにしています。

以下はプロキシサービスを無効にするJavaコードのサンプルです。Java APIを使って、プログラムでプロキシサービスを有効/無効にする方法を示しています。同じコードをビジネスサービスにも適用できます。
package com.oracle.ateam;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Hashtable;

import com.bea.wli.sb.management.configuration.SessionManagementMBean;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
import weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean;
import weblogic.management.jmx.MBeanServerInvocationHandler;

import com.bea.wli.config.Ref;
import com.bea.wli.sb.management.configuration.ProxyServiceConfigurationMBean;

public class ServiceManager {

    private static JMXConnector initConnection(String hostname, int port,
            String username, String password)
    throws IOException,MalformedURLException
    {
        JMXServiceURL serviceURL =
        new JMXServiceURL("t3", hostname, port,
        "/jndi/" + DomainRuntimeServiceMBean.MBEANSERVER_JNDI_NAME);

        Hashtable <string, string> h = new Hashtable<string, string>();
        h.put(Context.SECURITY_PRINCIPAL, username);
        h.put(Context.SECURITY_CREDENTIALS, password);
        h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote");

        return JMXConnectorFactory.connect(serviceURL, h);
    }

    private static Ref convertServiceURI2Ref(String resType,String serviceuri){
        Ref ref = null;
        if((serviceuri.equals(""))||(serviceuri==null))
                return ref;

        String[] uriData = serviceuri.split("/");
        ref = new Ref(resType,uriData);
        return ref;
    }

    public static void changeProxyServiceStatus(String serviceref,boolean status)throws Exception{
        JMXConnector conn = null;
        SessionManagementMBean sm = null;
        String sessionName = "Session.ByApp." + System.currentTimeMillis();

        try{

            conn = initConnection("localhost", 7001, "weblogic", "welcome1");
            MBeanServerConnection mbconn = conn.getMBeanServerConnection();
            DomainRuntimeServiceMBean domainService = (DomainRuntimeServiceMBean) MBeanServerInvocationHandler.
                 newProxyInstance(mbconn, new ObjectName(DomainRuntimeServiceMBean.OBJECT_NAME));

            sm = (SessionManagementMBean) domainService.
                 findService(SessionManagementMBean.NAME,
                             SessionManagementMBean.TYPE, null);

            sm.createSession(sessionName);

            ProxyServiceConfigurationMBean proxyConfigMBean = (ProxyServiceConfigurationMBean) domainService.
             findService(ProxyServiceConfigurationMBean.NAME + "." + sessionName,
                     ProxyServiceConfigurationMBean.TYPE, null);
            Ref ref = convertServiceURI2Ref("ProxyService",serviceref);
            String msg = "";
            if(!status){
               proxyConfigMBean.disableService(ref);
               msg="Disabled the Proxy Service : " + serviceref;
            }
            else {             
                proxyConfigMBean.enableService(ref);   
                msg="enabled the Proxy Service : " + serviceref;
            }                                 

            sm.activateSession(sessionName, msg);
            System.out.println(msg);
            conn.close();
        }catch(Exception ex){
            if(null != sm) {
                try{
                    sm.discardSession(sessionName);
                }catch(Exception e) {
                    System.out.println("discard session error");
                }
            }
            throw ex;
        }finally{
            if(null != conn)
                try{
                    conn.close();
                }catch(Exception e) {
                    e.printStackTrace();
                }
        }
    }
}
SLAで定義した5秒よりも長い、10秒間のスリープをエンドポイントに配置すると、下図のように、プロキシサービスが自動的に無効になります。

エンドポイントを停止するという別のテストでも、期待通り同じ結果(自動的にプロキシサービスが無効になる)が得られます。同時に、OSBが自動的にエンドポイントをオフラインとマークしていることも確認できます。

このエントリで、エンドポイントが到達不能になったり、SLAに抵触する場合に自動的にプロキシサービスを無効にする方法を説明しました。しかし自動化を検討される場合にはご注意頂く必要があります。その理由は、プロキシサービスを無効にするべきかどうか、いつ無効にすべきかを判断するための、非常に多くの検討・評価すべき要素や基準があるからです。代わりに、上記サンプルに手を入れてアラート発行とJava APIを使ったプロキシサービスの無効化の2ステップに分け、その後人が決定するという手順を間に追加することもできます。

2012年8月13日

[WLS, Java] Weblogic Server - Monitor JDBC Resources via JMX API

原文はこちら。
https://blogs.oracle.com/muraliveligeti/entry/monitor_jdbc_resources_via_jmx

ドメインのJDBCリソースを監視する方法は2つあります。
  1. 各管理対象サーバに直接アクセス(ランタイムMBeanサーバ)
  2. 管理サーバを経由してアクセス(ドメインランタイムMBeanサーバ)
ドメインランタイムMBeanサーバを使った場合のメリット
  • 管理サーバ上のドメインランタイムMBeanサーバに接続するための一つのURLだけでよく、接続後、全てのサーバインスタンスの値をルックアップ、必要に応じて結果をフィルタリングすることもできる。
  • コードがランタイムMBeanサーバを使って複数のサーバインスタンスのMBeanの値を読み取る場合、各サーバインスタンス(一意のリスニングアドレス、ポートの組み合わせを持つ)のURLを使ってコードを作成する必要がある。
  • WebLogic Serverドメインの全ての管理トラフィックを管理サーバのセキュアな管理ポートにルーティングすることができる。ファイウォールを使うと、管理サーバの管理ポートへの外部からの接続を防ぐことができる。
ドメインランタイムMBeanサーバを使った場合のデメリット
  • 管理サーバが落ちている場合、ドメインランタイムMBeanサーバを使って監視できない。その場合、ランタイムMBeanサーバにアクセスする必要がある。
  • 各管理サーバのランタイムMBeanサーバに直接接続してMBeanの値を読む場合、ドメインランタイムMBeanサーバが管理対象サーバから値を取り出すために必要なネットワークホップ数が少なくなる。
WebLogic ServerのMbeansを、管理用途か、サーバやリソースの構成用途かに基づいて、以下の一般的なタイプの一つに分類することができます。
  1. ランタイムMBeansにはサーバやリソースのランタイム状態に関する情報が含まれている。 一般的にMBeanにはサーバやリソースの現在の状態に関するデータのみ持っており、これらのデータを永続化しない。サーバインスタンスを停止した場合、ランタイムMBeansからの全てのランタイム統計やメトリックは破棄される。
  2. 構成MBeansにはサーバやリソースの構成に関する情報が含まれている。このMBeansはドメインのXML構成ドキュメントに格納されている情報を表現している。システムモジュールの構成MBeansは、例えばJDBCデータソースや、システムレベルで指定されたJMSトピックサービスのようなサービス構成に関する情報が含まれている。
全てのMBeansを、javax.management.ObjectName型というオブジェクト名でMBeanサーバに登録する必要があります。
WebLogic Severの命名規則はMBeanオブジェクト名を以下のようにエンコードします。
com.bea:Name=name,Type=type[,TypeOfParentMBean=NameOfParentMBean]
[,TypeOfParentMBean1=NameOfParentMBean1]...
ここで、
  • com.bea: JMXドメイン名
  • Name=name,Type=type[,TypeOfParentMBean=NameOfParentMBean] [,TypeOfParentMBean1=NameOfParentMBean1]... :JMXキープロパティ
キープロパティの順序は重要ではありませんが、名前は必ずcom.bea:で始まる必要があります。
では、JDBCリソースを監視するためにMBeanサーバに接続するプログラムを書くというシナリオを考えてみましょう。
WebLogic ServerはMBeanを階層データモデルで整理しています。このモデルでは、全ての親MBeanが子MBeanのオブジェクト名を含む属性を持ちます。標準的なJMX APIで子オブジェクト名を使って、子MBeanの属性値を設定・取得したり、メソッドを呼び出したりします。
WebLogic ServerのMBean階層をナビゲートするには…

Step 1: MBeanサーバとの接続を作成する
MBeanサーバに接続する方法には、(a) ローカル接続と(b) リモート接続の2種類があります。

(a) ローカル接続
アプリケーションが同一サーバ(管理サーバもしくは管理対象サーバ)で実行しているものとします。
ドメインランタイムMBeanサーバに接続
private static MBeanServer connection;   
InitialContext ctx = new InitialContext();   
connection= (MBeanServer)ctx.lookup("java:comp/env/jmx/domainRuntime"); 

管理対象サーバのランタイムMBeanサーバに接続
private static MBeanServer connection;
InitialContext ctx = new InitialContext();   
connection = (MBeanServer)ctx.lookup("java:comp/env/jmx/runtime"); 
(b) リモート接続
アプリケーションはサーバ外で動作しており、サーバ(管理サーバもしくは管理対象サーバ)のリソースを監視するものとします。
ドメインランタイムMBeanサーバに接続
private static MBeanServerConnection connection;   
private static JMXConnector connector;   

String hostname = "WLS_host";
int port = WLS_port;   
String protocol = "t3";

Integer portInteger = Integer.valueOf(portString);   
int port = portInteger.intValue();   

String jndiroot = "/jndi/";   
String mserver = "weblogic.management.mbeanservers.domainruntime";   

JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port, jndiroot + mserver);
Hashtable<String,String> h = new Hashtable<String,String>();   

h.put(Context.SECURITY_PRINCIPAL, username);   
h.put(Context.SECURITY_CREDENTIALS, password);   
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,"weblogic.management.remote");   

connector = JMXConnectorFactory.connect(serviceURL, h);   
connection = connector.getMBeanServerConnection(); 

管理対象サーバのランタイムMBeanサーバに接続
private static MBeanServerConnection connection;   
private static JMXConnector connector;   

String hostname = "WLS_host";
int port = WLS_port;
String protocol = "t3";
Integer portInteger = Integer.valueOf(portString);
int port = portInteger.intValue();   
String jndiroot = "/jndi/";   
String mserver = "weblogic.management.mbeanservers.runtime";   

JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port, jndiroot + mserver);
Hashtable<String,String> h = new Hashtable<String,String>();   

h.put(Context.SECURITY_PRINCIPAL, username);   
h.put(Context.SECURITY_CREDENTIALS, password);   
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,"weblogic.management.remote");   

connector = JMXConnectorFactory.connect(serviceURL, h);   
connection = connector.getMBeanServerConnection(); 

Step 2: MBeanのオブジェクト名を取得する

MBeanServerConnection.getAttribute(ObjectName object-name, String attribute)メソッドを呼び出してMBean階層のルートでMBeanの名前を取得します。ここで、
  • object-name:MBeanサーバに登録されているサービスMBeanのオブジェクト名。
  • attribute :  子MBeanの一つ以上のインスタンスを含む現在のMBeanの属性の名前。属性が複数の子を含む場合、オブジェクト名の配列 ObjectName[] に出力結果を割り当てる。
1)ドメインランタイムMBeanを取得
javax.management.ObjectName service = new ObjectName(   
"com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean"); 

2)DomainRuntimeServiceでServerRuntimesを取得する(つまり、ドメインランタイムMBeanから全ての管理対象サーバのランタイムMBeanを取得しようとする、ということ)
ObjectName[] serverRuntimesArray = (ObjectName[])connection.getAttribute(service, "ServerRuntimes"); 

3)各サーバランタイムMBeanについてJDBCDataSourceRuntimeMBeansを取得する
Foreach serverRuntime:   
Start:   
ObjectName[] dataSourceArray = (ObjectName[])connection.getAttribute(new ObjectName("com.bea:Name="+name+",ServerRuntime="+name+",Location="+name+",Type=JDBCServiceRuntime"),"JDBCDataSourceRuntimeMBeans");
End:
ここで、
  • connection:MBeanServerConnection型のオブジェクト(step 1でこのオブジェクトを取得済み)


このエントリに添付したアプリケーションにアクセスするには

JDBCMbean.warとJDBCMbean.zipをこのエントリに添付しています。
  1. warファイルをダウンロード
  2. JDBCMbean.warを管理サーバにデプロイし、以下のURLでアプリケーションにアクセス
    http://<host>:<port>/JDBCMbean/index.jsp".
  3. ホスト名、管理サーバのポート番号、管理ユーザ名、パスワードを指定してsubmitをクリックする。このプログラムは環境全体(管理サーバ、管理対象サーバ)のJDBC構成を抽出する

.warファイルを実行すると以下のような表示が出てきます。

JDBC Resources

JDBCリソースの監視のためのサンプルWebアプリケーション
https://blogs.oracle.com/muraliveligeti/resource/JDBCMbean.war
プロジェクトファイル
https://blogs.oracle.com/muraliveligeti/resource/JDBCMbean.zip

2012年8月12日

[WLS] Oracle WebLogic RESTful Management Services: From Command Line to JavaFX

原文はこちら。
http://www.oracle.com/technetwork/articles/soa/oliveira-wls-rest-javafx-1723982.html

作者について
William Markito Oliveira
ブラジルのOracle Platform Technology SolutionsチームのSenior Technologist。ミドルウェア、SOA、Javaテクノロジーを主に担当。CDI、EJB 3.1、JAX-RSの記事やコードサンプルを提供する公式Java EE Tutorialのメンバーでもあります。

概要
Oracle WebLogic Server 12c はメジャーリリースで、Java EE 6、Mavenとの統合、JDK 7のサポートといったいくつかの新機能を含んでいますが、Oracle WebLogic Serverのドメインを管理・監視する上で重要な追加機能も含まれています。本記事ではそのような機能の一つである、RESTful Management Serviceについて取り上げます。
Oracle WebLogic Server 12cでは、RESTfulサービスを使って、実行中のサーバインスタンスを監視できるようになりました。例えば以下のようなものを監視できます。
  • Applications
  • Clusters
  • Data Sources
  • Servers
この機能のうちもっとも関心が高い部分は、こうしたサービスを任意のRESTfulクライアント(異なるプログラミング言語のクライアントを含む)から呼び出せることでしょう。この記事では以下のツールを使って監視タスクを実行する方法をご紹介します。
  • 組み込みWebクライアント
  • cURL
  • Pythonスクリプト
  • JavaFXアプリケーション
他のツールからも利用できますが、詳細をご紹介するのはこの記事の範囲を超えてしまいます。完全なAPIのリファレンスや詳細を知りたい方は、Oracle WebLogic Serverのドキュメントをご覧下さい。この記事の[参考資料]にまとめておきました。

必要なもの

  • Oracle WebLogic Server 12c
  • Python 2.7+
  • JDK 7u04 (JavaFXをビルトインサポートしているもの)
  • 任意のOS(UNIXライクなOS、LinuxやOSXなどが望ましい)
RESTful Management Servicesを使うため、この機能をOracle WebLogic Administration Consoleで有効にしましょう。
  1. [ドメイン構造]>ドメイン名をクリック
  2. [構成]>[全般]>[詳細]をクリック
  3. [RESTful管理サービス]のチェックボックスをONにして保存

  1. サーバを再起動します。再起動時に以下のような出力を確認できるはずです。
<2012/08/12 16時59分29秒 JST> <Notice> <WebLogicServer> <BEA-000360> <The server started in RUNNING mode.> 
<2012/08/12 16時59分29秒 JST> <Warning> <Server> <BEA-002611> <The hostname "javelin.local", maps to multiple IP addresses: 172.16.80.50, fe80:0:0:0:cabc:c8ff:fe9a:eff6%4.> 
8 12, 2012 4:59:31 午後 com.sun.jersey.api.core.PackagesResourceConfig init
情報: Scanning for root resource and provider classes in the packages:
  weblogic.management.rest.resources
  weblogic.management.rest.provider
8 12, 2012 4:59:31 午後 com.sun.jersey.api.core.ScanningResourceConfig logClasses
情報: Root resource classes found:
  class weblogic.management.rest.resources.ApplicationResource
  class weblogic.management.rest.resources.DataSourceResource
  class weblogic.management.rest.resources.ClusterResource
  class weblogic.management.rest.resources.TestResource
  class weblogic.management.rest.resources.ServerResource
8 12, 2012 4:59:31 午後 com.sun.jersey.api.core.ScanningResourceConfig logClasses
情報: Provider classes found:
  class weblogic.management.rest.provider.CollectionResponseJsonProvider
  class weblogic.management.rest.provider.CollectionResponseXmlProvider
  class weblogic.management.rest.provider.ItemResponseJsonProvider
  class weblogic.management.rest.provider.ItemResponseHtmlProvider
  class weblogic.management.rest.provider.CollectionResponseHtmlProvider
  class weblogic.management.rest.provider.ItemResponseXmlProvider
8 12, 2012 4:59:32 午後 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
情報: Initiating Jersey application, version 'Jersey: 1.9 09/02/2011 11:17 AM'

RESTful管理サービス
共通のフォーマットに従う共通のURLでRESTful管理サービスにアクセスできます
http(s)://[host]:[port]/management/tenant-monitoring/[path]
ここで、
  • host - Oracle WebLogic Serverの管理サーバを実行しているホスト
  • port - HTTP もしくは HTTPS ポート
  • path - 各リソースを識別する相対パス。例えば、サーバインスタンスへのパスはservers/AdminServer、データソースはdatasources/myDataSource…といった感じ。
サービスの実装はJersey(JAX-RSの参照実装)ベースで、以下の結果表現をサポートしています。
  • JSON ("application/json")
  • XML (""application/xml")
  • HTML
デフォルトの出力はHTMLですが、APIを呼び出す際にAccept: HTTPヘッダを特定することにより振る舞いを変更することができます。APIの詳細や、各リソースが取り出す値や属性の完全なリファレンスはOracle WebLogic Serverのドキュメントから入手できます。この記事の[参考資料]にまとめてあります。
次は、RESTクライアントの例をご紹介しましょう。こうしたサービスに任意のWebブラウザからアクセスできることに言及しておくことは重要なことと考えています。例えば、RESTfulサービスを現在実行中のWebLogic Serverのドメインで有効にした後、以下のURLをブラウザに入力して下さい。
http://localhost:7001/management/tenant-monitoring/servers
[注意]このURLに最初にアクセスするときに、ユーザ名とパスワードの入力を求められます。AdministratorsグループもしくはMonitorsグループに属するユーザのみがRESTful管理サービスにアクセスできます。
この記事ではデフォルトユーザ名 weblogic とパスワード welcome1 を使います。
認証が通ると、ブラウザ出力は以下のような感じになっているはずです。

前述の通りデフォルトの出力はHTMLなので簡単なHTMLページです。

「隠された」ネイティブクライアント
Oracle WebLogic Server 12cには組み込みWebクライアントも含まれています。これを使ってサービスを呼び出すことができます。このWebクライアントは種々の出力フォーマット(XML、JSON、HTML)をサポートしています。
[注意]クライアントはテスト目的のためだけに使って下さい。サポート対象外です。
このクライアントには以下のURLでアクセスできます。
http://localhost:7001/management/ajaxtest.html
以下の3個の図はリソースの選択についての利用例です。

ネイティブクライアント:全サーバのリスト


ネイティブクライアント:全クラスタのリスト

ネイティブクライアント:特定のサーバ情報をXML形式でチェック

ネイティブクライアントを使うと管理コンソールよりも簡単かつ迅速に利用可能なリソースの共通情報にアクセスできます。もし必要な情報の正しいパスを知っていれば、という前提付きですが。

cURL - (libcurl)
Linux Manual によると、cURLは次のように定義されています。
"A tool to transfer data from or to a server, using one of the supported protocols (DICT, "FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP). The command is designed to work without user interaction…cURL offers a busload of useful tricks like proxy support, user authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer resume and more."
"サポートされているプロトコル(DICT, "FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET、そしてTFTP)を使い、サーバから/へデータを転送するツール。コマンドはユーザインタラクションなしで動作するように設計されている…cURLは多数の有用なトリック(プロキシのサポート、ユーザ認証、FTPアップロード、HTTPのポスト、SSL接続、cookie、ファイル転送の中断·再開など)を提供します。"
実行中のOracle WebLogic Serverドメインからデータを取り出す簡単なシェルスクリプトを作るのにcURLはいいツールです。以下はcURLスクリプトのスニペットです。
コード1 - サーバ情報のチェック(RAW JSON形式で出力)
Javelin% curl -s --user weblogic -H "Accept: application/json" http://localhost:7001/management/tenant-monitoring/servers/
Enter host password for user 'weblogic':
{"body":{"items":[{"name":"AdminServer","state":"RUNNING","health":"HEALTH_OK"},{"name":"ManagedServer_1","state":"SHUTDOWN"},{"name":"ManagedServer_2","state":"SHUTDOWN"}]},"messages":[]}
コード2 - サーバの現在のフリーのヒープをチェック
Javelin% curl -s --user weblogic -H "Accept: application/json" http://localhost:7001/management/tenant-monitoring/servers/AdminServer | grep -Po '"heapFreeCurrent":[ 0-9]*'
Enter host password for user 'weblogic':
"heapFreeCurrent":152676576
コード3 - 作成されたデータベース接続の総数を表示
Javelin% curl -s --user weblogic -H "Accept: application/json" http://localhost:7001/management/tenant-monitoring/datasources/myDataSource | grep -Po '"connectionsTotalCount":[ 0-9]*'
Enter host password for user 'weblogic':
"connectionsTotalCount":10
いくつかのオプションを使うと、コマンドラインツールからの出力結果をパースすることができます。よく使われるのは、awk、sed、grepですが、新しいツールとして、jsawkという、JSONのパースに特化したものもあります。ご利用の用途にあわせて賢明な選択をして下さい。

Pythonクライアント
Pythonはアプリケーション開発者、Web開発者、システム管理者、および科学的な研究者を含む専門家の広い範囲の間で非常に人気のあるパワフルな言語です。そのパワーに加え、Pythonを学ぶのは非常に簡単で、スペースとインデントでコードの可読性を提供することに明確な目標があります。
PythonはほとんどのLinuxサーバにデフォルトでインストールされているので、多くのシステム管理者は、マシン環境(メモリ、CPU使用率、ファイルシステム、ネットワーク)を監視するPythonスクリプトを作成します。この記事では、そのリストにOracle WebLogic Serverを追加してみたいと思います。

Script #1 — サーバステータスの監視
この最初のスクリプトでは、Oracle WebLogic Serverのサーバをリスト表示し、各サーバの状態を表示します。華麗さはありませんが、このスクリプトを簡単にLinux/UNIXのcronに追加でき、特定の時間(1分、30秒)実行して全てのOracle WebLogic Serverが起動していて実行中かどうかを確認できます。この場合のREST呼び出しの応答はJSONです。PythonのJSONライブラリを使って結果を辞書やリストにパースすることができます。

コード 4 - Pythonを使ってサーバ状態をチェックする
#!/usr/bin/python
'''
Created on Jul 2, 2012 Check Weblogic Server Status @author: markito
'''
import urllib2, json

####################
# Modify the server information accordingly
####################
host = "localhost"
port = "7001"
username = "weblogic"  
password = "welcome1"
    
################################################################################
def main():

    baseURL = "http://%s:%s/management/tenant-monitoring/servers" % (host,port)
    
    # HTTP Authentication
    passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
    passman.add_password(None, baseURL, username, password)    
    authhandler = urllib2.HTTPBasicAuthHandler(passman)
    opener = urllib2.build_opener(authhandler)
    urllib2.install_opener(opener)
    
    try:
        req = urllib2.Request(baseURL, None, {'Accept': 'application/json'})
        raw = urllib2.urlopen(req).read()
        data = json.loads(raw)
        items = data['body']['items']
        
        for item in items:
            print "Server: " + item['name'] + " [ " + item['state'] + " ]" 
            
    except urllib2.HTTPError, e:
        print "HTTP error: %d" % e.code
        
    except urllib2.URLError, e:
        print "Network error: %s" % e.reason.args[1]
################################################################################
if __name__ == '__main__':
    main()
スクリプトを実行するために、上記のスクリプトをコピーして実行可能なPythonスクリプト(serverStatus.pyなど)として保存しましょう。出力結果は以下のような感じになるはずです。
Javelin% ./ServerStatus.py 
Server: AdminServer [ RUNNING ]
Server: ManagedServer_1 [ SHUTDOWN ]
Server: ManagedServer_2 [ SHUTDOWN ]
もちろん、Oracle WebLogic Scripting Tool(WLST)を使用してもほぼ同じ結果を達成できますが、いくつか考慮すべき違いがあります。
  • Python vs. JythonPythonはCで作られた多目的言語です。解釈、コンパイルされると.pycファイルを生成します。Pythonは自身でガベージコレクション実装も有しています。Jythonは100%Javaで書かれたPythonの移植版で、任意のJVMで実行できます。コンパイルするとコードは.classファイルを生成しJavaのガベージコレクション実装を使用します。WLSTスクリプトはJythonで書かれています。
  • クラスパスが必要WLSTを実行するためには、特定のライブラリをご自身の環境に設定しなければなりません。通常の場合、WLSTスクリプトを実行する前に、<Domain_Home>/binにあるsetDomainEnv.sh/cmdスクリプトを実行する必要があります。
  • プロトコルWLSTを使うと、接続ではOracle WebLogic Server固有のプロトコルであるT3を使います。PythonとRESTを使う場合はHTTP接続です。
  • 実行Python言語は軽量です。スクリプトを何度か実行したところ、一貫してWLSTはPythonよりも時間がかかることがわかりました。
WLSTを使って、Oracle WebLogic Serverのドメインを管理(サーバーの開始、停止)したり、サーバーの設定を変更したり、新しいリソース(データソース、JMSキューなど)を作成できることに注意してください。このリリースでは、Oracle WebLogic RESTful管理サービスは厳密に監視のみに限定されていて、サーバー上の任意の値を更新したり変更したりすることはできません。

コード5 - サーバ状態のチェックする(WLST版)
'''
Created on Jul 4, 2012 @author: Markito @file: serverStatusWLST.py
'''

####################
# Modify the server information accordingly
####################
username = 'weblogic'
password = 'welcome1'
URL='t3://localhost:7001'

################################################################################
connect(username,password,URL)
domainConfig()
serverList=cmo.getServers();

domainRuntime()
cd('/ServerLifeCycleRuntimes/')

for server in serverList:
     name=server.getName()
     cd(name)
     serverState=cmo.getState()
     
     print "Server: " + name + " [ " + serverState + " ]"
     cd('..')

上記スクリプトを実行するために、serverStatusWLST.py などといった名前でファイルに保存して下さい。setDomainEnv.sh スクリプト(source setDomainEnv.shもしくは. /setDomainEnv.sh)を実行してから以下のコマンドで実行して下さい。
java weblogic.WLST serverStatusWLST.py

Script #2 — 手の込んだPythonクライアント
2個目のスクリプトには実行中のOracle WebLogic Serverのドメインの追加情報を監視するためのいくつかの追加オプションが含まれています。それは、スクリプトにOracle WebLogic Serverの固定のURL、ユーザ名またはパスワードを持っておらず、以前のスクリプトよりも安全であるの点に注意することが重要です。監視したいリソースのタイプを含めて、すべてをスクリプトにパラメータとして渡します。
  • -h または --host: Oracle WebLogic 管理サーバのアドレス
  • -u または --user: 認証のためのユーザ名
  • -p または --password: パスワード
  • -s または --server: サーバの監視
  • -d または --datasource: データソースの監視
  • -a または --application: アプリケーションの監視
  • -c または --cluster: クラスタの監視
コード6 - 多くの監視オプションを追加したPythonスクリプト
#!/usr/bin/python
''' Created on Jun 26, 2012 @author: Markito @file: WLSTRESTPy.py '''
import getopt, sys, getpass
import urllib2

__version__ = 0.1

def main():
    
    wls = WLSREST()
    
    try:
        opts, args = getopt.getopt(sys.argv[1:], "h:o:u:pvs:d:a:c", 
["host=", "output=", "user=","password","version", "server=",
 "datasource=", "application=", "cluster="])
    except getopt.GetoptError, err:
        print str(err)
        wls.usage()
        sys.exit(2)
        
    ###############
    ## iterate and parse each parameter and input value
    ###############
    for opt, value in opts:
        if (opt in ('-v', '--version')):
            print 'Version %(v)s' % {'v':  __version__ }
            
        elif (opt in ('-h', '--host')):
            host = value
            wls.baseURL = "%s/management/tenant-monitoring/" % (host)     
                  
        elif (opt in ('-p', '--password')):
            wls.password = getpass.getpass("Password: ")
   
        elif (opt in ('-u', '--user')):
            wls.username = value
    
        elif (opt in ('-s', '--server')):
            wls.checkServer(value)
            
        elif (opt in ('-d', '--datasource')):
            wls.checkDataSource(value)
            
        elif (opt in ('-a', '--application')):
            wls.checkApplication(value)
            
        elif (opt in ('-c', '--cluster')):
            wls.checkCluster(value)
        else: 
            wls.usage()
            
    ###########
    # Simple print the results but could parse it from here or from 
    # each wls monitoring method (checkServer, checkCluster...)
    ###########
    print wls.GET()
        

''' WLSRest class that encapsulate the monitoring methods,
authentication and GET call  ''' 
class WLSREST():
     
    def setURL(self, url):
        self.baseURL = url
        return self
    
    def usage(self):
        print("Please check the command options and syntax")
        print("Syntax: ./WLSRESTPy.py -h [http://adminServerHost:port]
[-sacd] [parameter] -u [username] -p")
        print("For example: ./WLSRESTPy.py -h http://localhost:7001 -s     
AdminServer -u weblogic -p")
        
    def checkServer(self, server):
        return self.setURL(self.baseURL + "servers/%s" % server)
        return self
    
    def checkDataSource(self, dataSource):
        return self.setURL(self.baseURL + "datasources/%s" % dataSource)
    
    def checkApplication(self, application):
        return self.setURL(self.baseURL + "applications/%s" % application)
        
    def checkCluster(self, cluster):
        return self.setURL(self.baseURL + "clusters/%s" % cluster)
    
    def GET(self):
        # HTTP Authentication
        passman = urllib2.HTTPPasswordMgrWithdefaultRealm()
        passman.add_password(None, self.baseURL, self.username, self.password)    
        authhandler = urllib2.HTTPBasicAuthHandler(passman)
        opener = urllib2.build_opener(authhandler)
        urllib2.install_opener(opener)
        
        try:
            data = ""
            req = urllib2.Request(self.baseURL, None, {'Accept': 'application/json'})
            data = urllib2.urlopen(req).read()
            
            return data
            
        except urllib2.HTTPError, e:
            print "HTTP error: %d" % e.code
            self.usage()
            
        except urllib2.URLError, e:
            print "Network error: %s" % e.reason.args[1]
            self.usage()
            
########################################################################
if __name__ == '__main__':
    main()
簡単のため、このスクリプトにはサービス呼び出しの応答に対する特別な取り扱いをしていません。単にJSONレスポンスを出力しているだけですが、この記事の最初のPythonスクリプトの例を見て、Pythonが提供する組み込みjsonライブラリを使ったコンテンツをパースする方法を理解してもらいたいと思います。

以下にスクリプトの呼び方を例示しておきます。
コード 7 - 全てのサーバ状態を表示 (Python)
Javelin% ./WLSRESTPy.py -h http://localhost:7001 -s ''  -u weblogic -p
Password: 
{"body":{"items":[{"name":"AdminServer","state":"RUNNING","health":"HEALTH_OK"},
{"name":"managedA","state":"SHUTDOWN"},{"name":"managedB","state":"SHUTDOWN"}]},
"messages":[]

コード 8 - サーバ情報をチェック (Python)
Javelin% ./WLSRESTPy.py -h http://localhost:7001 -s 'AdminServer' -u weblogic -p
Password: 
{"body":{"item":{"name":"AdminServer","state":"RUNNING","health":"HEALTH_OK",
"clusterName":null,"currentMachine":"","weblogicVersion":"WebLogic Server 
Temporary Patch for 13340309 Thu Feb 16 18:30:21 IST 2012\nWebLogic Server 
Temporary Patch for 13019800 Mon Jan 16 16:53:54 IST 2012\nWebLogic Server 
Temporary Patch for BUG13391585 Thu Feb 02 10:18:36 IST 2012\nWebLogic Server 
Temporary Patch for 13516712 Mon Jan 30 15:09:33 IST 2012\nWebLogic Server 
Temporary Patch for BUG13641115 Tue Jan 31 11:19:13 IST 2012\nWebLogic Server 
Temporary Patch for BUG13603813 Wed Feb 15 19:34:13 IST 2012\nWebLogic Server 
Temporary Patch for 13424251 Mon Jan 30 14:32:34 IST 2012\nWebLogic Server 
Temporary Patch for 13361720 Mon Jan 30 15:24:05 IST 2012\nWebLogic Server 
Temporary Patch for BUG13421471 Wed Feb 01 11:24:18 IST 2012\nWebLogic Server 
Temporary Patch for BUG13657792 Thu Feb 23 12:57:33 IST 2012\nWebLogic Server 
12.1.1.0  Wed Dec 7 08:40:57 PST 2011 1445491 ","openSocketsCurrentCount":1,
"heapSizeCurrent":530186240,"heapFreeCurrent":
486465744,"heapSizeMax":530186240,"javaVersion":"1.6.0_33","oSName":"Mac OS X",
"oSVersion":"10.7.4"}},"messages":[]}

コード 9 - アプリケーション情報のチェック(Python/medrecアプリケーション使用)
Javelin% ./WLSRESTPy.py -h http://localhost:7001 -a medrec -u weblogic -p
Password: 
{"body":{"item":{"name":"medrec","type":"ear","state":"STATE_NEW",
"targetStates":[{"target":"myCluster","state":"STATE_NEW"},
{"target":"AdminServer","state":"STATE_FAILED"}],"dataSources":[],
"workManagers":[],"minThreadsConstraints":[],"maxThreadsConstraints":[],
"requestClasses":[]}},"messages":[]}

JavaFXクライアント
未だにJavaFXを新しい、実験的なテクノロジーと考えている人がいるようですが、Sun MicrosystemsがJavaFXを2007年にリリースしてから、携帯電話やテレビ、自動車のシステム、ブラウザ、その他のデバイスでリッチクライアントにする強力なテクノロジーのアイデアは非常に重要になってきて、このアイデアがより一層広く受け入れられてきました。JavaFXを使って様々な面を持つ複雑なアプリケーションを作成することができます。 しかし、この次の章では、RESTful管理サービスを使うOracle WebLogic Serverの簡単な監視ツールを作る予定にしています。JavaFX初心者で何がどうなっているかをざっと見てみたい場合は、JavaFX 2 Sample ShowcaseでEnsembleというアプリケーションサンプルをご覧下さい。
JavaFXの基本を説明することはこの記事の範疇外になりますので、Oracle WebLogic Server JavaFX Monitorのサンプルを、主要コンポーネントに特化して以下で説明します。

RESTクライアント
このクライアントはJerseyのcom.sun.jersey.api.client.Clientcom.sun.jersey.api.client.WebResourceというクラスで作られ、Oracle WebLogic Serverのセキュリティレルムに対してリクエストを認証します。簡単のため、アプリケーションではJSON形式のリクエストのみを扱いますが、少し修正すれば簡単にXML、HTMLで応答を返すようにできるでしょう。

コード 10 - Java RESTクライアント
// code with some parts ommited
public class WLSClient {
…

    public final void initClient() {
        final Client client = Client.create();
        client.addFilter(new HTTPBasicAuthFilter(getUsername(), getPassword()));
        this.webResource = client.resource(getEndpoint());
    }
… 
    public ClientResponse getCall(final String uriPath) {

        if (webResource == null) {
            initClient();
        }

        final ClientResponse response = 
   webResource.path(uriPath).accept(MEDIA_TYPE).get(ClientResponse.class);

        return response;
    }
…

コマンド
REST管理サービスを呼び出して、認証を行うことができたので、監視できるいくつかのクラスがあります。それは、リソースのタイプごとに1個のクラスです。プロセスは、Commandデザインパターンに従います。クライアントによっては、こうしたクラスを異なるスレッドから呼び出すことができます。全てのコマンドはjava.util.concurrent.Callableインターフェースを実装しています。これは結果を返し、例外を投げることもあるタスクを表しています。REST呼び出しから結果をパースし、その結果をJackson JSONライブラリのorg.codehaus.jackson.map.ObjectMapperクラスを使ってjava.util.Mapオブジェクトに入れるメソッドもあります。これはこの例の全てのコマンドにおけるデフォルトの動作です。

コード 11 - 他のコマンドをベースとした抽象クラス
// code with some parts omitted
public abstract class AbstractCommand implements Callable<map> {
…
    protected AbstractCommand(WLSClient client) {
        this.client = client;
        this.mapper = new ObjectMapper();
    }
… 
    public Map parseResults(final String jsonResponse) throws JSONException,
  IOException {

        Map
コード 12 - Oracle WebLogic Serverの情報を監視できるコマンドクラスの例
// imports omitted -
public class ServerCommand extends AbstractCommand {

    private String server;

    public ServerCommand(WLSClient client, String server) {
        super(client);
        this.server = server;
    }

    public Map getServerInfo() throws WebApplicationException, JSONException,
  IOException {
        setCommandPath("/servers/" + ((server != null) ? server : ""));

        Map
コマンドをjavafx.concurrent.Servicesjavafx.concurrent.Tasksに簡単に変換します。UIスレッド(JavaFX アプリケーションスレッド)を新たなユーザイベントを処理できるようにしながら、バックグラウンドスレッドでの作業をカプセル化します。

その他のアプリケーションコンポーネント
この記事の目的はREST管理サービスゆえ、このアプリケーションの他のコンポーネントについて詳細を記載することはありません。しかし、コンポーネントのソースコード(WLSMonitor.zip)は評価目的でダウンロード頂けます。
これらのコンポーネントの概要は以下の通りです。
  • GUI
    Java FX Scene Tool(こちらからダウンロードできます)を使って、Graphical User Interface (GUI)を作成しました。 JavaFXを使ってUIを作成する方法はいくつかありますが、この記事ではGUIアクションのControllerとして、FXMLファイルとJavaクラスを使います。
oliveira-wls-rest-javafx-fig05
JavaFX Scene Tool - JavaFXアプリケーションの設計
  • ワークマネージャ
    スレッドをグループ化し、サービスリクエストの実行をよりうまく分離するために、ExecutorServiceを使って複数のコマンド呼び出しを共有します。
結果を以下のスクリーンショットで確認できます。
oliveira-wls-rest-javafx-fig06
WLSFXMonitor - 構成の設定
oliveira-wls-rest-javafx-fig07
Figure 7: WLSFXMonitor - 結果タブと履歴
oliveira-wls-rest-javafx-fig08
WLSFXMonitor - サーバの状態

まとめ
Oracle WebLogic Server 12cはアプリケーションサーバの様々な局面で使える多くの機能(RESTful管理サービスやその他の最新の監視APIなど)を集約・統合しています。
APIへのRESTfulなアクセスを提供することで、アプリケーション開発者やシステム管理者が様々なツールやプログラミング言語を使って重要な情報を収集するより多くの可能性を提供します。このコンセプトを念頭に、JavaFXや他のリッチメディアを用いたモダンなアプローチを使用すると、シンプルではあるが非常に有益な、Webブラウザやスタンドアロンクライアントで実行できるアプリケーションサーバの監視アプリケーションを作ることができます。

参考資料