Oracle Service Busの機能を拡張できるようにするために、プロキシ・サービス内からカスタムJavaコードを呼び出すことができます。Oracle Service Busでは、POJO (Plain Old Java Object)へのコールアウトを可能にする「Javaコールアウト」アクションを使用したJava終了メカニズムをサポートしています。
POJOからは静的メソッドにアクセスすることが可能です。POJOとそのパラメータは、設計時にOracle Service BusコンソールまたはEclipse用Oracle Service Busプラグインに表示されます。パラメータは、メッセージ・コンテキスト変数にマップできます。
また、 Javaコールアウトを使用してJavaオブジェクトを作成し、パイプラインに格納したり、Javaオブジェクトをパラメータとして他のJavaコールアウトに渡したりすることもできます。
POJOへのJavaコールアウトの構成については、22.20項「Javaコールアウト・アクションの追加」を参照してください。
Oracle Service BusでJavaコールアウトを使用できるシナリオは以下のとおりです。
カスタム検証 - カスタム検証の例には、DTDの検証、またはJavaでのフィールド間のセマンティックの検証があります。
カスタム・トランスフォーメーション - カスタム・トランスフォーメーションの例には、バイナリ・ドキュメントのbase64Binaryへの変換、base64Binaryのバイナリ・ドキュメントへの変換、またはカスタムJavaトランスフォーメーション・クラスの使用があります。
カスタム認証とカスタム認可 - カスタム認証とカスタム認可の例には、メッセージ内のカスタム・トークンを認証および認可する必要があるシナリオがあります。ただし、Oracle Service Busは、プロキシ・サービスによって以降に呼び出されるサービスまたはPOJOに、認証されたユーザーのIDを伝播することはできません。
メッセージに情報を追加するためのルックアップ - たとえば、ファイルまたはJavaテーブルを使用して、メッセージに情報を追加できる任意のデータをルックアップできます。
バイナリ・データ・アクセス - POJOへのJavaコールアウトを使用してバイナリ・ドキュメントの最初の数バイトを検出し、MFLの型を推測します。返されるMFL型は、次の MFL変換 アクションによる非XMLからXMLへのトランスフォーメーションで使用されます。
カスタム・ルーティング・ルールまたはルール・エンジンの実装
Javaオブジェクトの作成とパイプラインへの格納
別のJavaコールアウトへのJavaオブジェクトのパラメータとしての受け渡し
JEJBプロキシ・サービスを使用したJEJBによるリモートEJB操作またはサービスの呼出し。
Javaコールアウトの入力と戻りの型は制限されていません。Javaオブジェクトのパイプラインでの格納と受渡しの詳細は、38.3.5項「body変数内のJavaコンテンツ」を参照してください。
Enterprise JavaBeans (EJB)もJava終了メカニズムを提供します。次の場合は、Javaコールアウトではなく、EJBを使用することをお薦めします。
EJB実装がすでにある場合。ただし、JEJBトランスポートでOracle Service Busを介してEJBコールによりEJBを呼び出し、メッセージ・ルーティング、UDDI統合、アラート、操作ごとのモニター、レポート、結果キャッシュなどのOracle Service Busの機能を利用できます。
JDBCデータベースに対する読込みアクセスが必要な場合。JDBCデータベースに対する読込みアクセス権のために、POJOを使用することもできますが、EJBはこの目的のために特別に設計されており、JDBCリソースの管理およびJDBCリソースへの接続のサポートが強化されます。
JDBCデータベースまたは他のJ2EEトランザクション対応リソースへの書込みアクセスが必要な場合。EJBはトランザクション対応のビジネス・ロジック向けに特別に設計されており、障害に対する適切な処理へのサポートが強化されます。ただし、トランザクションとセキュリティ・コンテキスト伝播はPOJOを使用してサポートされ、JEJBトランスポートで、トランザクション・コンテキストでのエラー処理が提供されます。
アウトバウンド・メッセージには、POJOまたはEJBを使用するかわりにカスタム・トランスポートを記述することをお薦めします。
バイナリ・コンテンツを入力引数としてコールアウト・メソッドに渡すため、およびJavaコールアウト・メソッドからストリーミング・コンテンツの結果を受け入れるために、Javaコールアウトを使用してストリーミング・コンテンツを操作できます。
Javaコールアウト・メソッドに、バイナリ・コンテンツを入力引数としてストリーミング形式で渡すことができます。Oracle Service Busは入力引数のJavaタイプを確認して処理します。引数のタイプがjavax.activation.DataSource
の場合、システムはラッパーDataSource
オブジェクトを作成し、Source.getInputStream()
メソッドを呼び出して、対応するソースからInputStream
を取得します。このメソッドは、Javaコールアウト・コードから必要なだけ何回でも呼び出すことができます。
また、getContentType()
メソッドは、バイナリ・コンテンツがページングされたMIME添付ファイルでないかぎり、application/octet-stream
を返します。バイナリ・コンテンツがページングされたMIME添付ファイルである場合は、対応するMIME部分のContent-Typeヘッダー(存在する場合)が使用されます。
同様に、getName()
メソッドは、バイナリ・コンテンツがページングされたMIME添付ファイルでないかぎり、バイナリ・コンテンツの参照属性の文字列値を返します。バイナリ・コンテンツがページングされたMIME添付ファイルである場合は、対応するMIME部分のContent-IDヘッダー(存在する場合)が使用されます。getOutputStream()
メソッドは必要に応じてUnsupportedOperationException
をスローします。
完了後、結果はJavaコールアウト・メソッド引数に渡されます。入力ストリームのバイナリ・オクテットを正しく解釈するために、Javaコールアウト・メソッドでContent-Transfer-Encodingヘッダーの値が必要な場合もあります(たとえば、エンコーディングがバイナリ、7ビット、8ビットのいずれであるかを判別する場合ど)。次に示すように、このパラメータを別個の引数として渡すことができます。
$attachments/*:attachment[1]/*:Content-Transfer-Encoding/text()
入力引数がDataSourceでない場合、Oracle Service Busは引数をbyte[]配列に変換します。
Javaコールアウト・メソッドからストリーミング・コンテンツ結果を取得できます。この処理のために、Oracle Service Busは結果のJavaタイプを確認し、適切なコンテキスト変数の値を対応するctx:binary-content
XML要素に設定して、新しいソースをソース・リポジトリに追加します。
注意: Javaコールアウト・メソッドからファイルのコンテンツを返す場合、javax.activation.FileDataSource のインスタンスを使用することができます。 |
Oracle Service Busパイプラインがソースのバイナリ・コンテンツを必要とする場合、ctx:binary-content
要素に対応するDataSource
オブジェクトをリポジトリから検索して、バイナリ・オクテットを取得するためにDataSource.getInputStream()
メソッドを呼び出します。
getInputStream()
メソッドは、トランスポート・レイヤーでのアウトバウンド・メッセージの再試行に応じるなどのために、メッセージ処理時に何度も呼び出されることがあることに注意してください。
POJOは、Oracle Service BusでJARリソースとして登録されます。JARリソースの詳細は、第8章「JAR」を参照してください。
通常、JARはサイズを小さくし、簡単なものにすることをお薦めします。JARが呼び出すサイズの大きいコードまたは使用される大きなフレームワークは、システム・クラス・パスに含めることをお薦めします。システム・クラス・パスを変更する場合は、サーバーを再起動する必要があります。
独立したクラスおよび重複するクラスは、同じJARリソースに含め、性質上区別されるクラスは異なるJARに含めることをお薦めします。JARを変更すると、そのJARを参照するすべてのサービスが再デプロイされます。これはOracle Service Busにとって多大な時間を必要とする場合があります。同じクラスを、競合させずに複数のJARリソースに配置できます。JARは、最初に参照されたときに、動的にクラス・ロードされます。
1つまたは複数のプロキシ・サービスで、単一のPOJOを呼び出せます。プロキシ・サービスのすべてのスレッドが同じPOJOを呼び出します。そのため、POJOはスレッド・セーフであることが必要です。POJOのクラスまたはメソッドは同期できます。この場合、呼出しを行うすべてのプロキシ・サービスのすべてのスレッドによるアクセスを順序付けします。POJOコードによって、任意のより詳細な並行処理(たとえば、データベース読込みの結果キャッシュへのアクセスの制御や、古いキャッシュ・エントリ処理の実装)を実装する必要があります。
通常、POJOの場合、スレッドの作成は推奨されません。