アダプタの開発
![]() |
![]() |
![]() |
![]() |
イベント接続では、EIS から WebLogic Integration 環境に情報を伝播します。そのため、イベント接続は情報のパブリッシャと呼ばれます。
WebLogic Integration のすべてのイベント接続では、以下の機能が実行されます。
WebLogic Integration では、すべてのイベント接続に共通する最初の 3 つの機能を実装し、開発者がアダプタの EIS 固有の機能に専念できます。WebLogic Integration では、任意に使用できる 4 つの機能にフレームワーク サポートを提供しますが、これらの機能を直接実装できません。
実行時環境でのイベントの動作を、図 7-1 に示します。
図 7-2 は、イベント接続の開発手順の概要です。
開発を開始する前に、イベント接続の要件を定義する必要があります。そのために必要な情報の完全なリストについては、「アダプタ設定ワークシート」を参照してください。この節では、手順 1 に重要なタスクの概要を説明します。
この手順では 5 つの作業を行い、コンピュータでアダプタ開発を行う準備をします。
イベント接続の開発環境に必要なファイル構造は、サービス接続の開発に必要な構造と同じです。詳細については、「サービス アダプタの開発」の「手順 2a : ディレクトリ構造の設定」を参照してください。
使用するアダプタに論理名を割り当てます。通常は、ベンダ名、アダプタに接続する EIS のタイプ、EIS のバージョン番号を並べて「ベンダ名_EIS のタイプ_EIS のバージョン」のように指定します。たとえば、以下のようになります。
WebLogic Integration では、100% Pure Java ベースのビルド ツールである Ant をベースとするビルド プロセスが採用されます。Ant の機能の詳細については、「Ant ベースのビルド プロセス」を参照してください。Ant の使用方法の詳細については、以下を参照してください。
http://jakarta.apache.org/ant/index.html
WebLogic Integration に付属のサンプル アダプタには、以下の場所に Ant ビルド ファイルが用意されています。WLI_HOME
/adapters/sample/project/build.xml
。このファイルには、J2EE 準拠アダプタのビルドに必要なタスクが指定されています。GenerateAdapterTemplate
ユーティリティを実行してアダプタの開発ツリーのクローンを作成すると、そのアダプタ専用の build.xml
が作成されます。このファイルは自動的に生成されるため、サンプルの build.xml
ファイルをカスタマイズする必要はなく、コードに問題はありません。GenerateAdapterTemplate
ユーティリティの使用方法の詳細については、「カスタム開発環境の作成」を参照してください。
構築プロセスの詳細については、「サービス アダプタの開発」の「手順 2c : ビルド プロセスの設定」を参照してください。
エンドユーザ向けに設計されたあらゆるメッセージは、メッセージ バンドル、つまりメッセージのインターナショナライズを可能にする key=value
の組み合わせを含む .properties
テキスト ファイルに配置する必要があります。実行時に地理的ロケールと地域言語が指定されると、メッセージの内容が key
=
value
組み合わせに基づいて解釈され、メッセージが指定された言語で表示されます。
メッセージ バンドルの作成方法の詳細については、以下のサイトの JavaSoft チュートリアルでインターナショナライゼーションについて参照してください。
http://java.sun.com/docs/books/tutorial/i18n/index.html
ロギングは、Apache Jakarta プロジェクトの一環として開発された Log4j というロギング ツールで実行されます。
この手順を開始する前に、「開発の基本概念」でログインの詳細を、また「ロギング ツールキットの使い方」で Log4j の使用方法の詳細を確認することをお勧めします。
イベント接続を使用する場合は、イベント生成専用のロギング カテゴリを作成する必要があります。ロギング カテゴリの詳細については、「メッセージ カテゴリ」を参照してください。特定のアダプタのロギング コンフィグレーション ファイル (WLI_HOME
/adapters/
YOUR_ADAPTER
/src/
adapter_logical_name.xml
) を編集するには、以下のリストに示すコードを追加する必要があります。
コード リスト 7-1 イベント生成のロギング カテゴリを作成するためのサンプル コード
<category name='BEA_WLS_SAMPLE_ADK
.EventGenerator' class='com.bea.
logging.LogCategory'>
</category>
BEA_WLS_SAMPLE_ADK
は、使用するアダプタの論理名で置き換えてください。
このカテゴリにパラメータを設定しない場合は、親カテゴリから適切なすべての設定が継承されます。この例では、親カテゴリは BEA_WLS_SAMPLE_ADK です。ルート カテゴリにアダプタ論理名を使用する必要はありませんが、複数アダプタ環境で使用する他のアダプタに影響しないユニークな識別子を使用する必要があります。
イベント接続を実装するには、以下の 2 つの手順を行う必要があります。
IEventGenerator
インタフェースを実装します (後者のインタフェースは、イベント生成プロセスを実行するために、イベント ルータで使用されます)。この手順は「手順 3a : イベント ジェネレータの作成」で説明します。イベントを生成すると、EIS から通知を受信するメカニズムまたは特定のイベントが発生していないか EIS をポーリングするメカニズムが、アダプタに提供されます。WebLogic Integration エンジンには、複数のタイプのイベントをサポートする強力なイベント ジェネレータが用意されています。イベント タイプは、イベントのコンフィグレーション プロパティにより定義されます。
通常、イベント プロパティは、設計時にイベントと関連付けられたプロパティで定義されます。イベント接続をコンフィグレーションするときは、アダプタによるイベント プロパティの収集元となる Web ページを 1 つまたは複数指定できます。これらのプロパティは、アプリケーション ビュー記述子と共に保存され、実行時にイベントに返されます。WebLogic Integration エンジンでは、これらのプロパティとアプリケーション ビューを使用して、リスナへ返すルーティングが決定されます。たとえば、同じプロパティが定義された同じイベント ジェネレータを 2 つ別々にデプロイしても、WebLogic Integration エンジンでは IEventDefinition
は 1 つしか作成されません。しかし、異なるプロパティが定義されている場合は、1 つのイベント接続の各デプロイメントに対して IEventDefinition
が作成されます。イベント ジェネレータでは、ルーティング プロセスでどの IEventDefinition
を使用するかを決定する必要があります。この決定は、通常、プロパティ値と特定のイベントの発生に基づいて行われます。
IEventDefinition
オブジェクトは、イベント ジェネレータの実装で使用され、特定のイベントをリスナに返すルーティングを行います。他の場所でも説明したように、WebLogic Integration エンジンでは、イベントを含むデプロイ済みのアプリケーション ビューの IEventDefinition
オブジェクトが作成されます。IEventDefinition
オブジェクトを使用して、アプリケーション ビューのデプロイメントに関する特定のプロパティを抽出したり、スキーマおよびルーティング オブジェクトにアクセスできます。これらの属性は、イベントのルーティング時に使用します。
WebLogic Integration は、以下の 2 つのデータ抽出モードをサポートしています。
Pull モードでは、ポーリング手法によりイベントの発生が判断されます。これを実装するには、com.bea.adapter.event
パッケージの AbstractPullEventGenerator
からイベント ジェネレータを取得します。
注意 : adk-eventgenerator.jar
ファイルには、イベント ジェネレータの実装に必要な ADK の基本クラスが記述されています。このファイルは、WAR メイク ファイルにインクルードする必要があります。
ADK では、AbstractPullEventGenerator
に、いくつかの抽象メソッドが用意されていますが、実際の実装ではこれをオーバーライドします。以下の表で、これらのメソッドを説明します。
Push モードでは、イベントのルーティングをトリガする通知を使用します。これを実装するには、com.bea.adapter.event
パッケージの AbstractPushEventGenerator
クラスからイベント ジェネレータを取得します。このイベント パッケージには、他にもいくつかのサポート クラスが用意されています。表 7-2 に、これらのクラスを示します。
注意 : adk-eventgenerator.jar
ファイルには、イベント ジェネレータの実装に必要な WebLogic Integration の基本クラスが含まれます。このファイルは、WAR メイク ファイルにインクルードする必要があります。
|
|
|
|
|
|
|
通常、イベント ジェネレータは、以下の制御フローを実装します。
postEvents()
メソッドはイベントが存在する場合に EIS をポーリングし、postEvent()
は、イベントが存在する場合に、どの IEventDefinition
オブジェクトがイベントを受け取るかを決定します。その後、関連付けられたスキーマを使用して、イベント データを IDocument
オブジェクトに変換し、IEventDefinition
オブジェクトに関連する IEvent
を使用して IDocument
オブジェクトをルーティングします。postEvents()
メソッドはイベントの通知を待ちます。通知を受け取ると、イベント データを PushEvent
オブジェクトから抽出し、そのデータをイベント接続に割り当てられたスキーマに従って IDocument
オブジェクトに変換します。必要なすべてのイベント データが IDocument
に変換されると、IDocument
が正しい IEventDefinition
オブジェクトにルーティングされます。コード リスト 7-2 に、サンプル アダプタの (Pull モード) イベント ジェネレータのクラス宣言を示します。
コード リスト 7-2 データ抽出の Pull モードのサンプル実装
public class EventGenerator
extends AbstractPullEventGenerator
注意 : AbstractPullEventGenerator
は、独自のスレッドで実行できるようにするため、Runnable
インタフェースを実装します。
「手順 3a : イベント ジェネレータの作成」の残りの節では、データ抽出の Pull モードでのイベント ジェネレータ実装方法を示すコードのその他の例を紹介しています。
コード リスト 7-3 に、イベント ジェネレータの単純なコンストラクタを示します。親のメンバーが正しく初期化されるように、親のコンストラクタを呼び出す必要があります。このリストは、doInit()
メソッドが map
変数からコンフィグレーション情報を受け取り、パラメータを検証する方法を示します。このサンプルには、設計時にイベント ジェネレータと関連付けられているすべてのパラメータが含まれます。
コード リスト 7-3 EventGenerator 用のサンプル コンストラクタ
public EventGenerator()
{
super();
}
protected void doInit(Map map)
throws java.lang.Exception
{
ILogger logger = getLogger();
m_strUserName = (String)map.get("UserName");
if (m_strUserName == null || m_strUserName.length() == 0
{
String strErrorMsg =
logger.getI18NMessage("event_generator_no_UserName");
logger.error(strErrorMsg);
throw new IllegalStateException(strErrorMsg);
}m_strPassword = (String)map.get("Password");
if (m_strPassword == null || m_strPassword.length() == 0)
{
String strErrorMsg = logger.getI18NMessage
("event_generator_no_Password");
logger.error(strErrorMsg);
throw new IllegalStateException(strErrorMsg);
}
コード リスト 7-4 に示されているように、postEvents()
が親クラスの実行メソッドから呼び出されます。このメソッドが、EIS をポーリングして、新しいイベント発生の有無を判別します。このメソッドは、一定間隔 (間隔は、イベント ルータの web.xml
ファイルで定義) で呼び出されます。
コード リスト 7-4 postEvents() のサンプル実装
protected void postEvents(IEventRouter router)
throws java.lang.Exception
{
ILogger logger = getLogger();
// 作業 : 実際のアダプタでは EIS を呼び出し、
// 前回このメソッドが呼び出された後に新しいイベントが発生
// したかどうかの判別が必要。例示のため、
// このメソッドが呼び出されるたびに 1 つのイベントを通知する
// イベント データは現在イベント定義に従って
// フォーマットされたシステムにあるいくつかの
// イベント タイプを検索する
Iterator eventTypesIterator = getEventTypes();
if (eventTypesIterator.hasNext())
{
do
{
// イベント ルータはまだこのタイプのイベントに関連性がある
IEventDefinition eventDef = (IEventDefinition)
eventTypesIterator.next();
logger.debug("Generating event for " + eventDef.getName());
// デフォルトのイベント (ブランクまたはデフォルトのデータ) を作成する
IEvent event = eventDef.createDefaultEvent();
// イベントのフォーマットを取得する
java.util.Map eventPropertyMap = eventDef.
getPropertySet();
String strFormat = (String)eventPropertyMap.get
("Format");
if( logger.isDebugEnabled() )
logger.debug("Format for event type '"+eventDef.
getName()+"' is '"+strFormat+"'");
java.text.SimpleDateFormat sdf =
new java.text.SimpleDateFormat(strFormat);
IDocument payload = event.getPayload();
payload.setStringInFirst("/SystemTime", sdf.format(new
Date()));
// ここで、監査メッセージのログを取る
try
{
logger.audit(toString() + ": postEvents >>> posting event
["+payload.toXML()+"] to router");
}
catch (Exception exc)
{
logger.warn(exc);
}
// この呼び出しによって実際に IEventRouter にイベントが通知される
router.postEvent(event);
} while (eventTypesIterator.hasNext());
}
}// postEvents の終了
実際のアダプタでは、EIS にクエリを実行し、前回このメソッドが呼び出された後に新しいイベントが発生したかどうかを判断する必要があります。ADK に付属の DBMS サンプル アダプタで提供される、このような呼び出しの具体例は、EventGenerator.java
ファイルの postEvent()
メソッドです。
WLI_HOME
/adapters/dbms/src/com/bea/adapter/dbms/event/EventGenerator.java
新しいイベント タイプの処理更新時には、setupNewTypes()
が呼び出されます。通常、イベント ジェネレータは、EIS からのイベントを受け取るために EIS にリソースを割り当てる必要があります。たとえば、DBMS サンプル アダプタでは、新しいイベント タイプを処理するために、DBMS でトリガが作成されます。setupNewTypes()
メソッドにより、新しいタイプを処理するのに必要な定義を設定できます。親クラスですでに listOfNewTypes()
ファイルの健全性チェックがなされ、ログに記録されているので、ここでチェックは行いません。
コード リスト 7-5 setupNewTypes() のサンプル テンプレート
protected void setupNewTypes(java.util.List listOfNewTypes)
{
Iterator iter = listOfNewTypes.iterator();
while (iter.hasNext())
{
IEventDefinition eventType = (IEventDefinition)iter.next();
}
}
アンデプロイされたアプリケーション ビューのイベント タイプの削除時には、removeDeadTypes()
が呼び出されます。
非推奨のイベント タイプが今後処理されないようにするため、クリーンアップ処理を行う必要があります。たとえば、非推奨のイベント タイプの処理に必要なリソースをクローズします。コード リスト 7-6 に、removeDeadTypes()
の実装方法を示します。
コード リスト 7-6 removeDeadTypes() テンプレートに基づくサンプル コード
protected void removeDeadTypes(java.util.List listOfDeadTypes)
{
Iterator iter = listOfDeadTypes.iterator();
while (iter.hasNext())
{
IEventDefinition eventType = (IEventDefinition)iter.next();
doCleanUpOnQuit()
is called during shutdown of the event generator.このメソッドは、イベント処理中に割り当てられたリソースを削除します。サンプル アダプタはこのメソッドで停止します。以下のリストに、このメソッドを実装するテンプレートを示します。
コード リスト 7-7 doCleanUpOnQuit() メソッド呼び出しのサンプル
protected void doCleanUpOnQuit()
throws java.lang.Exception
{
ILogger logger = getLogger();
logger.debug(this.toString() + ": doCleanUpOnQuit");
}
}
データ トランスフォーメーションは、EIS からデータを取り出してアプリケーション サーバが読み取れる XML スキーマに変換する処理です。各イベントに対し、スキーマが SOM
および IDocument
クラス ライブラリを使用して XML 出力の表示を定義します。以下のコード リストに、データ トランスフォーメーション プロセス時のイベントのシーケンスを示します。
コード リスト 7-8 EIS データを XML スキーマに変換するサンプル コード
SOMSchema schema = new SOMSchema();
SOMElement root = new SOMElement("SENDINPUT");
SOMComplexType mailType = new SOMComplexType();
root.setType(mailType);
SOMSequence sequence = mailType.addSequence();
SOMElement to = new SOMElement("TO");
to.setMinOccurs("1");
to.setMaxOccurs("unbounded");
sequence.add(to);
SOMElement from = new SOMElement("FROM");
from.setMinOccurs("1");
from.setMaxOccurs("1");
sequence.add(from);
SOMElement cc = new SOMElement("CC");
cc.setMinOccurs("1");
cc.setMaxOccurs("unbounded");
sequence.add(cc);
SOMElement bcc = new SOMElement("BCC");
bcc.setMinOccurs("1");
bcc.setMaxOccurs("unbounded");
sequence.add(bcc);
SOMElement subject = new SOMElement("SUBJECT");
subject.setMinOccurs("1");
subject.setMaxOccurs("1");
sequence.add(bcc);
SOMElement body = new SOMElement("BODY");
if (template == null)
{ body.setMinOccurs("1");
body.setMaxOccurs("1");
}else
{ Iterator iter = template.getTags();
if (iter.hasNext())
{ SOMComplexType bodyComplex = new SOMComplexType();
body.setType(bodyComplex);
SOMAll all = new SOMAll();
while (iter.hasNext())
{ SOMElement eNew = new SOMElement((String)iter.next());
all.add(eNew);
}//endwhile
bodyComplex.setGroup(all);
}//endif
}//endif
sequence.add(body);
schema.addElement(root);
コード リスト 7-9 コード リスト 7-8 のコードで作成された XML スキーマ
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="SENDINPUT">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="TO" maxOccurs="unbounded"
type="xsd: string"/>
<xsd:element name="FROM" type="xsd:string"/>
<xsd:element name="CC" maxOccurs="unbounded"
type="xsd:string"/>
<xsd:element name="BCC" maxOccurs=
"unbounded" type= "xsd:string"/>
<xsd:element name="BCC" maxOccurs="unbounded"
type="xsd:string"/>
<xsd:element name="BODY" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
コード リスト 7-10 コード リスト 7-9 のスキーマで作成された有効な XML ドキュメント
</xsd:schema>
<?xml version="1.0"?>
<!DOCTYPE SENDINPUT>
<SENDINPUT>
<TO/>
<FROM/>
<CC/>
<BCC/>
<BCC/>
<BODY/>
</SENDINPUT> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
この手順は省略可能です。サスペンド/再開サポートにより、イベント ジェネレータでイベント ルータからのリクエストに応答して、イベント生成のサスペンドまたは再開を実行できます。管理者がアダプタからのイベント配信をサスペンドする必要があることを指定すると、イベント ルータによりこれらのリクエストが作成されます。サスペンド/再開サポートの実装を直接行わない場合、アダプタのサスペンド中にイベント ジェネレータが生成したイベントは WebLogic Integration エンジンに保存されます。
アダプタにサスペンド/再開サポートを実装するかどうかは、後からイベント情報を取得できるように EIS インスタンスでこれらの情報を保存できるかどうかで決まります。EIS でこれらの情報を保存できる場合は、アダプタにサスペンド/再開サポートを実装する必要があります。このサポートを実装すると、WebLogic Integration でイベント情報を保存する場合よりも効果的に EIS でイベントを保存できます。
後からイベント情報を取得できるように EIS で効果的にイベント情報を保存できない場合は、イベント ジェネレータにサスペンド/再開サポートを直接実装せず、WebLogic Integration でイベントを保存できるようにする必要があります。
サスペンド/再開サポートを実装する場合は、イベント ジェネレータ実装クラスに com.bea.wlai.event.ISuspendableEventGenerator
インタフェースを実装するだけです。AbstractPullEventGenerator
をサブクラスにする場合は、suspend()
および resume()
呼び出しをスーパークラスに委託するだけです。以下のコード リストは、DBMS サンプル アダプタによる ISuspendableEventGenerator
の実装方法を示します。
import com.bea.adapter.event.AbstractPullEventGenerator;
import com.bea.wlai.event.ISuspendableEventGenerator;
public class EventGenerator
extends AbstractPullEventGenerator
implements ISuspendableEventGenerator {
/**
* イベントの生成を (一時的に) サスペンド。EIS インスタンスで発生したイベントは、
* EIS インスタンス自体、または EventGenerator 独自の記憶装置内に
* 保存する必要がある。このメソッドは、呼び出しを
* スーパークラスに委託するのみ。
*/
public void suspend()
throws Exception
{
super.suspend();
}
/**
* イベントの生成を再開。この EventGenerator のサスペンド中に
* 発生したイベントは、ここでできるだけ早く EventRouter に
* 配信する必要がある。このメソッドは、呼び出しをスーパークラスに
* 委託するのみ。
*/
public void resume()
throws Exception
{
super.resume();
}
}
イベント ジェネレータが AbstractPullEventGenerator
から拡張されない場合は、ISuspendableEventGenerator
の適切な実装方法を指定する必要があります。
この手順は省略可能です。WebLogic Integration 8.1 には、イベント ジェネレータがイベント ジェネレータ自体のステータスおよび EIS インスタンスのステータスをイベント ルータに示す機能が追加されました。この機能により、イベント ジェネレータの管理性が大幅に向上します。アダプタ開発者がアダプタにこのサポートを実装することを強くお勧めします。
ステータス レポートは、WebLogic Integration 管理者に以下の 2 つの大きな利点を与えます。
ステータス レポートを実装するには、IEventRouter
インタフェースで以下のメソッドを使用します。
注意 : postEvents
、setupNewTypes
、および removeDeadTypes
の呼び出しで、IEventRouter
インスタンスが渡されます。
setEventGeneratorStatus(Status
status
)
- このメソッドを使用すると、イベント ジェネレータのステータスを示すことができます。Status クラスは、標準ステータス値 (UNKNOWN、HEALTHY、SUSPENDED、MARGINAL、INOPERATIVE など) を定義する列挙クラスです。値をこれらのステータス値から選択することも、独自のステータス値を 100 より大きい整数値として定義することもできます。また、ステータス クラスでは説明フィールドも用意されており、イベント ジェネレータが該当するステートに移った理由を説明できます。eisUnavailable(String
reason
)
- このメソッドは、イベント ジェネレータが EIS インスタンスに接続できないことを示すために使用されます。このメソッドと EIS に接続できなかった理由の説明を呼び出します。このメソッドを呼び出すと、イベント ジェネレータのアダプタ インスタンスがサスペンドされ、WLI 管理コンソールにこのアダプタ インスタンスが Suspended
として表示されます。eisAvailable(String
reason
)
- このメソッドは、イベント ジェネレータが EIS インスタンスに再度接続できることを示すために使用されます。このメソッドと EIS に接続できるようになった理由の説明を呼び出します。理由としては、EIS への接続をリセットした、または定義済みの時間が経過するまで待機してから接続を再試行したなどが挙げられます。このメソッドを呼び出すと、イベント ジェネレータのアダプタ インスタンスが再開され、WLI 管理コンソールにこのアダプタ インスタンスが Deployed
として表示されます。コード リスト 7-12 DBMS サンプル アダプタのステータス レポート
/**
* このメソッドは、イベント ジェネレータが DBMS への接続にアクセスするたびに
* 呼び出される。
*/
private final boolean verifyEISStatus(IEventRouter router)
{
Status status = null;
if (router != null)
{
status = router.getEventGeneratorStatus();
}
boolean pingSucceeded = false;
Exception pingException = null;
try
{
// アクセスしたら、接続が有効かどうかを確認するために簡単な処理を実行する。
// 初めて ping が失敗した場合は、再接続を試行する。
pingSucceeded = pingAndRevive(true);
}
catch (Exception e)
{
pingException = e;
}
// 現在位置を確認し、その場所で実行する。
if (pingSucceeded)
{
if (status == null || status.status != Status.HEALTHY)
{
router.eisAvailable("Ping on DBMS connection succeeded");
}
}
else
{
if (status == null || status.status != Status.SUSPENDED)
{
String msg = "Ping on DBMS connection failed";
if (pingException != null)
{
msg += ": " + pingException;
}
router.eisUnavailable(msg);
}
}
return pingSucceeded;
}
WebLogic Integration 8.1 Service Pack 2 では、クラスタ化環境においてイベント ジェネレータの対象を設定する必要があることに注意してください。空の対象 (""
) では、クラスタ内のどのノードでもイベントが起動されません(単一ノード環境では値を指定する必要はありません。イベント ジェネレータの対象値が空でも 1 つのサーバーでイベントが起動されます)。
WebLogic Integration 8.1 には、イベント ジェネレータを WebLogic Integration クラスタのノード間で分散する機能が追加されました。これにより、イベント生成のロード バランスとフォールト トレランスが向上します。ただし、これを行う機能は、アダプタ自体の要件および実装に基づきます。
一部のイベント ジェネレータでは、イベント発生の検出に使用するリソースを EIS 内に所有していることを前提としています。このようなイベント ジェネレータは、リソースの使用において衝突が発生するため、同じ EIS インスタンスを使用して他のイベント ジェネレータと共存できません。例としては、WebLogic Integration 7.0 DBMS サンプル アダプタが挙げられます。このアダプタでは、DBMS 内のイベント ステージング テーブルに情報を所有していることを前提としています。そのため、このアダプタは、他の WebLogic Integration 7.0 DBMS サンプル アダプタ のイベント ジェネレータと共存できません。イベント ステージング テーブル内のイベント情報について競合するため、1 つまたは複数のジェネレータが飢餓状態に陥ったり、またはデータベースのロック/更新が頻繁に衝突するためです。
注意 : イベント ジェネレータのインスタンス サポートを実装しないイベント ジェネレータでも、新しいイベント生成の対象設定を利用できます。ただし、WebLogic Integration 管理者は、クラスタ内のノードを指定して、イベント ジェネレータの 1 つのインスタンス (またはインスタンスを使用しないこと) を設定することしかできません。イベント ジェネレータのインスタンス サポートを実装すると、アダプタでイベント生成をより細かく制御でき、優れた管理性が得られます。
WebLogic Integration 8.1 では、DBMS サンプル アダプタの機能が向上し、同じ DBMS インスタンスを使用した複数のイベント ジェネレータが共存できるようになりました。これは、イベント ジェネレータのインスタンス サポートとして知られる概念を実装することで実現します。DBMS サンプル アダプタでは、管理者が定義したジェネレータ インスタンスを任意の数だけ認識します。この節では、ジェネレータ インスタンスの概要や DBMS サンプル アダプタでのジェネレータ インスタンスの使用方法を説明します。
3 ノード WebLogic Integration クラスタを使用するとします。クラスタのノードには、Server1、Server2、Server3 という名前が付けられています。管理者が、1 つのアダプタ インスタンス (および通常は 1 つの EIS インスタンス) に対するイベント生成の担当をノード間で均等に分散するとします。管理者は、このような分散を行う前に、アダプタで複数のイベント ジェネレータがサポートされているかどうかを確認する必要があります。この情報は、アダプタのドキュメントに記載されています。
アダプタが複数のイベント ジェネレータをサポートしない場合は、1 つのイベント ジェネレータにクラスタ内の 1 つのノードを関連付ける必要があります。そのためには、WebLogic Integration Administration Console ([アダプタ インスタンス イベント接続] ページ) の [イベント生成対象] フィールドで以下の値を指定します。
アダプタが複数のジェネレータ インスタンスをサポートする場合は、イベント ジェネレータをクラスタ内の各ノードに分散できます。このような分散を行うには、[イベント生成対象] フィールドで以下のように指定します。
これにより、3 つのイベント ジェネレータで、該当する EIS インスタンスのイベント生成作業を共有できます。
DBMS サンプル アダプタの場合、複数のイベント ジェネレータが同じテーブルで選択、削除、または更新を行うと、データベースのロックが衝突します。この問題を解決するために、個々のイベントが特定のジェネレータ インスタンス用に処理されるよう、各ジェネレータ インスタンスの識別方法を定義します。これにより、各イベント ジェネレータが独自のイベント セットを処理するため、複数のイベント ジェネレータが共存できます。ジェネレータ インスタンス識別子を使用すると、DBMS サンプル アダプタのイベント ステージング テーブルの単一セットを、複数のテーブルの論理セットに効率よくパーティション化できます。
DBMS サンプル アダプタの場合、ジェネレータ インスタンスに数値識別子または ID が含まれています。システム管理者は、DBMS サンプル アダプタが複数のイベント ジェネレータ インスタンスをサポートすることを確認すると、数値識別子のリストを定義してジェネレータ インスタンスのセットを定義できます。次に、ジェネレータ インスタンスの数値 ID を [イベント生成対象] フィールド値のサーバ名に関連付けることにより、これらのジェネレータ インスタンスをクラスタのノード間で分散できます。
DBMS サンプル アダプタに対する、例として使用している 3 ノード クラスタの一般的な [イベント生成対象] の設定は以下のようになります。
この仕様では、クラスタのノードごとに 1 つのジェネレータ インスタンスが定義されています。各インスタンス仕様は、以下のように表されます。
=[instance_id
/number_of_instances
]
インスタンス仕様は、インスタンスが関連付けられるサーバ名に続いて指定されます。
注意 : instance_id
/number_of_instances
のフォーマットは、DBMS サンプル アダプタ固有です。ジェネレータ インスタンスのフォーマットは自由に定義できます。ただし、インスタンスのリストは角括弧 []
で囲み、各インスタンスは 1 つまたは複数のスペースにより他のインスタンスと分ける必要があります。そのため、インスタンスのフォーマットでは以下の文字を使用できません。
イベント ジェネレータのインスタンス サポートが強力な機能である理由を説明するため、ここで DBMS サンプル アダプタを使用して、WebLogic Integration クラスタでの単一ノード障害シナリオを検証します。管理者が各ノードに 1 つのジェネレータ インスタンスを割り当てるように 3 つのノードをコンフィグレーションし、ジェネレータは初期化済みで、イベントを安定して処理および配信していると仮定します。しばらくして、Server2 に障害が発生したとします。
この場合、管理者が Server2 にジェネレータ インスタンス 2 を割り当てているため、Server2 に障害が発生している間は、インスタンス 2 専用のすべてのイベントの処理が停止するだけです。管理者は、Server2 の障害を検出すると、WebLogic Integration Administration Console で [イベント生成対象] フィールドをリセットして、インスタンス 2 をクラスタ内の有効なノードとして再度設定します。
管理者は、この変更を行うことにより、インスタンス 2 のイベント生成担当を障害の発生した Server2 から有効な Server1 へと移行します。次の節では、ジェネレータ インスタンス仕様の変更をイベント ジェネレータで検出する方法と、これらの変更に対してイベント ジェネレータで必要な応答について説明します。
WebLogic Integration 管理者が [イベント生成対象] の値を変更するたびに、イベント ジェネレータでは refresh()
の呼び出しを受信します。これにより、ジェネレータが担当するジェネレータ インスタンス ID のリストを更新できます。
DBMS サンプル アダプタで、AbstractPullEventGenerator
が拡張されます。AbstractPullEventGenerator
により refresh()
の呼び出しがインターセプトされ、イベント ジェネレータの現在のイベント タイプが照合されます。また、必要な場合のみ、setupNewTypes()
または removeDeadTypes()
が呼び出されます。ジェネレータ インスタンスで安定して作業を行うには、コード リスト 7-13 に示すように、refresh()
メソッドをオーバーライドします。
コード リスト 7-13 refresh() メソッドでのジェネレータ インスタンス ID のリスト取得
/**
* このルータが担当する現在のイベント タイプ (定義) のリスト、
* および担当するイベント ルータ インスタンス ID のリストを考慮に入れて、
* このジェネレータを更新する。
*/
public void refresh()
throws Exception
{
// 処理を求められているインスタンス ID を確認する。
refreshEventRouterInstanceIDs();
// EVENT_GENERATOR テーブルで新しい最大カウントが反映されているか確認する // (「プライマリ」ジェネレータ インスタンス (インスタンス ID 1 など) でない場合は、
// この呼び出しは省略できない)。
updateGeneratorID(getConnection(), true);
// このルータのイベント タイプが変更されたかどうかは、スーパークラスに
// 判断させる。
super.refresh();
}
private void refreshEventRouterInstanceIDs()
{
m_isPrimaryInstance = false;
String[] eventRouterInstanceIDs =
getRouter().getEventRouterInstanceIDs();
Store the new list of instance IDs, and if we see instance `1', we have
become the `primary' instance.The `primary' instance is responsible for
certain singleton lifecycle updates.The concept of principal instance
allows us to avoid collisions that might result if more than one instance
attempted these lifecycle operations
}
オーバーライドされたメソッドの最後で、スーパークラス refresh()
メソッドを呼び出します。これにより、必要に応じて、適切な setupNewTypes()
および removeDeadTypes()
の呼び出しが保証されます。また、refresh()
の呼び出しでは、このジェネレータが担当する現在のジェネレータ インスタンス ID のリストを取得します。次に、DBMS サンプル アダプタのイベント ジェネレータで、この新しいリストで検出された任意のジェネレータ インスタンス専用のイベントをイベント ステージング テーブルから選択し始めます。
注意 : DBMS サンプル アダプタのイベント ジェネレータでは、AbstractPullEventGenerator
により、このジェネレータ用に作成された 1 つのスレッドのみを使用します。イベント ジェネレータの処理力を上げる強力な方法は、ジェネレータ インスタンス ID ごとに 1 つの処理スレッドを割り当てることです。この方法では、前述の単一ノード障害シナリオで、Server1 に 1 つだけではなく、2 つのスレッド処理イベントを割り当てることができます。さらに、イベント ジェネレータに関連付けられているジェネレータ インスタンスの数が増えるにつれてスレッドの数が増えるようにすると、管理者はイベント処理のスループットを増やすことができます。管理者は、より多くのジェネレータ インスタンス (たとえば、クラスタ内で 2 つ以上) を定義し、ノード間で分散するだけです。
この手順は省略可能です。環境変数を使用すると、アダプタで特定のデプロイメント環境固有の情報を隔離できるため、そのアダプタを使用するアダプタ インスタンスを環境間で移動するときに、WLI 管理者がこれらの情報を更新できます。
アダプタの対話仕様オブジェクト、サービス要求ドキュメント、またはイベント定義で環境固有の情報を必要とするアダプタでは、環境変数サポートの実装を考慮する必要があります。環境固有の情報の例として、DBMS アダプタ用のテーブル名のようなリソース識別子や電子メール アダプタ用の電子メール フォルダ名が挙げられます。
注意 : 環境固有の情報には、EIS への接続を作成するために必要な情報は含まれません。通常、この情報は環境に固有です。
対話仕様オブジェクト、要求ドキュメント、またはイベント定義に環境固有の情報を持たないアダプタでは、環境変数のサポートを実装する必要はありません。
環境変数は、Application Integration Design Console での設計時に特定のアプリケーション ビューに対して定義されます。作成された変数定義のセットは、イベント ジェネレータでのイベント サブスクリプションを表すために使用する IEventDefinition
オブジェクトとして、イベント アダプタ インスタンス、イベント ルータ、そして最後にイベント ジェネレータに伝播されます。
設計時における環境変数の定義方法の詳細については、「設計時 GUI の開発」を参照してください。
イベント定義のセットは、IEventGenerator.refresh()
、AbstractEventGenerator.setupNewTypes()
、または AbstractEventGenerator.removeDeadTypes()
の各呼び出しで取得します。
実行時の環境変数は、IVariable
インタフェースのインスタンスとして表されます。IVariable
インタフェースは以下のとおりです。
/**
* アダプタ定義の環境変数を含む。
*/
public interface IVariable
extends java.io.Serializable
{
public String getName();
public String getType();
public String getDescription();
public String getDefaultValue();
public String getValue();
}
/**
* アダプタ用のアダプタ定義の環境変数セットを含む。
*/
public interface IVariableSet
extends java.io.Serializable
{
public void addListener(VariableChangeListener listener);
public void removeListener(VariableChangeListener listener);
public String[] listVariableNames();
public IVariable getVariable(String name);
public IVariable[] listVariables();
}
イベント ジェネレータのインスタンスでは、変数の名前と値のみが関係します。イベント ジェネレータ実装での変数の使用方法は自由です。これは、設計時コンポーネントによりイベントのイベント定義に配置されるメタデータのフォーマットにより決定されます。通常は、アダプタにより、置き換え可能な変数値を示すイベント定義プロパティのテキストにマーカ フィールドが配置されます。
たとえば、DBMS サンプル アダプタでは、イベントのテーブル、カタログ、およびスキーマの名前を定義する際に、アプリケーション ビューの設計者が環境変数を使用できます。DBMS サンプル アダプタでは、イベントを指定されたテーブルでの挿入、削除、または更新として処理します。テーブルは、テーブル名、およびテーブルを含むカタログやスキーマの名前により識別されます。これらの名前は環境ごとに異なることが多いため、変数を使用することで、管理者は環境間でアプリケーション ビューを移動するときに、簡単にこれらの名前を変更できます。DBMS サンプル アダプタの一般的なイベント記述子には、以下のプロパティ名と値の組み合わせが含まれます。
mySchema
および myCatalog
の値を囲む中括弧に注目してください。DBMS サンプル アダプタでは、この括弧を使用して変数値を示します。この場合の変数とは、mySchema
と myCatalog
です。このイベント定義を使用すると、DBMS サンプル アダプタのイベント ジェネレータでは、実行時にイベント定義に mySchema
と myCatalog
という名前の 2 つの変数を含む変数セットが添付されます。実行時に、イベント ジェネレータにより、その時点で有効な変数値が取得され、これらの値がそれぞれ schemaName
および catalogName
プロパティ値の {mySchema
} および {myCatalog
} テキストと置き替えられます。以下は、DBMS サンプル アダプタからのコードです。
IEventDefinition eventDef = One of the event defs passed in setupNewTypes()
IClientData clientData = eventDef.getClientData();
if (clientData != null)
{
IVariableSet varSet = clientData.getVariableSet();
catalogName = DBMSSQLUtils.applyVariables(varSet, catalogName);
schemaName = DBMSSQLUtils.applyVariables(varSet, schemaName);
tableName = DBMSSQLUtils.applyVariables(varSet, tableName);
}
DBMSSQLUtils.applyVariables()
は、特定のプロパティで検出された変数の文字列を、対応する変数の値に置き換えます。
WebLogic Integration に用意されているアダプタのテスト ハーネスを使用して、アダプタをテストできます。このツールとその使用方法の詳細については、「サービス アダプタの開発」の「手順 6 : アダプタのテスト」を参照してください。
新しいアダプタを再構築したら、そのアダプタを WebLogic Integration 環境にデプロイします。アダプタのデプロイは、手動でも WebLogic Server Administration Console からでも実行できます。詳細については、「アダプタのデプロイ」を参照してください。
![]() ![]() |
![]() |
![]() |