custom transport sdk
DESCRIPTION
Oracle Service Bus をカスタムで拡張する事で、新しいプロトコルや独自なプロトコルに対応する事ができます。拡張するための Custom Transport SDK について紹介しますTRANSCRIPT
<Insert Picture Here>
カスタム・トランスポート
日本オラクル株式会社
Fusion Middleware事業統括本部
Copyright© 2012, Oracle. All rights reserved. 2
以下の事項は、弊社の一般的な製品の方向性に関する概要を説明するものです。また、情報提供を唯一の目的とするものであり、いかなる契約にも組み込むことはできません。以下の事項は、マテリアルやコード、機能を提供することをコミットメント(確約)するものではないため、購買決定を行う際の判断材料になさらないで下さい。オラクル製品に関して記載されている機能の開発、リリースおよび時期については、弊社の裁量により決定されます。
OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
Copyright© 2012, Oracle. All rights reserved. 3
はじめに
• ガイドの対象者
• Oracle Service Bus (以下OSB)に新しいトランスポート・プロバイダを追加する必要がある方
• Java、Webサービス・テクノロジ、OSB、トランスポート・プロトコル、WebLogic Serverについての知識を有する方
• ガイドの目的
• 開発者にカスタム・トランスポートの作成およびデプロイに必要な情報を提供する
• 学習内容
• サンプル・ソケット・トランスポート・プロバイダを例として、カスタム・トランスポートの作成とデプロイ
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
4
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
トランスポートSDKの用途
• OSBのメッセージ処理は、メッセージの送受信方法とは関係なく行われます。トランスポートSDKは、OSBとOSBで送受信されるデータ・フローを扱うコンポーネントの間
に抽象化レイヤーを提供します。この抽象化レイヤーがあることで、一意の転送プロトコルを扱うためのカスタム・トランスポートを開発できます。
• トランスポートSDKは、OSBの他の部分から以下を抽象化します。
• 特定のトランスポート・バイディングの処理
• サービス・エンドポイントのトランスポート・バイディングへのデプロイ
• モニター情報の収集
• エンドポイントの管理
• サービス・レベル・アグリーメント動作の適用
5
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
6
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
カスタム・トランスポートの開発流れ
トランスポートSDKを使用したカスタム・プロバイダの開発は、基本的に下記の手順になります。
• 計画
• カスタム・トランスポートを開発する必要があるかどうかの判断
• メッセージ・エンドポイントをトランザクション対応にするかどうかの判断
• メッセージ・エンドポイントを一方向、同期、非同期のいずれかの判断
• 開発
• トランスポート・フレームワーク・コンポーネントの確認
• トランスポート・プロジェクトのディレクトリ構造の作成
• トランスポート構成ファイルの作成
• トランスポート固有のアーティファクトのXMLスキーマの作成
• ユーザー・インタフェースの作成
…
• パッケージ化およびデプロイ
7
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
8
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
カスタム・トランスポートの開発必要の判断
以下の場合は、トランスポートSDKを使用したカスタム・トランスポートの開発が適しています。
• 内部アプリケーション間の通信に使用している特殊な転送方式を利用したい
• トランスポートSDKを使用して、個々のエンドポイントや、インバウンドおよびアウトバインドを使用するトランスポートの実装が可能
• トランスポートSDKを使用して、特別なトランスポートのメタデータ、ヘッダー・フィ
ールドをプロキシ・サービス・パイプラインで使用できるコンテキスト変数にマッピングが可能
• トランスポートSDKを使用して、特別なトランスポートをOSBのあらゆる側面にシームレスに統合可能
• OSBで提供されるトランスポートの仕組みを利用して開発したい
9
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
10
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
トランザクション対応/非対応の判断
11
エンドポイントはトランザクション対応の場合と非対応の場合があります。トランザ
クション対応のエンドポイントは、メッセージを処理する際に、グローバル・トランザクションのコンテキスト内で開始または追加できます。以下の例では、トランザクションのプロパティがエンドポイントによってどのように異なるかを示します
• XA接続ファクトリを使用するJMSプロキシ・サービスはトランザクション対応のエ
ンドポイントです。メッセージを受信すると、コンテナは、トランザクションのコンテキスト内でメッセージが処理されるように、トランザクションが開始されたことを確認します。
• Tuxedoプロキシ・サービスは、トランザクション対応でない場合があります。Tuxedoプロキシ・サービスは、メッセージを受信する前にTuxedoクライアント・ア
プリケーションによってトランザクションが開始された場合にのみトランザクション対応になります。
• HTTPクライアントによって呼び出されるHTTPプロキシ・サービスには通常はトランザクションが関連付けられませんが、トランザクションを開始して、 そのトランザクションのコンテキストでメッセージ・フローを実行するというオプションをHTTPプロキシ構成で設定できます。
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
12
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
メッセージ・パターンの判断
13
任意のエンドポイントで、以下のメッセージ・パターンのいずれかを使用できます。
• 一方向
レスポンスを受け取りません。一方向のエンドポイントの例としては、レスポンスを受け取らないJMSプロキシ・サービスがあります。
• 同期
リクエストまたはレスポンスを意味します。この場合、レスポンス・メッセージとリクエスト・メッセージは暗黙的にペアになります。これは、リクエストが出 された時点から
レスポンスを受け取るまでの間にトランスポート・チャネルで他のトラフィックが発生し得ないためです。ほとんどの場合、同期メッセージは、 アウトバウンド・リクエストの呼出しのブロックを意味します。EJBエンドポイントは同期です。HTTPエンドポイントも同期です。
• 非同期
リクエストおよびレスポンスを意味します。レスポンスは、JMSトランスポートおよびJMSCorrelationIDメッセージ・プロパティによる相関 関係などの、トランスポート固
有のメカニズムによってリクエストと関連付けられます。たとえば、リクエストおよびレスポンスを持つJMSビジネス・サービ ス・エンドポイントは非同期です。
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
14
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
トランスポート・コンポーネントの理解
15
実装および構成する必要があるコンポーネントを理解する必要があります。
トランスポート・コンポーネントは下図に示しています。詳細な紹介について、次のページをご参照ください。
Copyright© 2012, Oracle. All rights reserved.
トランスポート・コンポーネントの理解
16
• トランスポート・マネージャ:トランスポート・プロバイダの登録および管理し、OSBとの通信を処理します。
• トランスポート・プロバイダ:トランスポート・エンドポイントのライフ・サイクルおよび実行時の動作を管理します。
• トランスポートUIバインディング:トランスポート・プロバイダのユーザー・インタフェース・コンポーネント。
• トランスポート・エンドポイント:メッセージの送受信を行います。
• エンドポイント構成:エンドポイント構成を格納します。
• トランスポート・メッセージ・コンテキスト:メッセージのリクエスト・ヘッダー、レスポンス・ヘッダー、およびその他の部分のメタデータが含まれています。
• トランスポートの送受信:アウトバウンド・メッセージおよびペイロードのメタデータを取得します。
• トランスポートのリスナー:アウトバウンドがOSBの残りの部分にアウトバウンド・リクエストの結果をポストできるようにします。
• リクエスト/レスポンスのメタデータ:リクエスト・メッセージおよびレスポンス・メッセージの
メタデータ。
• WLSアーティファクト・デプロイヤ:(オプション)メッセージを送受信するサーブレットなどの、アーティファクトをデプロイします。
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
17
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
トランスポート・プロジェクト・ディレクトリの作成
18
ディレクトリ 説明
build サンプル・ソケット・トランスポート・プロバイダをビルドするときに作成されます。OSBで使用するビルド化およびパッケージ化されたトランスポートを含みます。
eclipse Eclipse環境にサンプル・トランスポートを追加するために必要なplugin.xmlファイルを含みます。
L10n 国際化のためのファイルを含みます。Socket TransportMessage.xml-OSBコンソールに表示されるテキスト・メッセージのための構成ファイルです。
META-INF アプリケーション・デプロイメント記述子ファイルを含みます。Application.xml-J2EEアプリケーション記述子ファイル
weblogic-application.xlm-WebLogicアプリケーション記述子ファイル
resources SocketConfig.xml-トランスポートSDKが使用する、サンプル・ソケット・トランスポート・プロバイダの構成です。トランスポートのサンプル・ヘルプ・ファイル。
schemas このトランスポート用に定義されている、次の関連スキーマを含みます。
SocketTransport.xsd-ソケットのエンドポイント・リクエスト/レスポンスのメタデータ/ヘッダーを記述します。
src サンプル・トランスポートのソース・ツリー
test テスト・ファイルのディレクトリ。src-テスト・サーバーとクライアントのソース・ツリー
webapp サンプル・トランスポート・ヘルプWebアプリケーションで必要なデプロイメント記述子を含みます。
build.xml コンパイル、ビルド、およびデプロイ用の異なる対象を含むAntビルド・ファイルです。
build.properties Antのプロパティ・ファイルです。
トランスポート・プロバイダを開発する前に、プロジェクトの適切なディレクトリ構造をセットアップします。サンプル・ソケット・トランスポート・プロバイダに使用されているディレクトリ構造をコピーすることをお薦めします。構造の詳細は、以下になります。
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
19
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
カスタム・トランスポートの構成ファイルの作成
• TransportProviderConfigurationファイルを設定し、カスタム・トランスポートの構成を設定します。
• TransportProviderConfigurationのスキーマはOSB_ORACLE_HOME/lib/sb-schemas.jarにあるTransportCommon.xsd
に定義されています。
• サンプル・ソケット・トランスポート・プロバイダの構成ファイルはSocketConfig.xmlで、これを基に構成ファイルを作成できます。
20
Copyright© 2012, Oracle. All rights reserved.
SocketConfig.xml のプロパティ
21
• inbound-direction-supported要素をtrueに設定し、プロキシ・サービスでトランスポートを使用できます。
• outbound-direction-supported要素をtrueに設定し、ビジネス・サービスでトランスポートを使用できます。
• トランスポートが自己記述型の場合、self-described要素の値をtrueに設定します。自己記述トランスポートでは、そのサービスがエンドポイント構成に基づいて形式(スキーマまたはWSDL)を記述します。
• トランスポートのtModelをUDDIにパブリッシュする場合、UDDI要素を含めます。
※プロパティの詳細について、TransportCommon.xsdファイルをご参照ください。
Copyright© 2012, Oracle. All rights reserved.
SocketConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<ProviderConfiguration xmlns="http://www.bea.com/wli/sb/transports">
<inbound-direction-supported>true</inbound-direction-supported>
<outbound-direction-supported>true</outbound-direction-supported>
<UDDI>
<TModelDefinition>
<tModel tModelKey="uddi:bea.uddi.org:transport:socket">
<name>uddi-org:socket</name>
<description>Socket transport based webservice</description>
<overviewDoc>
<overviewURL useType="text">
http://www.bea.com/wli/sb/UDDIMapping#socket
</overviewURL>
</overviewDoc>
<categoryBag>
<keyedReference keyName="uddi-org:types:transport"
keyValue="transport"
tModelKey="uddi:uddi.org:categorization:types"/>
</categoryBag>
</tModel>
</TModelDefinition>
</UDDI>
</ProviderConfiguration>
22
Copyright© 2012, Oracle. All rights reserved.
getProviderConfigurationメソッド
public TransportProviderConfiguration getProviderConfiguration() throws TransportException {
try {
URL configUrl = this.getClass().getClassLoader().getResource("SocketConfig.xml");
return ProviderConfigurationDocument.Factory.parse(configUrl).getProviderConfiguration();
}
catch (Exception e) {
SocketTransportUtil.logger.error(e.getLocalizedMessage(), e);
throw new TransportException(e);
}
}
23
以下のgetProviderConfigurationメソッドによって、SocketConfig.xmlが解析され、XMLBeanが生成されます。
Copyright© 2012, Oracle. All rights reserved.
AGENDA
1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
24
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
カスタム・トランスポート固有のXMLスキーマの作成
• XMLスキーマ(xsd)ファイルを作成し、トランスポート固有の定義を記述しま
す。このファイルは、サンプル・ソケット・トランスポート・プロバイダ用に開発されたスキーマ・ファイルSocketTransport.xsdを基に作成できます。
• XMLスキーマ・ファイルに、以下のトランスポート固有のXMLスキーマを定義します。
• EndpointConfiguration
• RequestMetaDataXML
• ReponseMetaDataXML
• RequestHeadersXML
• ReponseHeadersXML
25
Copyright© 2012, Oracle. All rights reserved.
EndPointConfiguration
• EndPointConfigurationは、エンドポイント構成のベース・タイプで、インバウ
ンド・エンドポイントおよびアウトバウンド・エンドポイントのデプロイメントと操作に必要なパラメータの完全なセットを表します。この構成は、汎用的な部分とプロバイダ固有の部分で成り立ちます。
• サンプル・ソケット・トランスポート・プロバイダのSocketEndpointConfigurationには、以下の六つのプロパティを定義します。各プロパティの詳細は、<xs:documentation>部分を参照してください。
• outbound-properties
• inbound-properties
• request-response
• dispatch-policy
• request-encoding
• response-encoding
26
Copyright© 2012, Oracle. All rights reserved.
SocketEndpointConfigurationのプロパティ
27
Copyright© 2012, Oracle. All rights reserved.
SocketEndpointConfigurationの抜粋
28
<xs:complexType name="SocketEndpointConfiguration">
<xs:annotation>
<xs:documentation>
SocketTransport - specific configuration
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:choice>
<xs:element name="outbound-properties"
type="SocketOutboundPropertiesType"/>
<xs:element name="inbound-properties"
type="SocketInboundPropertiesType"/>
</xs:choice>
<xs:element name="request-response" type="xs:boolean">
<xs:annotation>
<xs:documentation>
Whether the message pattern is synchronous
request-response or one-way.
</xs:documentation>
</xs:annotation>
</xs:element>
...
Copyright© 2012, Oracle. All rights reserved.
メタデータとヘッダー
29
• メタデータとヘッダーとして送信できる情報には、Content-Typeヘッダー、
セキュリティ情報、ロケール情報などがあります。
• メタデータとヘッダーの構成をスキーマ・ファイル(SocketTransport.xsd)に指定する必要があります。
• 各トランスポート・プロバイダは、メタデータとヘッダーをPOJO(Plain Old Java Object)に格納し、パイプラインに渡す必要があります。スキーマ・ファイルはPOJOをXMLで表現したものです。
Copyright© 2012, Oracle. All rights reserved.
SocketRequestMetaDataXMLのプロパティ
30
※サンプル・ソケット・トランスポート・プロバイダはResponseHeadersXMLを定義していません。
Copyright© 2012, Oracle. All rights reserved.
SocketRequestMetaDataXMLの抜粋
31
<xs:complexType name="SocketRequestMetaDataXML">
<xs:annotation>
<xs:documentation/>
</xs:annotation>
<xs:complexContent>
<xs:extension base="ts:RequestMetaDataXML">
<xs:sequence>
<xs:element name="client-host"
type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>
Client host name
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="client-port" type="xs:int" minOccurs="0">
<xs:annotation>
<xs:documentation>Client port</xs:documentation>
</xs:annotation>
</xs:element>
…
Copyright© 2012, Oracle. All rights reserved.
ReponseMetaDataXMLの抜粋
32
<xs:complexType name="SocketResponseMetaDataXML">
<xs:complexContent>
<xs:extension base="ts:ResponseMetaDataXML">
<xs:sequence>
<xs:element name="service-endpoint-host"
type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>
Host name of the service end point connection.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="service-endpoint-ip"
type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>
IP address of the service end point connection.
</xs:documentation>
</xs:annotation>
</xs:element>
…
Copyright© 2012, Oracle. All rights reserved.
RequestHeadersXMLの抜粋
33
<xs:complexType name="SocketRequestHeadersXML">
<xs:annotation>
<xs:documentation/>
</xs:annotation>
<xs:complexContent>
<xs:extension base="ts:RequestHeadersXML">
<xs:sequence>
<xs:element name="message-count" type="xs:long" minOccurs="0">
<xs:annotation>
<xs:documentation>
Number of messages passed till now.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
34
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
ユーザー・インタフェースの作成
35
• OSBコンソールを使用してビジネス・サービスまたはプロキシ・サービスを追
加する場合、サービス作成ウィザードでトランスポート・プロバイダを選択します。ウィザードには、OSBで用意されているトランスポート・プロバイダおよびSDKで開発されたカスタム・トランスポート・プロバイダが表示されます。
• ここでカスタム・トランスポート・プロバイダで設定したプロパティを表示するウィザードの開発を説明します。
Copyright© 2012, Oracle. All rights reserved.
ユーザー・インタフェースの作成
36
サービスの名前、サービスのバインディング・タイプおよびその他の情報を定義します。OSBコンソールはgetProviderメソッドを呼び出し、トランスポート・プロバイダを生成します。getUIBindingメソッドが呼び出され、UIバインディングを生成します。
Copyright© 2012, Oracle. All rights reserved.
ユーザー・インタフェースの作成
37
• ウィザードで「サービス・タイプ」を選択したら、そのサービスの種類に対して適切なトランスポート・プロバイダだけが表示される必要があります。ウィザードによりTransportUIBindingインタフェースのisServiceTypeSupportedメソッドが呼び出され、トランスポート・プロバイダが選択したサービスの種類に適しているかどうか判定されます。
• 有効なトランスポート・プロバイダを選択したら、TransportUIBindingインタフェースのgetGenericInfoメソッドが呼び出され、トランスポート・プロバイダの情報を提供します。ここでURIのヒント、オートフィル・フィールドの情報が表示されます。
• エンドポイントURLを入力します。このURLを検証するために、ウィザードによりTransportUIBindingインタフェースのvalidateMainFormメソッドを呼び出されます。
Copyright© 2012, Oracle. All rights reserved.
ユーザー・インタフェースの作成
38
• 次に、トランスポート固有の構成のページがウィザードに表示されます。このページを表示するために、TransportUIBindingインタフェースのgetEditPageが呼び出されます。トランスポートSDKは、構成ページにフィールドを表示するTransportUIObjectsのセットを提供します。例えば、テキスト・ボックス、チェック・ボックス、およびその他のタイプのUI要素を追加できます。これらを作成するには、TransportUIFactoryを使用します。作成したら、同じファクトリを
使用して追加のプロパティを指定して、サービス作成ウィザードで表示可能なTransportEditFieldオブジェクトを取得します。
• イベントを大部分のUIフィールドに関連付けることができます。イベントは、TransportUIBindingインタフェースのコールバック・メカニズムのように動作するため、構成ペ
ージをリフレッシュ、検証、および更新することができます。イベントがトリガーされると、updateEditPageメソッドが呼び出されます。
• 入力した値を検証するために、TransportUIBinding
インタフェースのvalidateProviderSpecificForm
メソッドが呼び出されます。
• 次に、TransportUIBindingインタフェースの
getProviderSpecificConfigurationメソッドが
• 呼び出され、ウィザードで入力したトランスポート・
プロバイダ固有のプロパティの値をエンドポイント
の構成XMLオブジェクトに付与します。
Copyright© 2012, Oracle. All rights reserved.
ユーザー・インタフェースの作成
39
最後は、TransportUIBindingインタフェースのgetViewPageメソッドが呼び出され、ウィザードのサマリー画面でプロパティの値が表示されます。
Copyright© 2012, Oracle. All rights reserved.
isServiceTypeSupportメソッドの実装
40
/**
*メッセージ・タイプがテキストまたはXMLのいずれかである場合にtrueを返します。
*サンプル・ソケット・トランスポート・プロバイダはリクエスト・メッセージとレスポンス・メッセージの両方で、XMLおよび
*テキスト・メッセージ・タイプをサポートしています。
*/
public boolean isServiceTypeSupported(BindingTypeInfo bindingType) {
try {
BindingTypeInfo.BindingTypeEnum type = bindingType.getType();
/**
* バインディングが混在している場合は、リクエスト・タイプが存在する必要があり、それはテキストまたは
* XMLタイプのいずれかでなければなりません。レスポンス・タイプがある場合、
*それはテキストまたはXMLのいずれかでなければなりません。
*/
if (type.equals(BindingTypeInfo.BindingTypeEnum.MIXED)) {
/* ... サポートされていないタイプがある場合はfalseを返し、そうでない場合はtrueを返します。*/
}
/* バインディング・タイプがABSTRACT_XMLまたはXMLのいずれかでなければなりません。*/
return type.equals(BindingTypeInfo.BindingTypeEnum.ABSTRACT_XML)
|| type.equals(BindingTypeInfo.BindingTypeEnum.XML);
} catch (TransportException e) {
SocketTransportUtil.logger.error(e.getLocalizedMessage(), e);
return false;
}
Copyright© 2012, Oracle. All rights reserved.
getGenericInfoメソッドの実装
41
public TransportUIGenericInfo getGenericInfo() {
TransportUIGenericInfo genInfo = new TransportUIGenericInfo();
if (uiContext.isProxy()) {
genInfo.setUriFormat( "tcp://port" );
genInfo.setUriAutofill( "tcp://9999" );
} else {
genInfo.setUriFormat( "tcp://socket-ip-address:port" );
genInfo.setUriAutofill( "tcp://localhost:8888" );
}
return genInfo;
}
Copyright© 2012, Oracle. All rights reserved.
validateMainFormメソッドの実装
42
public TransportUIError[] validateMainForm(TransportEditField[] fields) {
Map<String, TransportUIFactory.TransportUIObject> map =
TransportEditField.getObjectMap(fields);
List<TransportUIError> errors = new ArrayList<TransportUIError>();
if (!uiContext.isProxy()) {
List<String[]> uris = getStringValues(map, TransportUIBinding.PARAM_URI);
for (String[] uristr : uris) {
try {
URI uri = new URI(uristr[0]);
if (!(uri.getScheme().equals("tcp") && uri.getHost() != null &&
uri.getPort() != -1)) {
errors.add(new TransportUIError(TransportUIBinding.PARAM_URI,"Invalid URI"));
}
} catch (URISyntaxException e) {
errors.add(new TransportUIError(TransportUIBinding.PARAM_URI,e.getMessage()));
}
}
} else {
/* 同様にプロキシURLをチェックします。プロキシURLの形式は”tcp:<port>”である必要があります。 */
}
return errors == null || errors.isEmpty() ? null :
errors.toArray(new TransportUIError[errors.size()]);
}
Copyright© 2012, Oracle. All rights reserved.
getEditPageメソッドの実装
43
public TransportEditField[] getEditPage(EndPointConfiguration config,BindingTypeInfo binding) throws
TransportException {
List<TransportEditField> fields = new ArrayList<TransportEditField>();
SocketEndpointConfiguration sockConfig = null;
if (config != null && config.isSetProviderSpecific()) {
sockConfig = SocketTransportUtil.getConfig(config);
}
/*requestResponseチェックボックスを追加します。*/
boolean requestResponse = sockConfig == null || sockConfig.getRequestResponse();
TransportUIFactory.CheckBoxObject checkbox = TransportUIFactory.createCheckbox(null,requestResponse, true);
TransportEditField editField = TransportUIFactory.createEditField(REQUEST_RESPONSE,
REQUEST_RESPONSE_LABEL,REQUEST_RESPONSE_TOOLTIP, false, checkbox);
fields.add(editField);
/*
*プロキシである場合、Backlogフィールドを追加します。
* timeoutとenableNagleAlgorithの値を取得します。
*/
long timeout = 5000;
boolean enableNA = true;
次のページへ続きます。
Copyright© 2012, Oracle. All rights reserved.
getEditPageメソッドの実装
44
if (uiContext.isProxy()) {
int backlog = 5;
if (sockConfig != null) {
SocketInboundPropertiesType inboundProperties = sockConfig.getInboundProperties();
backlog = inboundProperties.getBacklog();
timeout = inboundProperties.getTimeout();
enableNA = inboundProperties.getEnableNagleAlgorithm();
}
TransportUIFactory.TextBoxObject textBox =
TransportUIFactory.createTextBox(backlog + "", 20);
editField = TransportUIFactory.createEditField(BACKLOG, BACKLOG_LABEL,BACKLOG_TOOLTIP, false,
textBox);
fields.add(editField);
} else {
if (sockConfig != null) {
SocketOutboundPropertiesType outboundProperties =sockConfig.getOutboundProperties();
timeout = outboundProperties.getTimeout();
enableNA = outboundProperties.getEnableNagleAlgorithm();
}
}
/*Connection Timeoutテキストボックスを追加します。*/
/*Enable Nagle's Algorithmチェックボックス・フィールドを追加します。*/
/*Request Encodingチェックボックス・フィールドを追加します。 */
/*Response Encodingテキストボックス・フィールドを追加します。*/
/*Dispatch policyドロップダウン・リスト・フィールドを追加します。*/
return fields.toArray(new TransportEditField[fields.size()]);
}
Copyright© 2012, Oracle. All rights reserved.
updateEditPageメソッドの実装
45
public TransportEditField[] updateEditPage(TransportEditField[] fields,String name)
throws TransportException {
/*REQUEST_RESPONSEフィールドの値をアップデートします。*/
if (!REQUEST_RESPONSE.equals(name)) {
return fields;
}
/* REQUEST_RESPONSEがtrueである場合にのみ、RESPONSE_ENCODINGフィールドを有効にします。*/
Map<String, TransportEditField> fieldMap = TransportEditField.getFieldMap(fields);
TransportEditField editField = fieldMap.get(REQUEST_RESPONSE);
TransportUIFactory.CheckBoxObject selectObject = (TransportUIFactory.CheckBoxObject)
editField.getObject();
boolean b = selectObject.ischecked();
fieldMap.get(RESPONSE_ENCODING).setDisabled(!b);
return fields;
}
Copyright© 2012, Oracle. All rights reserved.
getProviderSpecificConfigurationメソッドの実装
46
public XmlObject getProviderSpecificConfiguration(TransportEditField[] fields)
throws TransportException {
SocketEndpointConfiguration socketEndpointConfig = SocketEndpointConfiguration.Factory.newInstance();
Map<String, TransportUIFactory.TransportUIObject> map = TransportEditField.getObjectMap(fields);
socketEndpointConfig.setRequestResponse(
TransportUIFactory.getBooleanValue(map, REQUEST_RESPONSE));
if (uiContext.isProxy()) {
SocketInboundPropertiesType socketInboundPropertiesType = socketEndpointConfig.addNewInboundProperties();
socketInboundPropertiesType.setBacklog(
TransportUIFactory.getIntValue(map, BACKLOG));
socketInboundPropertiesType.setEnableNagleAlgorithm(
TransportUIFactory.getBooleanValue(map, ENABLE_NAGLE_ALGORITHM));
socketInboundPropertiesType.setTimeout(TransportUIFactory.getIntValue(map, TIME_OUT));
} else {
/* ビジネス・サービスの発信のプロパティに対して同じ操作を行います。 */
}
String reqEnc = TransportUIFactory.getStringValue(map, REQUEST_ENCODING);
if (reqEnc != null && reqEnc.trim().length() != 0) {
socketEndpointConfig.setRequestEncoding(reqEnc);
}
String resEnc = TransportUIFactory.getStringValue(map, RESPONSE_ENCODING);
if (resEnc != null && resEnc.trim().length() != 0) {
socketEndpointConfig.setResponseEncoding(resEnc);
}
String dispatchPolicy = TransportUIFactory.getStringValue(map, DISPATCH_POLICY);
socketEndpointConfig.setDispatchPolicy(dispatchPolicy);
return socketEndpointConfig;
}
}
Copyright© 2012, Oracle. All rights reserved.
getViewPageメソッドの実装
47
public TransportViewField[] getViewPage(EndPointConfiguration config)
throws TransportException {
List<TransportViewField> fields = new ArrayList<TransportViewField>();
SocketEndpointConfiguration socketEndpointConfiguration =
SocketTransportUtil.getConfig(config);
/*requestResponseフィールドを追加します。*/
TransportViewField field =
new TransportViewField(REQUEST_RESPONSE, REQUEST_RESPONSE_LABEL,
socketEndpointConfiguration.getRequestResponse());
fields.add(field);
次のページへ続きます。
Copyright© 2012, Oracle. All rights reserved.
getViewPageメソッドの実装
48
/*
*プロキシである場合、Backlogフィールドを追加します。
*timeout とenableNagleAlgorithm フィールドを追加します.
*/
if (uiContext.isProxy()) {
SocketInboundPropertiesType inboundProperties =
socketEndpointConfiguration.getInboundProperties();
field = new TransportViewField(BACKLOG, BACKLOG_LABEL,
inboundProperties.getBacklog());
fields.add(field);
/*inboundPropertiesからConnection Timeoutフィールドを追加します。*/
/*inboundPropertiesからEnable Nagle's Algorithmフィールドを追加します。*/
} else {
/*outboundPropertiesからConnection Timeoutフィールドを追加します。 */
/*outboundPropertiesからEnable Nagle's Algorithmフィールドを追加します。 */
}
/*Request Encodingフィールドを追加します。*/
/*Response Encodingフィールドを追加します。*/
/*Dispatch policyフィールドを追加します。*/
return fields.toArray(new TransportViewField[fields.size()]);
}
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
49
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
エンドポイントのデプロイ
サービス登録で入力したエンドポイントをデプロイするには、以下の2セットのトランスポート・プロバイダ・インタフェースが用意されています。
• TransportProviderインタフェース
TransportProviderには、作成、更新、削除、サスペンド、再開などのメソッドがあります。このイ
ンタフェース中のすべてのメソッドを実現する必要があります。これらのメソッドは、サービスの作成、変更、またはサーバーを起動するときも呼び出されます。TransportProviderメソッドは、
ドメインのすべてのサーバー(管理サーバーおよび管理対象サーバー)で呼び出されます。管理対象サーバーでOSBドメインのアーティファクトは変更できないため、TransportProviderのメソッドを呼び出すのは、内部データ構造を更新する場合だけです。
• TransportWLSArtifactDeployerインタフェース
TransportProviderと同じメソッドがあります。TransportWLSArtifactDeployerを実装するのはプロバイダがOSBドメインのOracle WebLogic Serverアーティファクトを変更する必要がある場合だけです。TransportWLSArtifactDeployerのメソッドは、管理サーバーでのみ呼び出すことができます。この場合、渡されたDomainMBean引数を使用して変更が行われ、クラスタ全体に変更が伝播されます。特定のトランスポート・プロバイダがTransportWLSArtifactDeployerインタフェースを実装する場合、TransportProviderの対応するメソッドが呼び出される前に、TransportWLSArtifactDeployerのメソッドが呼び出されます。
50
※この資料では、TransportWLSArtifactDepolyerの実装を割愛しています。
Copyright© 2012, Oracle. All rights reserved.
エンドポイントのデプロイ
• サービスを登録した後、トランスポート・マネージャにより、TransportProviderインタフェースのvalidateEndPointConfigurationメソッドが呼び出されます。このメソッドにより、登録した情報を検証します。
• エラーが報告されない場合は、以下のメソッドを呼び出し、エンドポイントを作成、更新、削除、サスペンド、再開します。この段階で例外が発生すると、エンドポイントのデプロイをロールバックします。
• createEndPoint
• updateEndPoint
• suspendEndPoint
• resumeEndPoint
• deleteEndPoint
• 次に、activationCompleteメソッドが呼び出され、エンドポイントに対する操作を有効化します。
51
Copyright© 2012, Oracle. All rights reserved.
createEndpointメソッドの実装
52
public TransportEndPoint createEndPoint(
EndPointOperations.Create createContext) throws TransportException {
if(TransportManagerHelper.isAdmin() && TransportManagerHelper.clusterExists())
return null;
Ref ref = createContext.getRef();
createContext.getScratchPad().put(ref.getFullName()+ENABLED,
createContext.isEnabled());
SocketTransportEndPoint socketTransportEndPoint =
new SocketTransportEndPoint(ref, createContext.getEndPointConfiguration(), this);
endPoints.put(ref, socketTransportEndPoint);
return socketTransportEndPoint;
}
Copyright© 2012, Oracle. All rights reserved.
updateEndpointメソッドの実装
public TransportEndPoint updateEndPoint(EndPointOperations.Update update)
throws TransportException {
if(TransportManagerHelper.isAdmin() && TransportManagerHelper.clusterExists())
return null;
Ref ref = update.getRef();
SocketTransportEndPoint oldEp = endPoints.get(ref);
/** oldEPは、サンプル・ソケット・トランスポート・プロバイダが再起動されると、既存の
*コンフィギュレーションが更新された時に、nullにすることができます。
*/
if (oldEp != null) {
update.getScratchPad().put(ref.getFullName()+UPDATE_OLD_ENDPOINT, oldEp);
}
endPoints.remove(ref);
update.getScratchPad().put(ref.getFullName()+ENABLED, update.isEnabled());
SocketTransportEndPoint endPoint = new SocketTransportEndPoint(ref,
update.getEndPointConfiguration(), this);
endPoints.put(ref, endPoint);
return endPoint;
}
53
Copyright© 2012, Oracle. All rights reserved.
getViewPageメソッドの実装
54
/*
*プロキシである場合、Backlogフィールドを追加します。
*timeout とenableNagleAlgorithm フィールドを追加します.
*/
if (uiContext.isProxy()) {
SocketInboundPropertiesType inboundProperties =
socketEndpointConfiguration.getInboundProperties();
field = new TransportViewField(BACKLOG, BACKLOG_LABEL,
inboundProperties.getBacklog());
fields.add(field);
/*inboundPropertiesからConnection Timeoutフィールドを追加します。*/
/*inboundPropertiesからEnable Nagle's Algorithmフィールドを追加します。*/
} else {
/*outboundPropertiesからConnection Timeoutフィールドを追加します。 */
/*outboundPropertiesからEnable Nagle's Algorithmフィールドを追加します。 */
}
/*Request Encodingフィールドを追加します。*/
/*Response Encodingフィールドを追加します。*/
/*Dispatch policyフィールドを追加します。*/
return fields.toArray(new TransportViewField[fields.size()]);
}
Copyright© 2012, Oracle. All rights reserved.
activationCompleteメソッドの実装
55
public void activationComplete(EndPointOperations.CommonOperation context) {
Ref ref = context.getRef();
EndPointOperations.EndPointOperationTypeEnum type = context.getType();
SocketTransportEndPoint endPoint = endPoints.get(ref);
if(TransportManagerHelper.isAdmin() && TransportManagerHelper.clusterExists()) return;
try {
if (EndPointOperations.EndPointOperationTypeEnum.CREATE.equals(type)) {
if ((Boolean) context.getScratchPad().get(ref.getFullName()+ENABLED)) {
endPoint.start();
}
} elseif (EndPointOperations.EndPointOperationTypeEnum.UPDATE.equals(type)) {
SocketTransportEndPoint oldEP = (SocketTransportEndPoint) context
. getScratchPad().get(ref.getFullName()+UPDATE_OLD_ENDPOINT);
if (oldEP != null) {
oldEP.stop();
}
if ((Boolean)context.getScratchPad().get(ref.getFullName()+ENABLED)) {
endPoint.start();
}} else
/*削除/サスペンド/再開を処理します。 */
} catch (Exception e) {
String msg = SocketTransportMessagesLogger.activationFailedLoggable(ref.getFullName()).getMessage();
SocketTransportUtil.logger.error(msg, e);
}}
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
56
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
メタデータとヘッダーの表示
• 各トランスポート・プロバイダでは、メタデータおよびヘッダーをPOJOコンテーナDefaultRequestHeaders、DefaultRequestMetaData クラスに格納し、パイプラインに渡す必要
があります。特定なメタデータおよびヘッダーを利用する場合、これらのクラスを継承するだけでいいです。特定なメタデータおよびメタデータを利用しない場合、これらのクラスをそのまま利用してください。
• OSBでXML Beanが必要となる場合もあります。このような場合は、toXML()メソッドを実装してPOJOからXMLBeanへ変換します。
• 逆方向(XMLからPOJO)の場合は、以下のメソッドを実装する必要があります。
• TransportEndPoint.createRequestMetaData(RequestMetaDataXML)
• InboundTransportMessageContext.createResponseMetaData(ReponseMetaDataXML)
57
Copyright© 2012, Oracle. All rights reserved.
SocketRequestHeadersクラス
58
public class SocketRequestHeaders extends
DefaultRequestHeaders<SocketRequestHeadersXML> {
/*message-count要素はスキーマに指定されました。新しいヘッダー要素のget/setメソッドはここで追加できます。 */
private static final String MESSAGE_COUNT = "message-count";
public SocketRequestHeaders(RequestHeadersXML headers) throws
TransportException {
super(SocketTransportProvider.getInstance(), headers);
}
public long getMessageCount() {
return (Long) getHeader(MESSAGE_COUNT);
}
public void setMessageCount(long messageCount) {
setHeader(MESSAGE_COUNT, messageCount);
}
}
Copyright© 2012, Oracle. All rights reserved.
SocketRequestMetaDataクラス
59
public class SocketRequestMetaData extends DefaultRequestMetaData<SocketRequestMetaDataXML> {
private int port = Integer.MIN_VALUE;
private String hostAddress;
public SocketRequestMetaData(SocketRequestMetaDataXML rmdXML)
throws TransportException {
super(SocketTransportProvider.getInstance(), rmdXML);
if(rmdXML != null) {
if(rmdXML.isSetClientHost()) {
setClientHost(rmdXML.getClientHost());
}
if(rmdXML.isSetClientPort()) {
setClientPort(rmdXML.getClientPort());
} } }
public SocketRequestMetaData(String requestEncoding) throws TransportException {
/* hdrがnullである場合、新しいヘッダーを作成していないため、super.(TransportProvider provider, RequestHeaders hdr,String enc)を呼び出しません。*/
super(SocketTransportProvider.getInstance());
setCharacterEncoding(requestEncoding);
}
protected RequestHeaders createHeaders(TransportProvider provider,RequestHeadersXML hdrXML)
throws TransportException {
return new SocketRequestHeaders(hdrXML);
}
次のページへ続きます。
Copyright© 2012, Oracle. All rights reserved.
SocketRequestMetaDataクラス
60
/*SocketRequestMetaDataXMLに与えられたXmlObjectを検証 し、解析します */
public static SocketRequestMetaDataXML getSocketRequestMetaData(XmlObject xbean) throws TransportException {
if (xbean == null) {
return null;
} else if (xbean instanceof SocketRequestMetaDataXML) {
return (SocketRequestMetaDataXML) xbean;
} else {
try {
return SocketRequestMetaDataXML.Factory.parse(xbean.newInputStream());
}catch (XmlException e) {
throw new TransportException(e.getMessage(), e);
} catch (IOException e) {
throw new TransportException(e.getMessage(), e);
}
}
}
Copyright© 2012, Oracle. All rights reserved.
SocketResponseMetaDataクラス
• サンプル・ソケット・トランスポート・プロバイダはレスポンス・メタデータservice-
endpoint-hostおよびservice-endpoint-ipを定義しています。レスポンス・ヘッダーがないため、SocketReponseHeaderクラスを定義しなく、デフォルトのクラスを利用します。
61
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
62
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
メッセージ・コンテンツの表示
63
詳細な説明について、次のページをご参照ください。
Copyright© 2012, Oracle. All rights reserved.
メッセージ・コンテンツの表示
64
• Sourceは、トランスポート・レイヤーとバインディング・レイヤーの間の一般的なコンテンツ表現です。バインディング・レイヤーは、トランスポート・レイヤーで使用されるSource表現と実行時にパイプラインで使用されるメッセージ・コンテキストとの間でコンテンツを変換するエンティティです。変換がどのように行われるかは、サービスのタイプと添付の有無によって異なります。
• 添付が存在しない場合、受信したSourceは単にコアとなるメッセージ・コンテンツを示します。受信したSourceを特定のタイプのSourceに変換し、その後で基底のコンテンツを抽出することでMessgeContextが初期化されます。例えば、XMLベースのサービスの場合、受信したSourceはXmlObjectSourceに変換されます。その後、XmlObjectSourceからXmlObjectが抽出され、$bodyコンテキスト変数内でペイロードとして使用されます。
• 定義された一連のサービス・タイプで使用される標準的なSourceのタイプを以下に示します。
• SOAP-XmlObjectSource
• XML-XmlObjectSource
• TEXT-StringSource
• MFL-MFLSource
Copyright© 2012, Oracle. All rights reserved.
メッセージ・コンテンツの表示
65
• 添付が存在する場合、Sourceは最初にMessageContextSourceに変換されます。MessageContextSourceから、2つタイプSourceオブジェクトが取得されます。1つが添付で、もう1つがコア・メッセージです。コア・メッセージのSourceは、前述の通り処理されます。添付を表すSourceは、AttachmentsSourceに変換されます。AttachmentsSourceから、XMLが取得され、$attachmentsコンテキスト変数、および任意のバイナリの添付コンテンツを表す登録済みのSourceを含むSourceRepositoryの初期化に使用されます。
• トランスポート・レイヤーに渡すためにMessageContext内のデータからSourceを作成する場合にも、同様の変換が実行されます。コア・メッセージは、サービスのタイプの標準的なSourceに変換できるSourceインスタンスで表現されています。ほとんどの場合、Sourceはすでに標準的なSourceのインスタンスになっていますが、必ずしもそうであるとは限りません。添付が存在する場合、トランスポート・レイヤーに渡されるSourceは、MessageContextSourceインスタンスに変換できるSourceになります。トランスポート・プロバイダが、事前定義されたトランスポート・ヘッダーとしてContent-Typeをサポートする場合、一般的に配信されたSourceはMessageContextSourceのインスタンスになります。それ以外の場合、配信されたSourceはMimeSourceのインスタンスであることが多いですが、これもMessageContextSourceに変換できます。
Copyright© 2012, Oracle. All rights reserved.
組込みのトランスフォーメーション
66
• この一覧は、組込みのトランスフォーマによって提供される、サポートされているトランスフォーメーションのセットを示しています。左側にあるSource名の列は最初のSourceのタイプを示し、上にあるSource名の行はターゲットのSourceのタイプを示しています。
「X」は、左側のSourceから上にあるターゲットSourceへ直接変換できることを示しています。
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
67
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
インバウンドの処理
68
OSBラインタイムでのインバウンド・メッセージのフローは下図に示しています。詳細な説明について、次のページをご参照ください。
Copyright© 2012, Oracle. All rights reserved.
インバウンドの処理
69
• 最初に、HTTP Servletなどのインバウンド・アーティファクトが、クライアント・リクエストを受 け取ります。
• トランスポート・プロバイダが、InboundTransportMessageContextと呼ばれるデータ構造を作成します。メッセージ・コンテキストが、リクエストのヘッダーをメタデータ・オブジェクトにパッケージ化し、HTTPストリームのペイロードを特定のOSBソース・オブジェクトに変換します。
• トランスポート・プロバイダは、トランスポート・マネージャを呼び出し、メッセージを受信します。
• トランスポート・マネージャがメッセージを処理し、OSBランタイムでの処理に渡します。
• OSBランタイムは、メッセージ・コンテキストのサービス、サービスのバージョン、およびその他の情報を要求します。また、処理に必要なメタデータおよびペイロードについても要求します。
• ランタイムは、レスポンス・メタデータおよびレスポンス・ペイロードを作成するようMessageContextに要求し、その後でclose()を呼び出します。クライアントにレスポンスが返されます。
Copyright© 2012, Oracle. All rights reserved.
インバウンドの処理
トランスポート・プロバイダは、TransportManager.receiveMessage()に次のパラメータを提供します。
• QOS-exactly-onceまたはbest-effortのサービス品質を指定します。exactly-onceの
サービス品質は、インバウンド・メッセージがトランザクション対応の場合に指定されます。
• THROW_ON_ERROR-このフラグを設定すると、OSBのパイプラインの処理中にエラーが発生した場合に、メソッドTransportManager.receiveMessage()の呼ばれた側
に対して、例外がスローされます。例外スローのオプションには、インバウンド・メッセージに対して例外を返したり、エラーからレスポンス・メッセージを生成して、そのレスポンス・メッセージでインバウンド・メッセージに通知するものがあります。通常、QOSがexactly-once(トランザクション対応のメッセージ)の場合は、 THROW_ON_ERROR
をtrueに設定します。
• トランスポート固有の不透明なデータ-不透明なデータは、トランスポート・プロバイダによって設定された任意のデータで、パイプラインを介してアウトバウンド呼出しに渡されます。この方法を使用すると、インバウンドとアウトバウンドで同じトランスポートを使用する場合に、パフォーマンスを最適化できます。不透明なデータは、パイプラインを介して、インバウンド・トランスポートからアウトバウンド・トランスポートに直接渡されます。
70
Copyright© 2012, Oracle. All rights reserved.
SocketInboundMessageContextクラスの実装
71
public class SocketInboundMessageContext implements InboundTransportMessageContext {
private SocketTransportEndPoint endPoint;
private Socket clientSocket;
private String msgId;
private String msg;
private SocketRequestMetaData requestMetadata;
private SocketResponseMetaData responseMetaData;
private Source responsePayload;
private static int count = 0;
/**フィールド変数を初期化します。*/
public SocketInboundMessageContext(SocketTransportEndPoint endPoint,
Socket clientSocket, String msgId,String msg) throws TransportException {
this.endPoint = endPoint;
this.clientSocket = clientSocket;
this.msgId = msgId;
this.msg = msg;
String requestEncoding = endPoint.getRequestEncoding();
if(requestEncoding == null) {
requestEncoding = "utf-8";
}
requestMetadata = new SocketRequestMetaData(requestEncoding);
((SocketRequestHeaders)requestMetadata.getHeaders()).setMessageCount(++count);
requestMetadata.setClientHost(clientSocket.getInetAddress().getHostAddress());
requestMetadata.setClientPort(clientSocket.getPort());
}
次のページへ続きます。
Copyright© 2012, Oracle. All rights reserved.
SocketInboundMessageContextクラスの実装
72
/**インバウンド・メッセージを読んで、sourceを設定し、返します。*/
public Source getRequestPayload() throws TransportException {
if (msg == null) {
return null;
}
return new StringSource(msg);
}
/**インバウンド・レスポンスを初期化するために、空のメタデータを作成します。*/
public ResponseMetaData createResponseMetaData() throws TransportException {
SocketResponseMetaData responseMetaData =new SocketResponseMetaData(endPoint.getResponseEncoding());
return responseMetaData;
}
/**
*インバウンド・レスポンスを初期化するために、トランスポート・プロバイダ固有のXML Beanを使用して、
* レスポンス・メタデータを作成します。
*/
public ResponseMetaData createResponseMetaData(XmlObject rmdXML) throws TransportException {
SocketResponseMetaDataXML xmlObject = SocketResponseMetaData.getSocketResponseMetaData(rmdXML);
if (xmlObject != null) {
return new SocketResponseMetaData(xmlObject);
}
return null;
}}
次のページへ続きます。
Copyright© 2012, Oracle. All rights reserved.
SocketInboundMessageContextクラスの実装
73
/**レスポンス・メタデータを設定します。*/
public void setResponseMetaData(ResponseMetaData rmd)throws TransportException {
if (!(rmd instanceof SocketResponseMetaData)) {
throw new TransportException(
SocketTransportMessagesLogger.invalidResponseMetadataType(
SocketResponseMetaData.class.getName()));
}
responseMetaData = (SocketResponseMetaData) rmd;
}
/**レスポンス・メッセージのペイロードを設定します。*/
public void setResponsePayload(Source src) throws TransportException {
responsePayload = src;
}
次のページへ続きます。
Copyright© 2012, Oracle. All rights reserved.
SocketInboundMessageContextクラスの実装
74
/**クライアントにレスポンスを送信します。*/
public void close(TransportOptions transportOptions) {
OutputStream outputStream = null;
try {
/**メッセージ・パターンが一方向である場合、すぐに戻ります*/
if (endPoint.getMessagePattern().equals(TransportEndPoint.MessagePatternEnum.ONE_WAY)) {
return;
}
/**クライアントへのレスポンスを書き込みます。*/
String reqEnc = endPoint.getSocketEndpointConfiguration().getRequestEncoding();
if(reqEnc == null) {
reqEnc = "utf-8";
}
outputStream = clientSocket.getOutputStream();
if (responsePayload != null) {
TransformOptions options = new TransformOptions();
options.setCharacterEncoding(reqEnc);
responsePayload.writeTo(outputStream, options);
} else {
SocketTransportMessagesLogger.noResponsePayload();
}
/**末尾に¥r¥n¥r¥nを書き込みます。 */
outputStream.write(SocketTransportUtil.D_CRLF.getBytes(reqEnc));
outputStream.flush();
} catch (Exception e) {
/* エラーをログします。 */
} finally {
try {
//ソケット・ストリームを閉じます
clientSocket.close();
} catch (IOException ignore) {}}}}
Copyright© 2012, Oracle. All rights reserved.
SocketTransportReceiverクラスの実装
75
static class WorkerThread implements Runnable {
private Socket clientSocket;private SocketTransportEndPoint endPoint;
private int timeout; private boolean enableNagleAlgorithm;
public WorkerThread(Socket clientSocket, SocketTransportEndPoint endPoint,int timeout, boolean enableNagleAlgorithm) {
this.clientSocket = clientSocket; this.endPoint = endPoint; this.timeout = timeout;
this.enableNagleAlgorithm = enableNagleAlgorithm;
}
public void run() {
try {
/**ソケットのプロパティを設定します。*/
clientSocket.setSoTimeout(timeout); clientSocket.setTcpNoDelay(!enableNagleAlgorithm);
String msgId = new Random().nextInt() + "." + System.nanoTime();
InputStream inputStream = clientSocket.getInputStream();
/**受信メッセージを読みます。 */
String msg = ;/*入力ストリームからのメッセージ */
/**一方向ではない場合、コネクションを閉じます。*/
if (endPoint.getMessagePattern().equals(TransportEndPoint.MessagePatternEnum.ONE_WAY))
try {
//出力ストリームを開かなかったので、入力ストリームを閉じます。
clientSocket.getInputStream().close();
} catch (IOException e) {
SocketTransportUtil.logger.error(e.getLocalizedMessage());
}
}
final SocketInboundMessageContext inboundMessageContext = new SocketInboundMessageContext(endPoint, clientSocket, msgId, msg);
/**インバウンド・コンテキストがSDKに送信され、パイプラインに送信されます。*/
TransportManagerHelper.getTransportManager().receiveMessage(inboundMessageContext, null);
} catch (Exception e) {
/* エラーをログします。 */
}}
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
76
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
アウトバウンドの処理
77
OSBラインタイムでのアウトバウンド・メッセージのフローは下図に示しています。詳細な説明について、次のページをご参照ください。
Copyright© 2012, Oracle. All rights reserved.
アウトバウンドの処理
78
• OSBランタイムは、メッセージを外部サービスにルーティングします。
• トランスポート・プロバイダはリクエストのメタデータおよびTransportSenderオブジェクトを作 成します。このオブジェクトには、ペイロード、サービス品質および再試行に関する情報が含まれます。
• 次に、プロバイダはTransportManagerを呼び出し、メッセージを非同期で送信します。
• TransportManagerは、トランスポート・プロバイダを呼び出しメッセージを送信します。
• トランスポート・プロバイダはOutboundTransportMessageContextを作成します。
• その後、トランスポート・プロバイダは、メタデータ、ペイロードおよびその他の情報を要求し、適切なアクションを実行します。
• レスポンスを受信すると、トランスポート・プロバイダはTransportSenderListenerオブジェクトを呼び出します。
• 最終的に、トランスポート・マネージャがレスポンス・パイプラインを呼び出します。パイプライン・アクションが実行された後、アウトバウンド・エンドポイントが閉じられます。
Copyright© 2012, Oracle. All rights reserved.
アウトバウンドの処理
79
アウトバウンド処理の場合、OSBランタイムは、トランスポート・マネージャに次のパラメータを指定します。トランスポートはこれらのパラメータをいくつかを内部的に使用し、TransportProvider.sendMessageAsync()に伝播します。パラメータには、次のものが含まれます。
• QOS-exactly-onceのサービス品質を実現可能かどうかを指定します。たとえば、HTTPでは、サービス品質をexactly-onceに設定している場合、HTTP呼出しはブロックされています。Best-effortに設定している場合、HTTP呼出しはブロックされません。
• モード-一方向または双方向(リクエスト/レスポンス)を指定します。
• URI、再試行間隔、回数-トランスポート・プロバイダは、URIを使用してアウトバウンド・トランスポート接続を初期化します。たとえば、HTTPトランスポート・プロバイダは、新しいHttpURLConnectionをインストールする際にURIを使用します。トランスポート・プロバイダでは、再試行間隔および回数を使用する必要がありません。
• OperationName-トランスポート・プロバイダは、使用されているアウトバウンドWebサービスを認識する必要がある場合にOperationNameを使用します。トランスポート・マネージャは、このパラメータを使用してモニター統計を追跡します。
• トランスポート固有の不透明なデータ-トランスポート固有の不透明なデータの例として、HTTP/SのAuthorizationヘッダーの値があります。
Copyright© 2012, Oracle. All rights reserved.
sendMessageAsyncメソッドの実装
80
public void sendMessageAsync(TransportSender sender,TransportSendListener listener,TransportOptions options)
throws TransportException {
/**他のエンドポイントは、インバウンドであるかどうかを判断します。 */
boolean isInbound = false;
if (sender instanceof ServiceTransportSender) {
isInbound = ((ServiceTransportSender) sender).getEndPoint().isInbound();
}
if (!isInbound) {//他のエンドポイントはアウトポイントである場合
SocketOutboundMessageContext socketOutboundMessageContext =
new SocketOutboundMessageContext(sender, options);
socketOutboundMessageContext.send(listener);
} else { //エンドポイントはインバウンドである場合
SocketCoLocatedMessageContext socketCoLocatedMessageContext =
new SocketCoLocatedMessageContext((ServiceTransportSender) sender,options);
socketCoLocatedMessageContext.send(listener);
}
}
Copyright© 2012, Oracle. All rights reserved.
SocketOutboundMessageContextクラスの実装
81
/**外部サービスにメッセージを送信し、Runnableをスケジュールします。Runnableにより、レスポンス・メタデータを設定、
*外部サービスからレスポンスを読み取ります。*/
public void send(final TransportSendListener listener) throws TransportException {
String address = options.getURI().toString();
try {
String host = null; int port = 0;
try {
URI uri = new URI(address); host = uri.getHost(); port = uri.getPort();
} catch (URISyntaxException e) {
new TransportException(e.getMessage(), e);
}
SocketTransportMessagesLogger.ipAddress(host, port); final Socket clientSocket = new Socket(host, port);
SocketEndpointConfiguration socketEndpointConfiguration = SocketTransportUtil.getConfig(config);
SocketOutboundPropertiesType outboundProperties = socketEndpointConfiguration.getOutboundProperties();
clientSocket.setTcpNoDelay(!outboundProperties.getEnableNagleAlgorithm());
clientSocket.setSoTimeout(outboundProperties.getTimeout());
String reqEnc = socketEndpointConfiguration.getRequestEncoding();
if (reqEnc == null) reqEnc = "utf-8";
//外部サービスにメッセージを送信します。
OutputStream outputStream = clientSocket.getOutputStream();
TransformOptions transformOptions = new TransformOptions();
transformOptions.setCharacterEncoding(reqEnc); sender.getPayload().writeTo(outputStream, transformOptions);
outputStream.write(SocketTransportUtil.D_CRLF.getBytes(reqEnc)); outputStream.flush();
SocketTransportMessagesLogger.flushed();
PipelineAcknowledgementTask task = new PipelineAcknowledgementTask(listener, clientSocket,socketEndpointConfiguration);
TransportManagerHelper.schedule(task, socketEndpointConfiguration.getDispatchPolicy());
} catch (Exception e) {
/*エラーをログします。 */;
throw new TransportException(e.getMessage(), e);
}}
次のページへ続きます。
Copyright© 2012, Oracle. All rights reserved.
SocketOutboundMessageContextクラスの実装
82
/**このタスクは、パイプラインへのアウトバンドを確認します。*/
class PipelineAcknowledgementTask implements Runnable {
private TransportSendListener listener; private Socket clientSocket;
private SocketEndpointConfiguration epc;
public PipelineAcknowledgementTask(TransportSendListener listener,Socket clientSocket,SocketEndpointConfiguration epc) {
this.listener = listener; this.clientSocket = clientSocket; this.epc = epc;
}
/**外部サービスからのレスポンスを読み取り、ヘッダーを設定し、パイプラインを呼び出します。*/
public void run() {
try {
// エンドポイントは一方向である場合、レスポンスを読みません。
if (!epc.getRequestResponse()) {
SocketTransportMessagesLogger.oneWayEndpoint();
listener.onReceiveResponse(SocketOutboundMessageContext.this);return;
}
String resEnc = getResponseEncoding(); responseMetadata = new SocketResponseMetaData(resEnc);
InetAddress inetAddress = clientSocket.getInetAddress(); responseMetadata.setEndPointHost(inetAddress.getHostName());
responseMetadata.setEndPointIP(inetAddress.getHostAddress());
// Read the response from the external service.
/**メッセージを読み取るためのコードが省略されています。*/
String msg = omittedStuff(); responseIS = new ByteArrayInputStream(msg.getBytes(resEnc));
listener.onReceiveResponse(SocketOutboundMessageContext.this);
} catch (Exception e) {
listener.onError(SocketOutboundMessageContext.this,TransportManager.TRANSPORT_ERROR_GENERIC, e.getLocalizedMessage());
} finally {
try {
clientSocket.close();
} catch (IOException e) {}}}}}
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
83
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
Eclipse用のトランスポートの開発
84
OSBトランスポートは、元々はOSBサーバーにデプロイするようにl設計され、OSBコンソールを使用して構成されていますが、Eclipseなどの設計環境で使用する場合もあります。開発者は、以下の3種類モードを考慮する必要があります。
• オンライン・モード:カスタム・トランスポートのサービスが、実行中のOSBサーバーでOSBコンソールによって構成されます。
• オフライン・モード:トランスポートがOSBサーバーの外部で実行されている設計環境を使用して構成されます。リモート・サーバーは使用できません。
• オフライン・モード(リモート・サーバーあり):トランスポートがOSBサーバーの外部で実行されている設計環境を使用して構成されます。ただし、リモート・サーバーが利用可能であり、検証および構成の両方の目的に使用できます。
• Eclipseで実行されるトランスポートは、オフライン・モーとと必要に応じて、オフライン・モード(リモート・サーバーあり)をサポートする必要があります。
TransportManagerHelperクラスは、プロバイダを実装する際にコードがオフラインで実行しているかどうかを判断するためのboolean isOffline()メソッドを提供します。
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
85
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
カスタム・トランスポートの登録 • サーバーの再起動時に、デプロイしたカスタム・トランスポートがすぐサービス・リクエストの処理を開始できるようにすることが可能です。トランスポート・プロバイダをすぐに使用できるようにするには、weblogic.application.ApplicationLifecycleListenerクラスを拡張し、preStart()メソッドを使用して、TransportManager.registerProvider()によってトランスポートを登録します。
public class ApplicationListener extends ApplicationLifecycleListener {
/**
* アプリケーションが初期化された後、このメソッドはデプロイ・フレームワークによって呼び出されます。
*ソケット・トランスポートがTransportManagerに登録されます。
*/
public void postStart(ApplicationLifecycleEvent evt) throws ApplicationException {
try {
TransportManager man = TransportManagerHelper.getTransportManager();
SocketTransportProvider instance = SocketTransportProvider.getInstance();
man.registerProvider(instance, null);
} catch (Exception e) {
/* エラーをログします。*/
}}}
• ApplicationLifcycleListenerを拡張する際は、必ず拡張クラスをMETA/weblogic-application.xml
に登録してください。サンプル・ソケット・トランスポート・プロバイダで、次のApplicationListenerクラスのエントリを提供しています。
86
Copyright© 2012, Oracle. All rights reserved.
Eclipseでトランスポートの登録
Eclipse用のカスタム・トランスポートを登録するには、まずTransportProviderFactoryクラスを実装します。OSBトランスポート・サブシステムは、起動時にこのメソッドを呼び出し、カスタム・トランスポートを登録します。
/**
* このインタフェースは、Eclipseでカスタム・トランスポートを接続するための拡張ポイントです。
* 実装は、デフォルトのクラスコンストラクタを宣言する必要があります。
*/
public interface TransportProviderFactory {
/**
* トランスポート・マネージャを使用して、新しいプロバイダを登録します。
* 通常はOSBのコアEclipseプラグインによって呼び出されます。
*/
public void registerProvider(TransportManager tm) throws TransportException;
/**
*'http'のように、プロバイダを識別する一意の文字列を返します。
* このメソッドは、provider.getIdと同じIDを返す必要があります。
*/
String getId();
}
87
Copyright© 2012, Oracle. All rights reserved.
Eclipseでトランスポートの登録
次に、Eclipse用のplugin.xmlを作成します。このファイルによって、起動時に登録するトランスポート(前のページで実装したクラス)を認識できます。
<?xml version=“1.0” encoding=“UTF-8”?>
<?eclipse version="3.2"?>
<plugin>
<extension
id="socket"
name="Socket Transport"
point="com.bea.alsb.core.transports">
<transport transport-provider="com.bea.alsb.transports
.sock.SocketTransportProviderFactory"/>
</extension>
</plugin>
plugin.xmlの重要な部分
extension point属性の値は、トランスポートでは常にcom.bea.alsb.core.transportsです。
transport-provider属性は、TransportProviderFactory実装クラスの完全修飾パスです。
88
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
89
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
ビルドとプロパティ・ファイルの作成
サンプル・ソケット・トランスポート・プロバイダのbuild.xmlとbuild.propertiesを参照して、コンパイル、ビルド、およびデプロイ用の異なる対象を含むAntビルド・ファイルとプロパティ・ファイルを作成します。
90
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
91
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
カスタム・トランスポートのデプロイ
• トランスポート・プロバイダのデプロイ可能なEARファイルを作成したら、OSBドメインイデプロイする必要があります。EARは、以下のいずれかの方法でデプロイすることができます
• プログラムを実行します(WebLogic Deployment Manager JSR-88 APIを使用)
• Oracle WebLogic Server管理コンソールを使用します。
• 以下のようなOSBドメインのconfig.xmlファイルに追加します。
<app-deployment>
<name>My Transport Provider</name>
<target>AdminServer, myCluster</target>
<module-type>ear</module-type>
<source-path>$USER_INSTALL_DIR$/servicebus/lib/mytransport.ear</source-path>
<deployment-order>1234</deployment-order>
</app-deployment>
92
Copyright© 2012, Oracle. All rights reserved.
AGENDA 1. トランスポートSDKの用途
2. カスタム・トランスポートの開発
• 開発の流れ
• 開発必要の判断
• トランザクション対応/非対応の判断
• メッセージ・パターンの判断
• トランスポート・コンポーネントの理解
• プロジェクト・ディレクトリの作成
• 構成ファイルの作成
• 固有のXMLスキーマの作成
• ユーザー・インタフェースの作成
3. 使用するJARとクラスの紹介
93
• エンドポイントのデプロイ
• メタデータとヘッダーの表示
• メッセージ・コンテンツの表示
• インバウンドの処理
• アウトバウンドの処理
• Eclipse用のトランスポートの開発
• カスタム・トランスポートの登録
• ビルドとプロパティ・ファイルの作成
• カスタム・トランスポートのデプロイ
Copyright© 2012, Oracle. All rights reserved.
利用する主なJAR
• <OSB_Home>¥lib¥sb-kernel-api.jar
• <OSB_Home>¥modules¥com.bea.common.configfwk_1.5.0.0.jar
• <OSB_Home>¥modules¥com.bea.core.xml.xmlbeans_2.1.0.0_2-5-1.jar
• <WLS_Home>¥server¥lib¥weblogic.jar
• <Middleware_Home>¥modules¥com.bea.core.weblogic.security.identity_1
.1.2.1.jar
• <Middleware_Home>¥modules¥com.bea.core.i18n_1.8.0.0.jar
• <Middleware_Home>¥jdk160_24¥jre¥lib¥rt.jar
94
Copyright© 2012, Oracle. All rights reserved.
トランスポートSDKクラスの概要
• TransportManagerHelperクラス:クライアントがトランスポート・サブシステムに関する一部の一般的なタスクを実行できるようにするヘルパー・クラス。
• ServiceInfoクラス: トランスポートの構成およびバインディング・タイプなどのサービスについての情報を示すラッパー・クラス
• RequestHeaders,ReponseHeadersクラス:任意のインバウンド・リクエスト・メッセージまたはアウトバウンド・リクエスト・メッセージの、標準およびユーザー定義のヘッダーのユニオンを表します。一連の標準ヘッダーは、各トランスポート・プロバイダに固有です。これは、それぞれのバージョンのリクエスト・ヘッダーまたはレスポンス・ヘッダーを実装するために、各トランスポート・プロバイダによって拡張される必要のある抽象クラスです。
• RequestHeaders,ReponseHeadersクラス:任意のインバウンド・リクエスト・メッセージまたはアウトバウンド・リクエスト・メッセージの、標準およびユーザー定義のヘッダーのユニオンを表します。一連の標準ヘッダーは、各トランスポート・プロバイダに固有です。これは、それぞれのバージョンのリクエスト・ヘッダーまたはレスポンス・ヘッダーを実装するために、各トランスポート・プロバイダによって拡張される必要のある抽象クラスです。
• TransportUIFactoryクラス: トランスポートの変更フィールドおよびフィールドに関連付けられている様々なTransport UIオブジェクトを作成するファクトリ・メソッドを提供します。これらのオブジェクト内の値にアクセスするためのヘルパー・メソッドも提供します。
95
Copyright© 2012, Oracle. All rights reserved.
トランスポートSDKインタフェースの概要 • TransportManagerインタフェース:様々なトランスポート・プロバイダの管理、エンドポイントの登録、制御、インバウンド・メッセージおよびアウトバウンド・メッセージの処理などを一元化するための主要ポイントを提供するシングルトン・オブジェクト。
• TransportProviderインタフェース: 転送プロトコル固有の構成および実行時プロパティの中心的な管理ポイントを表します。サポートされているプロトコルごとに、TransportProviderの単一のインスタンスが存在します。たとえば、HTTPトランスポート・プロバイダやJMSトランスポート・プロバイダに、それぞれ単一のインスタンスが存在します。
• SelfDescribedTransportProviderインタフェース:TransportProviderを拡張します。任意のトランスポート・エンドポイントからサービスのバインディング・タイプについての説明を生成するトランスポート・プロバイダは、このインタフェースを実装する必要があります。この例としては、EJBトランスポート・プロバイダがあります。
• TransportCustomBindingProviderインタフェース:SOAPバインディングまたはカスタムOSBバインディングの要素を拡張します。
• TransportProviderFactoryインタフェース:EclipseでカスタムOSBトランスポートを実装します。
• EndPointOperationsインタフェース:様々なタイプのトランスポート・エンドポイントのライフサイクル関連のイベントについて説明します。このイベントによって、トランスポート・プロバイダへの通知を行います。ネストされたクラスには、CommonOperation、Create、Delete、EndPointOperationTypeEnum、Resume、Suspend、およびUpdateがあります。
• ServiceTransportSenderインタフェース:トランスポート・エンドポイントに関連付けられている登録済のサービスにアウトバウンド・メッセージを送信します。TransportProvider.sendMessageAsync()は、(TransportSenderを拡張する)ServiceTransportSenderのインスタンスを取得します。プロバイダは、このインスタンスから、アウトバウンド・リクエストのペイロードおよびメタデータを取得できます。
96
Copyright© 2012, Oracle. All rights reserved.
トランスポートSDKインタフェースの概要
• Sourceインタフェース:任意の形式のソース・コンテンツを表します。Sourceは、Transformerインスタンスを介して他のSourceに変換できます。Sourceは、少なくとも、このインスタンスで定義されている2つメソッドを介して、バイト・ベースのストリームへの変換をネイティブにサポートする必要があります。Sourceでは、シリアライゼーション中に文字セット・エンコーディングなどの様々なTransformOptionsを考慮することもできます。
• TransportEndPointインタフェース:トランスポート・エンドポイントは、サービス・メッセージの送信元または送信先となるOracle Service Busのエンティティまたはリソースです。
• Transformerインタフェース:あるタイプのSourceを別のタイプに変換します。このインスタンスは、どのタイプのソース間で変換できるかを示します。サポートされる入力ソースおよび出力ソースによって示される完全な製品間トランスフォーメーションをサポートするには、トランスフォーマが必要です。つまり、トランスフォーマは、サポートされるすべての入力ソースを、サポートされるすべての出力ソースに変換できる必要があります。
• InboundTransportMessageContext/OutboundTransportMessageContextインタフェース:インバウンド・メッセージのメッセージ・コンテキストまたはアウトバウンド・メッセージ・コンテキストの抽象化を実装します。
• TransportSendListenerインタフェース:これは、アウトバウンド・トランスポートに提供されるコールバック・オブジェクトで、システムにレスポンス処理を進めることができることを通知できるようにします。このコールバック・オブジェクトは、リクエスト・メッセージとは別のスレッドで呼び出す必要があります。
• TransportUIBindingインタフェース:サービスの定義、概要、およびトランスポート・プロバイダ固有のエンドポイントの構成の検証で使用される、プロバイダ固有のUIページを表示するオブジェクトを表します。
97
Copyright© 2012, Oracle. All rights reserved.
スキーマで生成されるインタフェースの概要
• インタフェースの多くは、XMLスキーマ・コンパイラ・ツールによってXMLから生成されます。以下のインタフェースのソース(XMLスキーマ)は、ファイルTransportCommon.xsdで提供されています。このファイルは、サービス・エンドポイントの構成用の基本となるスキーマ定義ファイルです。
• EndPointConfiguration:エンドポイント構成のベース・タイプ。エンドポイントは、メッセージの送信元または送信先となるOracle Service Busリソースです。EndPointConfigurationは、インバウンド・エンドポイントまたはアウトバウンド・エンドポイントのデプロイメントおよび操作に必要なパラメータ一式を示します。
• TransportProviderConfiguration:このプロバイダが(a)エンドポイントのサービスの説明(WSDLなど)を生成するかどうか、(b)インバウンド(プロキシ)エンドポイントをサポートするかどうか、または(c)
アウトバウンド(ビジネス・サービス)エンドポイントをサポートするかどうかを構成できます。
• RequestHeadersXML, ResponseHeadersXML:一連のインバウンドまたはアウトバウンドのリクエスト・ヘッダーまたはレスポンス・ヘッダーのベース・タイプ。
• RequestMetaDataXML,ReponseMetaDataXML:インバウンドまたはアウトバウンドのリクエストまたはレスポンスのメタデータのベース・タイプ。メタデータは、メッセージのペイロードに含まれず、個別に送信され、メッセージを処理するための「コンテキスト」として使用されます。メタデータとして送信できる情報の例には、Content-Typeヘッダー、セキュリティ情報、ロケール情報などがあります。
98
Copyright© 2012, Oracle. All rights reserved.
参考情報
• 製品マニュアル
• 「Oracle Fusion Middleware Developer’s Guide for Oracle Service Bus」 のPart VI
Transport SDK
• http://docs.oracle.com/cd/E24001_01/doc.1111/e15866/part_tsdk.htm#sthref957
• 書籍
• 「The Definitive Guide to SOA: Oracle Service Bus」のChapter 16
• By David Schorow , Jeff Davies , Samrat Ray ,
David Rieber
99
Copyright© 2012, Oracle. All rights reserved.
Copyright© 2012, Oracle. All rights reserved. 101