レベル: 初級 Christopher Vincent, Software Engineer, Internet Technology Team, IBM Server Group
2002年 11月 01日
IBM Lightweight Services (LWS) を使用すると、スクリプト開発者はWebSphereプラットフォームでのプロセス指向サービスの作成、デプロイ、およびデバッグを迅速に行うことができます。スクリプト・ベースのサービスはIBMミドルウェアと統合され、J2EEアプリケーションを拡張してインスタント・メッセージングなどの非トランザクション・リソースにアクセスできるようにします。この記事では、従来型のJ2EEアプリケーションを拡張して軽量サービスを組み込む方法を示します。著者は詳しい例を使用して、システムの各ユーザー用のエージェント・インスタンスを作成および管理する方法を示します。
このシリーズの第1回、「サーバー・サイド・スクリプト」では、LWSを紹介し、エージェント、トランザクション、拡張、ランタイム、およびアプリケーションについて説明しています。
概要
軽量サービスは、JavaScriptなどの軽量プログラム言語で開発された、長時間にわたって実行される、サーバー・サイド・プログラムです。スクリプトとの親和性の高い高水準のAPIにより、Webサービス、Sametimeインスタント・メッセージング、および高性能なPublish/Subscribeを利用できるようになります。LWSは、特に個人向けサービス の開発に適しています。個人向けサービスは、個々のユーザーに代わって動作するサーバー・サイド・アプリケーションです。このタイプのサービスはエージェント という用語で表され、エージェントのプログラム・コードの実行はエージェント・インスタンス という用語で表されます。
この記事では、従来型のJ2EEを拡張して軽量サービスを組み込み、システムの各ユーザーのエージェント・インスタンスを作成し管理する方法を示します。例として使用するサービスでは、以下の機能が示されます。
-
非同期Webサービス操作
- Webサービスの操作、特に複数の企業や組織にまたがるサービス操作では、応答または失敗が戻されるまでかなりの時間を要することがあります。LWSを使用すると、エージェントは複数の要求を同時に送信したり、ある操作が完了するのを待つ間に別のイベントを処理したりすることができます。LWSエージェントは、これを容易に行えるようにするために、非同期 APIを使用するWebサービス要求を開始して、別個のトランザクションで応答を処理します。
-
自己スケジュール
- LWSエージェントは、Entity Beanと同じように、そのプログラム状態がデータベース内に存続するため、長時間実行 されます。スクリプト・プログラムには、WebSphereコンテナーの外側で起こるイベントと独立した、それ自体の実行をスケジュールする追加機能が備わっています。この記事では、例として、ユーザーが設定した時間間隔でWebサービス操作を定期的に呼び出すエージェントを使用します。
-
非トランザクション・ミドルウェアへの管理されたアクセス
-
第1回で述べたように、LWSはトランザクション・エージェントと非トランザクション・ミドルウェア・リソースの間の対話を管理しやすくします。Lotus Sametimeを使用してユーザーにインスタント・メッセージングを送信するエージェントを作成してみたいと思います。
-
エージェント・スタイルのプログラミング
- 単純性とセキュリティーの両方を考慮して、1人の人に関する情報のみを管理するエージェント・プログラムを開発することにします。そして、サンプル・アプリケーションで各ユーザー用にこのエージェントのインスタンス を作成し、構成することにします。これは、複数ユーザーに関連するデータおよびイベントを明示的に管理するコードの開発に代わる方法です。
次のセクションでは、アプリケーション・シナリオについて説明し、新規LWSエージェントの開発およびデバッグを行い、エージェント・インスタンスを管理するためのエンタープライズ・アプリケーションを作成します。追加チュートリアル、サンプル・エージェント、およびAPI資料については、IBMのalphaWorksにあるIBM Lightweight Services を参照してください。この記事は、読者がApplication DeveloperによるJ2EEエンタープライズ・アプリケーションの開発およびテストについてよく理解していることを前提としています。この記事では、"Application Developer" はWebSphere Studio Application Developer 4.0.3のことを指します。特定のタスクについては、他のバージョンの開発環境ではこの記事の記載と異なる場合があります。
Personal Weather Serviceアプリケーション
上で概略を述べた機能を例示するために、以下の例のエージェントでは、非同期Webサービス操作を呼び出し、独自の実行をスケジュールし、Sametimeインスタント・メッセージングによって通信し、インスタンスごとの構成値を使用します。各地の最新の気温をインスタント・メッセージングで送信するオプションを備えた、Personal Weather Serviceという架空のWebアプリケーションを想定します。ユーザーは、サインオンし、郵便番号を入力し、ユーザーごとに設定された時間間隔で最新の気温が送信されるようにすることができます。図1 は、この記事で実装される、このアプリケーションのWebインターフェースを示しています。
図1. Personal Weather ServiceのWebインターフェース
Sametimeインスタント・メッセージングを使用すると、エンド・ユーザーとの直接通信を手軽に行うことができます。図2 に示すように、Sametime Connectクライアント・アプリケーションの新規メッセージ・ウィンドウとして最新の気温が表示されます。
図2. 最新気温メッセージ
このサンプル・アプリケーションは、次の4つの主要なサーバー・コンポーネントからなります。
- WebSphere Application Server
- DB2 Universal Database
- Lotus Sametime Server
- HTTPでアクセスすることのできる気温情報Webサービス
WebSphereおよびDB2は、気象情報サービス・エンタープライズ・アプリケーションとLWSの両方のホスト・サービスを行います。図3 は、これらのシステムとクライアントとの間の通信リンクを示しています。
図3. システムの概要
次の図4 は、WebSphereサーバーでホストされるコンポーネントを示しています。気象情報サービス・エンタープライズ・アプリケーションおよびLWSは、同じWebSphereインスタンスでホストされますが、別個にインストールされ、2つの異なるDB2データベースにデータを保管します。上記のWebインターフェースは、JavaServer Pages (JSP) テクノロジーを使用して実装され、Enterprise JavaBeans (EJB) Session Beanとして実装されたユーザー・マネージャー・コンポーネントを呼び出します。ユーザー・マネージャーはユーザー・プロファイル情報をEntity Beanに保管し、Javaリモート・メソッド呼び出し (RMI) を使用してLWSエージェント・マネージャーを呼び出します。HTTPを介したWebサービス要求を使用して、ユーザー・マネージャーとエージェント・マネージャーの間のアプリケーション間リンクを実装することもできますが、RMIを使用すると、2つのコンポーネントにまたがってWebSphereトランザクションを実行することができます。
エージェント・インスタンスを作成、管理、および除去するためのすべての操作は、エージェント・マネージャーSessionBeanを介して実行されます。新規ユーザーが最新気温情報サービスに登録するたびに、ユーザー・マネージャーは最新気温情報エージェントの新規インスタンスを作成し、構成します。このエージェント・インスタンスはSametimeサーバーに接続し、割り当てられたユーザーについて指定されたスケジュールに基づいて、気温情報Webサービスを呼び出します。Webサービス要求が完了すると、新しい別のインスタント・メッセージングでその結果がユーザーに送信されます。
図4. 軽量サービスを使用したWebSphereエンタープライズ・アプリケーション
次のセクションでは、WebSphere Studio Application DeveloperのWebSphere Test Environmentで稼働させるためにLWSを構成する方法について説明します。その後で、LWSパースペクティブ内でLWSエージェントを開発およびテストする方法について説明し、さらに、気象情報サービス・エンタープライズ・アプリケーションを実装します。
Application DeveloperへのLWSのインポート
軽量サービスを使用する新規J2EEアプリケーションを開発する際には、WebSphere Studio Application Developer 4.0.3に組み込まれているWebSphere Test Environment内でLWSを実行すると便利です。LWSインストール手順には、WebSphereのスタンドアロン・インスタンスにエンタープライズ・アプリケーションをインストールする方法が記載されています。このケースでは、Application Developer内で、LWSと新規気象情報サービス・アプリケーションの両方を含むサーバー構成を作成することにします。
最初に、Application DeveloperのFile/Import... コマンドを使用してLWSをワークスペースに追加します。図5 に示すように、LWSインストール・パッケージからエンタープライズ・アプリケーション・アーカイブ (EAR) ファイルを選択し、新規アプリケーション・プロジェクトにLightweightServices という名前を付けます。また、これにより、ワークスペースにいくつかの追加プロジェクト (EJB、およびエージェント・マネージャー、ランタイム、および拡張を定義するWebモジュール) が付け加えられます。
図5. LWSエンタープライズ・アプリケーションのインポート
LWSプロジェクトがワークスペースに追加された後で、アプリケーション・コードをホストするようにWebSphereTest Environmentを構成する必要があります。そのための構成ステップは、通常のインストール手順に含まれるステップそのままですが、ApplicationDeveloperサーバー・パースペクティブを使用して行われます。最初に、Create Server Instance and Configuration コマンドを使用して開始します。この新規サーバーは気象情報サービス・アプリケーションのテストに使用されるため、図6 に示すように、Personal Weather Service という名前を付け、そのプロジェクト・フォルダーとしてPersonalWeatherServiceServerを指定します。これにより、この新規サーバーは、「Server Configuration」ビューの「ServerInstances」と「Server Configurations」の両方に表示されるようになります。
図6. 新規サーバー・インスタンスおよび構成の作成
サーバー・インスタンス・エディターの「Environment」タブを使用して、false という値のシステム・プロパティーcom.ibm.ws.classloader.ejbDelegationModeを追加します。このプロパティーを使用すると、EJBモジュールは、別のバージョンが必要な場合にWebSphereクラスパス内のJavaクラスを置き換えられるようになります。
サーバー構成エディターの「General」タブを使用して、モジュール可視性をSERVERに設定します。これにより、新しい気象情報サービス・アプリケーションが、LWSアプリケーションの一部であるEJB Beanにアクセスできるようになります。
「Data source」タブを使用してLWSデータベースへのアクセスを構成する必要があります。まだこのデータベースがない場合には、LWSインストール手順に従って作成してください。すでに標準インストールされたLWSでデータベースを使用している場合には、そのアプリケーション・サーバーをシャットダウンし、WebSphere Test Environmentで同じデータベースを使用してください。
新規データ・ソースを作成する前に、DB2との通信に使用するJava Database Connectivity (JDBC) ドライバー・クラスを指定する必要があります。概要で述べたWebSphere構成には、気象情報サービス・アプリケーションとLWSの2つのエンタープライズ・アプリケーションが含まれています。それぞれのアプリケーションは固有のDB2データベースに情報を保管するため、両方にまたがって実行されるトランザクションでは2フェーズ・コミット・プロトコル が必要になります。これはデフォルトのDB2ドライバーではサポートされないため、図7 に示すように、Db2JdbcDriver を編集して、実装クラス名をCOM.ibm.db2.jdbc.DB2XADataSource に変更してください。新しく作成されたLWSデータベースにこのJTA対応DB2ドライバーを使用してアクセスする予定がある場合には、最初に、db2cliパッケージとdb2ubindパッケージをバインドしておく必要があります。詳細については、WebSphere 4.0 InfoCenterのUsing JTA Drivers を参照してください。
図7. DB2用にJDBCドライバーを再構成する
DB2ドライバーを再構成すると、図8 に示すように、エージェントおよびその関連データを保管するために必要なデータ・ソースを作成できるようになります。Java Naming and Directory Interface (JNDI) 名としてjdbc/AgentManagerを指定して、AgentManagerDataSourceという新規データ・ソースを追加してください。データベース名LWS を指定し、読者のDB2管理者ユーザーIDおよびパスワードを入力してください。
図8. LightweightServicesアプリケーション用のDB2データ・ソースの作成
最後に、LightweightServicesプロジェクトをPersonal Weather Serviceサーバー構成に追加します。ここでテスト環境を構成する必要があります。新規サーバーを開始し、LWSが正しくロードされることを確かめてください。WebSphere Test Environmentは、標準インストールされたWebSphereとは異なるデフォルト・ポートを使用します。LWS Web管理インターフェースはhttp://localhost:8080/lws/admin/web/ に存在するようになります。
LWSのパースペクティブでは、エージェントをインストールおよびデバッグするために、サーバー・ローカル・ホストおよびポート8080をここで指定する必要があります。
気温情報エージェントの開発
Application Developerに関するLWSパースペクティブでは、他のアプリケーション・コンポーネントを作成する前に、気温情報エージェントを開発し、完全にテストすることができます。エージェントが正しく機能していることを確認した後で、気温情報エージェントのインスタンスを自動的に作成、構成、および除去するEJBコンポーネントを開発することができます。
LWSパースペクティブをオープンし、図9 に示すようにTemperatureAgentという新規LWSプロジェクトを作成して、手順を開始します。
図9. 新規LWSプロジェクトの作成
図10 に示すように、Rhinoランタイムを指定してください。これは、Mozilla Rhino JavaScriptエンジンを基にしたランタイムです。これら2つのデフォルト・ランタイムには、APIに関していくつかの相違点があるため、LWS資料内のスクリプト解説の「Rhino Runtime」セクションを必ず参照してください。
図10. LWSプロジェクトの属性の指定
作成されたTemperatureAgent.amlファイルでは、エージェントおよびそのために必要なランタイム環境に関する、ほとんどの情報が示されます。図11 に示すように、エージェント・エディターはこのファイルを「Overview」タブ内に自動的にオープンします。読者はこのタブでエージェントの基本的なプロパティーを指定することができます。プロジェクトには固有のエージェントIDが自動的に割り当てられ、後で、気温情報サービス・アプリケーションからエージェントを参照するときにこのIDが使用されます。AuthorフィールドとDescriptionフィールドをカスタマイズして、サーバーでエージェントを識別しやすくしてください。
図11. エージェント・プロパティーの指定
図12 に示すように、「Extensions」タブを使用してSametime拡張とWebServices拡張を使用可能にします。これにより、対応する拡張オブジェクトが、JavaScriptプログラムの最上位プロパティーとして使用できるようになります。WebServices拡張には、クライアント・サイドとサーバー・サイドの両方の関数が含まれます。このエージェントはWebサービス・クライアントとしてのみ作動します。
図12. 拡張依存関係の追加
なんらかのJavaScriptコードを作成する前に、実行時のエージェント・インスタンスにどのような構成情報が必要になるのかを考える必要があります。値の中には、気温情報サービスと一緒に使用される郵便番号のように、ユーザーごとに設定されるものがあります。また、Sametimeログイン情報のように、気象情報サービス・エンタープライズ・アプリケーションの開発者によって設定される構成値もあります。これらの値はすべて、新規エージェント・インスタンスの作成時にユーザーが指定するインスタンス構成 XMLで表現されます。XMLがJavaScriptオブジェクトにどのように変換されるのかについては、LWS文書の中の「Configuring Agent Instances」チュートリアルを参照してください。
開発プロセスを簡素化するために、インスタンス構成XMLのデフォルト値をプロジェクトの一部として保管することができます。図12 の「Configuration」タブを使用して、リスト1 のXMLフラグメントをデフォルトのインスタンス構成として指定してください。sametime タグ内の情報を変更し、ネットワークのSametimeサーバーを指定する必要があります。また、両方のuserId タグでそのサーバーの有効なユーザーを指定するようにしてください。
リスト1. デフォルトのインスタンス構成
<configuration>
<userId>John Smith</userId>
<zipCode>02139</zipCode>
<period type="int">20000</period>
<retry type="int">20000</retry>
<sametime>
<server>localhost</server>
<userId>Temperature Agent</userId>
<password>temperatureagent</password>
</sametime>
</configuration>
|
これで、エージェントのJavaScriptソース・コードを開発するための準備が整いました。プロジェクトの一部として自動的に作成されたTemperatureAgent.jsファイルをオープンしてください。これにはすでに、LWSパースペクティブの「Instance Log」ビューに "hello world" メッセージを書き込むためのJavaScriptが含まれています。
リスト2. デフォルトのJavaScriptソース・コード
Agent.Log.writeMessage("Hello world.");
|
図13 に示されている「Install」タブを使用すると、エージェント・ソース・コードの新規バージョンをきわめて迅速にインストールおよびデバッグすることができます。デフォルトのエージェント・コードの新規インスタンスをインストールし、作成すると、「Agents」ビューに新規項目が現れ、「InstanceLog」ビューにサンプル出力が表示されるはずです。「Command Line」ビューも使いなれるようにしてください。このビューを使用すると、JavaScriptの式をサーバー・サイド・エージェント・インスタンスのスコープ内で評価することができます。コマンド行に別のAgent.Log.writeMessage 呼び出しを入力すると、その出力も「Instance Log」ビューに表示されるはずです。
図13. デフォルトJavaScriptコードのテスト
開発環境が正しく構成されたことが確認できましたので、エージェント・ソース・コードをカスタマイズすることが可能になりました。"hello world" コマンドを除去し、インスタンス構成オブジェクトおよびログ・オブジェクトにアクセスするのに便利な変数を定義してください。
リスト3. インスタンス構成およびログ
var config = Agent.configuration;
var log = Agent.Log;
|
ユーザーのエージェントは、別のサーバーでホストされる気温情報Webサービスを呼び出す必要がありますが、そのための最も簡単な方法はWebサービス記述言語 (WSDL) ファイルを利用することです。http://www.xmethods.net/sd/2001/TemperatureService.wsdl で記述された気温情報Webサービスを呼び出すことにします。
エージェントのインスタンスが有効な要求を生成するためにはこのWSDLリソースにアクセスする必要があります。この情報に対応するURLをそのまま指定することもできますが、デバッグし易くするために、このファイルをエージェントの一部として組み込んでください。ファイルをエージェント・プロジェクト・フォルダーにコピーしてください。ApplicationDeveloperの外部にファイルを作成する場合には、必ず「Refresh From Local」を実行してください。WSDLファイルがエージェントのフォルダーに入ると、「Install」タブの「Refresh」ボタンを押したときに新規項目がファイル・リストに現れるようになるはずです。
WSDLファイルをエージェントの一部として使用可能できるようになりましたので、WebServices.WSDL.createService 関数を使用してサービス・オブジェクトを作成することができます。リスト4 に示すようにgetTemperature 関数を定義してください。この関数はgetTemp 要求を作成し、zipCode パラメーターをインスタンス構成で指定された値に設定します。LWS内のすべてのWebサービスは、非同期 です。つまり、結果を処理するためにはイベント・ハンドラーを指定する必要があります。この関数の操作が完了したときには、要求が失敗した場合にも結果が戻された場合にも、onGetTemperatureComplete 関数が呼び出されます。さしあたり、インスタンス・ログに結果書き込むだけにしておきます。
リスト4. WSDLを使用してWebサービスを呼び出す
var temperatureService =
WebServices.WSDL.createService("TemperatureService.wsdl");
function getTemperature() {
var request = temperatureService.createRequest("getTemp");
request.body.zipcode = config.zipCode;
request.onComplete = onGetTemperatureComplete;
log.writeMessage("Calling temperature service...");
request.call();
}
function onGetTemperatureComplete(response) {
if (response.failed) {
log.writeError("Call to temperature service failed. " + response.error);
return;
}
var temperature = response.result.value;
log.writeMessage("Temperature service returned " + temperature + ".");
}
|
「Install」ボタン (図13) を使用してエージェントを再インストールし、新規エージェント・インスタンスを作成します。「Remove all instances before install」チェック・ボックスをオンにし、すでに作成したインスタンスを除去するようにしてください。「CommandLine」ビューでgetTemperature() と入力してリターン・キーを押し、Webサービスを手動で呼び出してください。呼び出しの結果が「Instance Log」ビューに表示されます。
基本的なWebサービス呼び出しのテストが終了した後で、JavaScriptコードを追加して、Sametimeインスタント・メッセージ・サーバーと統合することができます。リスト5 に示すソース・コードは、新規の最上位JavaScriptプロパティー "session" を作成し、それを新規Sametimeセッション・オブジェクトに設定しています。このセッションには、ログイン試行をモニターするために使用される2つのイベント・ハンドラーが割り当てられ、login 呼び出しにより、インスタンス構成XMLで提供された情報を使用して新規接続が行われます。
リスト5. Sametimeインスタント・メッセージとの統合
log.writeMessage("Connecting to Sametime server...");
var session = new Sametime.Session();
session.onLogin = onLogin;
session.onLoginFailed = onLoginFailed;
session.login(
config.sametime.server,
config.sametime.userId,
config.sametime.password,
true);
function onLogin(session, reconnect) {
log.writeMessage("Logged in to Sametime server.");
}
function onLoginFailed(session, reasonCode, description) {
log.writeError("Sametime login failed. " + description);
}
|
別の新規エージェント・インスタンスを作成すると、そのインスタンスはただちにSametimeサーバーへのアクセスを試みます。onLogin またはonLoginFailed イベントのメッセージ出力が「Instance Log」ビューに表示されます。エージェント・インスタンスが正常にSametimeに接続されると、「CommandLine」ビューを使用してセッション・プロパティーにアクセスし、ユーザーにメッセージを送信できるようになります。例えば、SametimeConnectクライアントを使用してJohn Smithとしてログインした場合、次のようなコマンドが読者のエージェント・インスタンスのスコープ内で評価されることになります。
? session.sendText("John Smith", "This is a test.")
|
Sametime接続は、WebSphereサーバーが再始動されると有効ではなくなりますので、注意してください。エージェント・インスタンスは、Sametimeセッション・オブジェクトへの参照を維持しますが、それらのオブジェクトに対するネットワーク操作を試みても、初期段階で失敗してしまいます。LWSでは、エージェント・インスタンスがこのタイプの非永続 リソースを復元できるように、Agent.onResume イベントが用意されています。Sametimeセッションの場合には、引数なしでlogin 関数を呼び出すだけで済みます。セッション・オブジェクトは、同じサーバー、ユーザーID、パスワード、およびイベント・ハンドラー情報を使用して、新規インスタント・メッセージ接続を行います。
リスト6. サーバー再始動の処理
Agent.onResume = onResume;
function onResume() {
session.login();
}
|
Webサービス要求と基本的なSametime接続の両方のテストを行った後で、getTemp 操作の結果を、インスタンス構成で指定されたSametimeユーザーに自動的に送信することができます。今回のgetTemperature 関数では、最上位のセッション・プロパティーがアクティブなSametime接続に設定されていることが想定されています。
リスト7. Webサービス応答をSametimeメッセージとして送信する
function onGetTemperatureComplete(response) {
if (response.failed) {
log.writeError("Call to temperature service failed. " + response.error);
return;
}
var temperature = response.result.value;
log.writeMessage("Temperature service returned " + temperature + ".");
session.sendText(
config.userId,
"The current temperature is " + temperature + "º F.");
}
|
getTemperature 関数がWebサービスを呼び出して、その結果をSametimeメッセージとして送信するようになりましたので、この関数をスケジュールに基づいて呼び出すことが可能になりました。初めに、"timer" という新しい最上位JavaScriptプロパティーを、最初はnull に設定して定義します。エージェント・インスタンスがSametimeに正常にログインされてから、最初のWebサービス要求を開始します。onLogin 関数は、login 関数の最後のパラメーターでtrue を指定することによって要求された自動再接続の結果として、複数回呼び出される可能性があります。
タイマー・オブジェクトが存在しない場合に新規タイマー・オブジェクトを作成する文節を、onLogin イベント・ハンドラーに追加してください。タイマーは、永続的 ですので、WebSphereサーバーが再始動された後も有効なままになります。まだタイマーを開始したくないかもしれませんが、タイマーのイベント・ハンドラーとしてgetTemperature 関数を設定し、最初の気温情報要求をすぐに開始してください。onGetTemperatureComplete 関数への最初の呼び出しにより、タイマーが開始され、Webサービス要求のサイクルが開始されます。要求が失敗した場合には、retry インスタンス構成エレメントで指定されたミリ秒単位の数値を使用して、getTemperature への次回の呼び出しがスケジュールされます。要求が成功した場合には、period 構成エレメントで指定されたとおりに次回の呼び出しがスケジュールされます。
リスト8. タイマー・オブジェクトによる要求のスケジューリング
var timer = null;
function onLogin(session, reconnect) {
log.writeMessage("Logged in to Sametime server.");
if (timer == null) {
timer = new Agent.Timer(getTemperature);
getTemperature();
}
}
function onGetTemperatureComplete(response) {
if (response.failed) {
timer.start(config.retry);
log.writeError("Call to temperature service failed. " + response.error);
return;
}
timer.start(config.period);
var temperature = response.result.value;
log.writeMessage("Temperature service returned " + temperature + ".");
session.sendText(
config.userId,
"The current temperature is " + temperature + "º F.");
}
|
これで、完全な機能をもったエージェントが完成しました。このエージェントのインスタンス化およびデバッグは、LWSパースペクティブから行うことができます。次のステップでは、郵便番号などのユーザー・プリファレンスを追跡し、そのための新規エージェント・インスタンスを自動的に作成する、新規エンタープライズ・アプリケーションを作成します。
エンタープライズ・アプリケーションの開発
図14 に示すように、Application DeveloperのJ2EEパースペクティブ内で、PersonalWeatherServiceと呼ばれる新規エンタープライズ・アプリケーションの作成を開始します。このプロセスでは、対応するEJBおよびWebプロジェクトも作成されます。後で、これらのプロジェクトにEJBとJSPWebインターフェースが入ります。アプリケーションの開発とテストを徐々にやっていくために、最初にUserProfileEntity Beanを定義し、次にUserManager Session Beanを追加し、最後に、エンド・ユーザーにアクセスするためのJSPファイルを定義します。
図14. 新規エンタープライズ・アプリケーション・ダイアログ
図15 は、J2EEパースペクティブにおけるUserProfile Entity Beanの作成を示しています。このBeanの永続的フィールドには、読者がユーザーごとに指定しようとしているエージェント・インスタンスの構成データが保管されます。各ユーザーは、自分の郵便番号、および気温情報の更新間隔 (period) を指定することができ、固有フィールドuserId はそのユーザーのSametime IDと同じであるものと想定されます。それぞれのユーザーごとに作成されたエージェント・インスタンスを追跡するためには、instanceGroupId フィールドとinstanceId フィールドを使用します。
図15. UserProfile Entity Beanの作成
J2EEパースペクティブを使用して、Entity Bean用のUserProfileData という「データ・クラス」アクセスBeanを作成してください。リモート・メソッドがEntity Beanへの参照を戻した場合、そのクライアントは、検索したいプロパティーごとにJava RMI呼び出しを行う必要があります。データ・クラスを使用すると、ユーザー・プロファイル情報のコピーをアプリケーション・コンポーネント間でやり取りして、すべてのEntity Beanのフィールドを1回の呼び出しで読み取ったり更新したりすることができます。Application Developerは、UserProfileFactory という新規Javaクラスも作成します。このクラスを使用すると、UserProfileインスタンスの作成および検索を単純化することができます。
UserProfile Entity BeanのインスタンスはDB2に保管されるため、リレーショナル・データベース(RDB) をマッピングするためのEJBを作成する必要があります。図16 に示すように、ターゲット・データベースDB2 UDB V7.2、データベース名WEATHER、およびスキーマ名USERPROFILEを指定してください。このプロセスでは、データベース定義言語(DDL) ファイルも生成されます。このファイルは、必要なデータベース・テーブルの設定に利用されます。
図16. EJBからRDBへのマッピングの作成
デプロイおよびRMICコードを生成した後で、対応するDB2を作成し、WebSphereテスト環境でBeanをテストすることができます。リスト9 は、WEATHERデータベースを作成するDB2コマンド・ウィンドウ・セッションを示しています。新規データベースを初期化するために、前のステップで生成したTable.ddlファイルをロードしていることに注意してください。また、ローカルでインストールされているDB2の正しいパスが、バインド・コマンドに含まれていることを確認してください。このプロセスは、バッチ・ファイルまたはシェル・スクリプトを使用して自動化することができます。
リスト9. DB2コマンド・ウィンドウ
C:\PROGRA~1\IBM\SQLLIB\BIN>db2 ATTACH TO DB2 USER DB2ADMIN
Enter current password for DB2ADMIN:
Instance Attachment Information
Instance server = DB2/NT 7.2.4
Authorization ID = DB2ADMIN
Local instance alias = DB2
C:\PROGRA~1\IBM\SQLLIB\BIN>db2 CREATE DATABASE WEATHER
DB20000I The CREATE DATABASE command completed successfully.
C:\PROGRA~1\IBM\SQLLIB\BIN>db2 CONNECT TO WEATHER USER DB2ADMIN
Enter current password for DB2ADMIN:
Database Connection Information
Database server = DB2/NT 7.2.4
SQL authorization ID = DB2ADMIN
Local database alias = WEATHER
C:\PROGRA~1\IBM\SQLLIB\BIN>db2 -t -f"C:\Program Files\IBM\
Application Developer\workspace\PersonalWeatherServiceEJB\ejbModule\
META-INF\Table.ddl"
DB20000I The SQL command completed successfully.
DB20000I The SQL command completed successfully.
DB20000I The SQL command completed successfully.
C:\PROGRA~1\IBM\SQLLIB\BIN>db2 BIND C:\Progra~1\SQLLIB\bnd\@db2cli.lst
LINE MESSAGES FOR db2cli.lst
------ --------------------------------------------------------------------
SQL0061W The binder is in progress.
SQL0091N Binding was ended with "0" errors and "0" warnings.
C:\PROGRA~1\IBM\SQLLIB\BIN>db2 BIND C:\Progra~1\SQLLIB\bnd\@db2ubind.lst
LINE MESSAGES FOR db2ubind.lst
------ --------------------------------------------------------------------
SQL0061W The binder is in progress.
LINE MESSAGES FOR db2clpnc.bnd
------ --------------------------------------------------------------------
SQL0595W Isolation level "NC" has been escalated to "UR".
SQLSTATE=01526
LINE MESSAGES FOR db2arxnc.bnd
------ --------------------------------------------------------------------
SQL0595W Isolation level "NC" has been escalated to "UR".
SQLSTATE=01526
LINE MESSAGES FOR db2ubind.lst
------ --------------------------------------------------------------------
SQL0091N Binding was ended with "0" errors and "2" warnings.
C:\PROGRA~1\IBM\SQLLIB\BIN>db2 DISCONNECT CURRENT
DB20000I The SQL DISCONNECT command completed successfully.
|
サーバーでEntity Beanをテストするためには、そのBeanを新規データ・ソースにバインドする必要があります。サーバー・パースペクティブで、サービス構成エディターを使用してPersonal Weather Service をオープンし、Weatherという名前の別のDB2データ・ソースを作成してください。JNDI名としてjdbc/Weather を、また、データベース名としてWEATHER (これは、上記で作成したものです) を指定し、読者のDB2管理者ユーザーIDおよびパスワードを指定してください。
図17. PersonalWeatherServiceアプリケーション用のDB2データ・ソースの作成
J2EEパースペクティブで、EJB拡張エディターを使用してPersonalWeatherServiceEJB モジュールをオープンします。「Bindings」タブを使用して、デフォルト・データ・ソースのJNDI名をjdbc/Weather に設定します。
これで、PersonalWeatherServiceプロジェクトをPersonal Weather Serviceサーバー構成に追加して、WebSphereTest Environmentテスト環境を開始する準備ができました。サーバーがエラーなしで開始されることを確認し、EJBテスト・クライアントを立ち上げてください。JNDIエクスプローラーを使用してUserProfileHomeの入り口まで行きます。このUserProfileHomeを使用することにより、新規EntityBeanのインスタンスを作成、変更、および検索することができます。
図18. EJBテスト・クライアント内でのUserProfileの作成
UserProfile Entity Beanをテストした後で、図19 に示すようにUserManager Session Beanの開発に進むことができます。このコンポーネントは、ユーザー・プロファイル情報を管理し、また、LWSエージェント・マネージャーを呼び出して気温情報エージェントのインスタンスを作成および破棄します。
図19. UserManager Session Beanの作成
新規Session Bean用にリスト10 のリモート・インターフェースを定義します。これにより、JSPインターフェースがユーザー・プロファイルを検索したり更新したりできるようになります。実際のEntity Beanに対してリモート参照を使用するのではなく、UserProfileData クラスを使用してください。このようにすると、1回のJava RMI呼び出しでユーザー・プロファイル情報の完全なコピーを受け渡すことができます。また、アプリケーション・レベルのエラーをJSPコンポーネントに戻すために、UserManagerException という基本例外クラスを定義してください。
リスト10. UserManager Session Bean用のリモート・インターフェース
public interface UserManager extends EJBObject {
public UserProfileData getUserProfile(String userId)
throws RemoteException, UserManagerException;
public void updateUserProfile(UserProfileData profileData)
throws RemoteException, UserManagerException;
}
|
Session Beanを実装する前に、PersonalWeatherServiceEJBプロジェクトのためのJavaビルド・パスを変更する必要があります。前のステップでサーバー可視性をSERVERに設定してあるため、読者のコードがWebSphere内で実行されるときに、必要なすべてのクラスが使用可能になります。ただし、J2EEパースペクティブで作業を行うときには、必要なクラスのうちのいくつかをコンパイル時のクラスパスに明示的に追加する必要があります。
エージェント・マネージャーを呼び出すためには、LWSエンタープライズ・アプリケーションの一部としてインポートされたAgentManagerEJBプロジェクト内のクラスにアクセスする必要があります。通常は、Javaビルド・パス・エディターの「Projects」タブ内でリンクを作成することになりますが、Application DeveloperにEJBモジュールをインポートしても、EJBプロジェクトの通常のファイル構造は再作成されません。その代わりに、インポートされたクラスが単一のJARファイル内に集められます。図20 に示すように、「Libraries」タブで「Add JARs...」コマンドを選択して、/AgentManagerEJB/AgentManagerEJB.imported_classes.jarを指定する必要があります。
図20. インポートしたEJBモジュールをJavaビルド・パスに追加する
インスタンス構成XMLを作成するためのXercesも必要になります。Xercesは、WebSphereで稼動しているすべてのエンタープライズ・アプリケーションで使用することができますが、Application Developerコンパイル時環境に追加する必要があります。Javaビルド・パス・エディターの「Libraries」タブで、「Add Variable...」コマンドを選択してください。図21 で示すように、lib/xerces.jarというパスを指定してWAS_PLUGINDIR変数を使用し、Xerces APIを使用可能にしてください。
図21. Javaビルド・パスへのWebSphereライブラリーの追加
これで、UserManagerBean.javaファイルにgetUserProfile およびupdateUserProfile を実装する準備が整いました。まず最初に、トレース・ロガーを作成して、JRasメッセージ・ロギングへのアクセスを構成する必要があります。これにより、デバッグのための例外情報を、設定変更可能で便利な方法で捕そくすることができます。
リスト11. JRasトレース・ロガーの定義
static final RASTraceLogger traceLogger;
static {
Manager manager = Manager.getManager();
traceLogger =
manager.createRASTraceLogger(
"IBM",
"Lightweight Services",
"WeatherTutorial",
UserManagerBean.class.getName());
manager.addLoggerToGroup(traceLogger, "LWS_WeatherTutorial");
}
|
UserManager クライアントの実装を単純化するために、getUserProfile メソッドを定義して、指定されたユーザーが見付からない場合に新規UserProfile が自動的に作成されるようにしてください。ユーザー・プロファイルのフィールドではまだどのようなデフォルト値も指定していませんので、クライアントは、ヌルの郵便番号を「未指定」、ゼロの期間値を「更新不可」、またヌルのインスタンス・グループIDを「アクティブなエージェント・インスタンスなし」と解釈するようになっています。
このサンプル・コードでは、すべての例外を捕そくする、単一の例外ハンドラーのみが提供されています。実際には、それぞれの例外を明示的に捕そくし、スローされるUserManagerException に関する詳細なメッセージを提供する必要があります。このサンプル・コードは特定の例外情報をトレース・ログに出力します。新規Session Beanをデバッグするときには、このトレース・ログを使用可能にしてください。
リスト12. getUserProfileの実装
public UserProfileData getUserProfile(String userId)
throws UserManagerException {
try {
UserProfile profile = null;
UserProfileFactory factory = new UserProfileFactory();
try {
profile = factory.findByPrimaryKey(userId);
} catch (FinderException e) {
profile = factory.create(userId);
}
return profile.getUserProfileData();
} catch (Exception e) {
traceLogger.exception(RASITraceEvent.TYPE_ERROR_EXC, this, "getUserProfile", e);
throw new UserManagerException("Failed to get user profile.");
}
}
|
updateUserProfile メソッドでは、エージェント・インスタンスを作成および除去するためにLWSエージェント・マネージャーを呼び出します。エージェント・インスタンスを作成するときには、JavaScriptコードをカスタマイズするために必要なインスタンス構成を生成するための手段が必要になります。LWSパースペクティブで作業を行ったときに、気温情報エージェントをデバッグするためのデフォルトXMLフラグメントを定義しました。読者のエンタープライズ・アプリケーションでは、それぞれのユーザーに対応する構成情報を指定する必要があります。情報の中には、(郵便番号や期間のように) ユーザーごとに指定されるものと、(Sametimeログイン情報のように) EJBデプロイメントの一環として定義されるものがあります。EJBエディターの「Environment」タブで、UserManager Beanのために以下の環境項目を定義してください。
リスト13. UserManager Session Bean用の環境項目
| 名前 | タイプ | 値 |
|---|
| Instance Group ID | String | PersonalWeatherService | | Temperature Agent ID | String | 読者のエージェントID (例えば、"600DAA62C8C1001613D1CBCCE0E564B6") | | Sametime Server | String | Sametimeサーバーのホスト名 (例えば、"localhost") | | Agent User ID | String | Temperature Agent | | Agent Password | String | 気温情報エージェントのSametimeパスワード (例えば、"mypasswd") | | Retry | Integer | 30000 (30秒) |
createConfigXML メソッドは、これらの環境項目とユーザーごとの構成値を組み合わせて、エージェントの実装に必要なすべての構成データが指定されたXMLフラグメントを生成します。これにより、読者は、LWSに組み込まれているユーティリティー・メソッドを使用して文書を文字列にシリアライズすることができます。
リスト14. インスタンス構成XMLの作成
String createConfigXML(UserProfile profile) throws Exception {
Context environment = (Context) (new InitialContext()).lookup("java:comp/env");
String sametimeServer = (String) environment.lookup("Sametime Server");
String userId = (String) environment.lookup("Agent User ID");
String password = (String) environment.lookup("Agent Password");
Integer retry = (Integer) environment.lookup("Retry");
Document document = new DocumentImpl();
Element configElement = document.createElement("configuration");
document.appendChild(configElement);
Element element = document.createElement("userId");
element.appendChild(document.createTextNode((String) profile.getPrimaryKey()));
configElement.appendChild(element);
...
return com.ibm.lws.server.Utility.serializeNode(configElement);
}
|
createTemperatureAgent という別のヘルパー・メソッドで、AgentManager Session Beanへの参照を獲得し、気温情報エージェントの新規インスタンスを作成します。カスタム・インスタンス・グループIDを使用すると、LWS管理インターフェース内でエージェント・インスタンスをグループ化するのに便利です。このグループIDとインスタンスIDをユーザー・プロファイルに保管することにより、後でそのインスタンスを見付けて除去できるようになります。
リスト15. 気温情報エージェントのインスタンスの作成
void createTemperatureAgent(UserProfile profile) throws Exception {
AgentManager agentManager = (new AgentManagerFactory()).create();
String configXML = createConfigXML(profile);
Context environment = (Context) (new InitialContext()).lookup("java:comp/env");
String temperatureAgentId = (String) environment.lookup("Temperature Agent ID");
String instanceGroupId = (String) environment.lookup("Instance Group ID");
int instanceId =
agentManager.createAndStartInstance(
temperatureAgentId,
instanceGroupId,
configXML);
profile.setInstanceGroupId(instanceGroupId);
profile.setInstanceId(instanceId);
}
|
updateUserProfile メソッドは、前にgetUserProfile を使用して検索したユーザー・プロファイル・データを受け入れ、気温情報エージェントの対応するインスタンスの除去または作成 (あるいはその両方) を行います。単純化するために、前のバージョンのユーザー・プロファイルで作成されたすべてのエージェント・インスタンスが廃止されているものと想定します。このようなインスタンスが存在する場合には、エージェント・マネージャーへの参照を獲得してそれを除去してください。その後で、更新が可能な場合 (期間の値がゼロよりも大きい場合) には、データ・オブジェクトの内容を使用して実際のユーザー・プロファイル・インスタンスを更新し、新規エージェント・インスタンスを作成してください。
setRollbackOnly は、なんらかの例外が発生した場合に現行トランザクションを差し止めるために呼び出されます。ユーザーが捕そくするのは、EJBコンテナーおよびエージェント・マネージャーによってスローされたアプリケーション・レベルの例外ですので、これは重要です。例えば、あるエージェントの実装がインスタンス初期化中にJavaScriptエラーをスローした場合、ユーザーのプロファイルに対して加えられた変更はデータベースにコミットされません。
リスト16. updateUserProfileの実装
public void updateUserProfile(UserProfileData profileData)
throws UserManagerException {
try {
String userId = (String) profileData.getPrimaryKey();
UserProfile profile = (new UserProfileFactory()).findByPrimaryKey(userId);
String instanceGroupId = profile.getInstanceGroupId();
if (instanceGroupId != null) {
try {
AgentManager agentManager = (new AgentManagerFactory()).create();
agentManager.removeInstance(instanceGroupId, profile.getInstanceId());
} catch (AgentManagerException e) {
profileData.setInstanceGroupId(null);
}
}
profile.setUserProfileData(profileData);
if (profileData.getPeriod() != 0) {
createTemperatureAgent(profile);
}
} catch (Exception e) {
mySessionCtx.setRollbackOnly();
traceLogger.exception(
RASITraceEvent.TYPE_ERROR_EXC,
this,
"updateUserProfile",
e);
throw new UserManagerException("Failed to update user profile.");
}
|
EJBエディターでPersonalWeatherServiceEJBをオープンし、「Transaction」タブまで行きます。すべてのユーザー・マネージャー・メソッドのトランザクション・タイプを「Required」に設定して、データベース・アクセスがWebSphereトランザクションの有効範囲内で行われるようにしてください。さらに、EJB拡張エディターの「Methods」タブでデータベース・アクセスを指定する必要があります。UserManager Beanについては、すべてのメソッドの分離レベルをSERIALIZABLE(これが最も無難な設定値です) に設定してください。UserProfile Beanについては、すべてのメソッドのアクセス意図をUPDATEに、また分離レベルをSERIALIZABLEに設定してください。このアクセス意図設定値を指定すると、ロックの頻発による潜在的なDB2デッドロックを避けることができます。デプロイおよびRMICコードを生成した後で、サーバーで新規SessionBeanをテストすることができます。
アプリケーションがJRasに出力した情報を見るためには、トレース・サービスを使用可能にする必要があります。サーバー構成エディターの「Trace」タブを使用してトレースを使用可能にし、トレース・ストリングをcom.ibm.lws.doc.tutorial.personalweather.*=all=enabled に設定してください。WebSphereテスト環境が開始されると、トレース出力がWSAD_HOME\workspace\.metadata\.plugins\com.ibm.etools.websphere.tools\logs\trace.logファイルに表示されます。
サーバーを開始し、EJBテスト・クライアントを使用してユーザー・マネージャーのインスタンスを獲得します。ユーザー・プロファイルを入手し、郵便番号と期間の値を設定し、そのユーザー・プロファイルを更新して新規エージェント・インスタンスを作成してみてください。LWS管理インターフェースのInstances ページを使用して、作成されたエージェント・インスタンスをモニターしてください。「Instances」ページからインスタンス・ログ (これは、LWSパースペクティブのログに似ています) をオープンすると、デバッグ・メッセージをモニターすることができ、さらに、JavaScriptエラーが発生した場合にはそれらのエラーもモニターすることができます。
JSP Webインターフェースの作成
アプリケーションの最後のコンポーネントは、個々のユーザーのためにユーザー・マネージャーを呼び出すJSP Webインターフェースです。単純化するために、サインイン、プロファイル・エディター、および応答ページとして機能する、単一のJSPファイルを作成することができます。ユーザーIDをセッション属性として保管する、フォーム・ベースのサインイン・プロシージャー (さしあたり、パスワード・フィールドは無視することにします) を使用します。
最初に、ユーザー・マネージャー・ホームへの参照を獲得し、ユーザー・マネージャーSession Beanへの参照を作成します。JSPコンポーネントとユーザー・プロファイルまたはエージェント・インスタンスとの唯一の対話は、このBeanのリモート・インターフェースのメソッドを使用して行われます。JSPコンポーネントをコンパイルするためには、com.ibm.lws.doc.tutorial.personalweatherパッケージをインポートし、Webプロジェクトのモジュール依存関係を編集してPersonalWeatherServiceEJBを組み込む必要があります。
リスト17. UserManager Session Beanの獲得
InitialContext initialContext = new InitialContext();
Object homeObject =
initialContext.lookup(
"ejb/com/ibm/lws/doc/tutorial/personalweather/UserManagerHome");
UserManagerHome home =
(UserManagerHome) PortableRemoteObject.narrow(
homeObject,
UserManagerHome.class);
UserManager userManager = home.create();
|
サポートする必要のあるすべての操作 (ログイン、ユーザー・プロファイルの更新、およびログアウト) を、単一のコード・ブロックで扱うように定義することができます。ページの残りの部分では、既存のプロファイル・データが記入されたフォームの生成、またはログイン・フォームの生成 (userId が設定されていない場合) のみを行う必要があります。JSPコードの残りの部分については、組み込まれているプロジェクト・ファイルを参照してください。
リスト18. JSPフォームの処理
String userId = (String) session.getAttribute("userId");
String action = request.getParameter("action");
if (action != null) {
if (action.equalsIgnoreCase("login")) {
userId = request.getParameter("userId");
if (userId.length() == 0) {
userId = null;
}
session.setAttribute("userId", userId);
} else if (action.equalsIgnoreCase("update") &&
request.getMethod().equalsIgnoreCase("POST")) {
UserProfileData profileData = userManager.getUserProfile(userId);
profileData.setZipCode(request.getParameter("zipCode"));
if (request.getParameter("enable") != null) {
profileData.setPeriod(Integer.parseInt(request.getParameter("period")));
} else {
profileData.setPeriod(0);
}
userManager.updateUserProfile(profileData);
} else if (action.equalsIgnoreCase("logout")) {
session.removeAttribute("userId");
userId = null;
}
}
|
JSPインターフェースが定義されましたので、これで、軽量サービスを含む完全なエンドツーエンドのエンタープライズ・アプリケーションが出来上がりました。ユーザー・マネージャーで作成されたエージェント・インスタンスも、LWS管理インターフェースを使用してモニターすることができます。サーバーを開始し、Sametimeにログインし、JSPインターフェースを使用してhttp://localhost:8080/PersonalWeatherServiceWeb/ にある気温情報の更新を構成してください。
複数の異なるユーザーについて、それぞれ別の更新プリファレンスを指定してユーザー・プロファイルを作成してみてください。
追加演習
以上で、基本的なサンプル・アプリケーションを使用して、IBM Lightweight ServicesによってJ2EEアプリケーションを拡張する方法を紹介しました。このセクションでは、ユーザーに試していただきたいいくつかの代替手段または追加機能について、概略を示します。
-
結果の集計
- LWSを使用すると、新しい永続的JavaScriptプロパティーを簡単に追加することができます。1つまたは複数のWebサービスの結果を保管し、その情報を使用して新規の気温更新内容を "The temperature is 80º F, today's average is 78º F." のように拡張することができます。
-
エージェント・インスタンスの保存
- 単純化するために、サンプル・アプリケーションでは、再構成が必要なときにはユーザーの既存エージェント・インスタンスを除去するようにしてあります。Webサービスを使用して既存のエージェント・インスタンスを再構成するようにしたほうが実用的です。Webサービス操作
setZipCode およびsetPeriod をエージェントに追加し、ユーザー・マネージャーSession Beanからこれらの操作を呼び出すことができます。また、ユーザー・プロファイルEntity Beanから郵便番号と期間を除去し、追加のWebサービス操作を使用して既存のエージェント・インスタンスからこれらの情報を取り出すようにすることもできます。
-
ユーザー状況のトラッキング
- 気温情報エージェントは、Webサービス操作が完了したときに更新メッセージの送信を試みます。私たちのサンプル・アプリケーションでは、ターゲット・ユーザーが実際にオンラインになっているかどうか、あるいはメッセージの送信が成功したかどうかを判別していません。セッション・オブジェクトの
addUsers 関数と、それに対応するonUserStatusChanged イベントを使用して、ユーザーがオンラインになっていてインスタント・メッセージが利用可能なときを追跡してください。ユーザーが結果を受信できないときにはエージェントがWebサービス呼び出しを遅らせるようにすることもできます。onImOpenFailed イベントを処理して、メッセージ送信が失敗したときに通知を送るようにしてください。
-
Publish/Subscribeの使用
- 決められたスケジュールに基づいて気温情報Webサービスを呼び出す代わりに、DistHub拡張を使用して気温データ配布サービスに加入することもできます。このようにすると、気温が5度以上変化したときに毎回更新データを送信させるなど、よりインテリジェントな警報を効果的にプログラミングすることができます。
-
代替警報メカニズムの使用
- この例では、更新内容をSametimeインスタント・メッセージで送信するようにしました。これは、エンド・ユーザーと直接通信するための比較的単純な方法であるためです。同じ警報を、ページャー・ゲートウェイまたはEメール・サーバー用のWebサービス・インターフェースを呼び出すことによって送信することもできます。
-
エージェント・マネージャーWebサービスの呼び出し
- サンプル・アプリケーションでは、エージェント・マネージャーとエンタープライズ・アプリケーションを同じWebSphereのデプロイメントで実行しました。Java RMIを使用してエージェント・マネージャーを呼び出すと、エージェント・インスタンスを作成および除去するときに分散トランザクションを使用することができます。エージェント・マネージャーはWebサービスとして利用することもできます。分散アプリケーションまたは企業間アプリケーションには、このほうが適切であると思われます。

 |
まとめ
この記事では、IBM Lightweight Servicesを使用してJ2EEアプリケーションを拡張し、非同期Webサービス、自己スケジューリング、およびSametimeインスタント・メッセージを組み込みました。かなり複雑な工程を、構成可能なエージェントを使用して、50行足らずのJavaScriptコードで実装することができました。軽量サービスを使用することにより、複雑な工程、一連のWebサービス操作の管理、個々のユーザーとのやりとりを協調させることが可能であることが、この単純なサンプルでお示しできたのではないかと思います。よく尋ねられる質問、スクリプトのチュートリアル、およびサンプル・エージェントについては、IBMのalphaWorksサイトにあるIBM Lightweight Services を参照してください。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| i-lws2.zip | i-lws2.zip | 105KB | HTTP |
|---|
参考文献
著者について  | |  | Christopher Vincent氏は、IBM Server Group、インターネット・テクノロジー・チームのソフトウェア・エンジニアです。Vincent氏の研究対象は、インスタント・メッセージング、Publish/Subscribeインフラストラクチャー、RAD(迅速なアプリケーション開発)、およびプログラミング・プログラム言語などです。氏はマサチューセッツ工科大学 (MIT) で工学修士および理学学士の学位を取得しており、同大学の人工知能研究所に在籍していました。 |
記事の評価
|