この章では、Oracle Service Busで使用できるカスタムOracle XQuery関数について説明します。
Oracle XQueryエンジンは、XQueryのWorld Wide Web (W3C)仕様で説明する、モジュール以外のすべての言語機能を完全にサポートしています。XQuery 1.0およびXPath 2.0の関数と演算子(W3Cの作業草案、2004年7月23日)の詳細は、http://www.w3.org/TR/2004/WD-xpath-functions-20040723/
を参照してください。
Oracle Service Busでは、以下のXQuery関数をサポートしています。
W3C仕様で説明するXQuery関数の堅牢なサブセット。
いくつか例外はありますが、Oracle XQueryエンジンの一部として提供されるOracle拡張関数および言語キーワード(43.1項「Oracleでサポートされる拡張関数」を参照)。
Oracle Service Bus固有の拡張関数。43.2項「Oracle Service Busでの拡張関数」を参照してください。
注意: すべてのOracleの拡張関数で、次の関数接頭辞 fn-bea: function_name. |
すべてのOracle拡張関数については、http://download.oracle.com/docs/cd/E13162_01/odsi/docs10gr3/xquery/extensions.html
にある『XQueryおよびXQSE開発者ガイド』の「XQueryの実装」を参照してください。
Oracle Service Busでは、XQueryに対し、次のものを除くすべてのOracle拡張関数がサポートされています。
fn-bea:is-access-allowed
fn-bea:is-user-in-group
fn-bea:is-user-in-role
fn-bea:userid
fn-bea:async
fn-bea:timeout
fn-bea:get-property
fn-bea:execute-sql()
以下の関数は使用しないでください。他の言語機能で代用することをお薦めします。
fn-bea:if-then-else
fn-bea:QName-from-string
fn-bea:sql-like
Oracle Service Busには、以下のXQuery関数が用意されています。
fn-bea:lookupBasicCredentials
関数は、指定されたサービス・アカウントのユーザー名と暗号化されていないパスワードを返します。任意のタイプのサービス・アカウントを指定できます(静的、パススルー、またはユーザー・マッピング)。第17章「サービス・アカウント」を参照してください。
fn-bea:lookupBasicCredentials
関数は、カスタム・トランスポート・ヘッダー、またはSOAPエンベロープのアプリケーション固有の場所にあるユーザー名とパスワードのエンコードに使用するXQuery関数の大規模なセットの一部として使用します。HTTP認証ヘッダーにユーザー名とパスワードだけを含める必要がある場合、またはWS-Securityユーザー名トークンとしてユーザー名とパスワードだけを必要とする場合は、この関数を使用する必要はありません。Oracle Service Busは事前にサービス・アカウントからユーザー名とパスワードを取得し、必要に応じてHTTP認証ヘッダーにエンコードします(WS-Securityユーザー名トークンの場合も同様)。
関数には以下の署名が含まれます。
fn-bea:lookupBasicCredentials( $service-account as xs:string ) as UsernamePasswordCredential
ここで、$service-account
は、次の形式のサービス・アカウントのパスと名前です。
project-name[/folder[...]]/service-account-name
戻り値は、以下の形式のXML要素です。
<UsernamePasswordCredential xmlns="http://www.bea.com/wli/sb/services/security/config"> <username>name</username> <password>unencrypted-password</password> </UsernamePasswordCredential>
返された要素をユーザー定義の変数に保管し、必要なときにこの変数からユーザー名とパスワード値を取得できます。
たとえば、Oracle Service Busプロジェクトには、myProject
という名前が付けられます。myServiceAccount
という名前の静的なサービス・アカウントを、myFolder1/myFolder2
という名前のフォルダに作成します。サービス・アカウントに、ユーザー名pat
とパスワードpatspassword
を保存します。
サービス・アカウントのユーザー名とパスワードを取得するには、以下の関数を呼び出します。
fn-bea:lookupBasicCredentials( myProject/myFolder1/myFolder2/myServiceAccount )
関数は以下の要素を返します。
<UsernamePasswordCredential xmlns="http://www.bea.com/wli/sb/services/security/config"> <username>pat</username> <password>patspassword</password> </UsernamePasswordCredential>
特定のユーザーが特定のグループに所属するかどうかを返します(trueまたはfalse)。例:
fn-bea:isUserInGroup($user-name as xs:string, $group-name as xs:string)
特定のユーザーが特定のロールに所属するかどうかを返します(trueまたはfalse)。例:
fn-bea:isUserInRole($user-name as xs:string, $role-name as xs:string)
関数fn-bea:uuid
は、汎用一意識別子を返します。関数には以下の署名が含まれます。
fn-bea:uuid() as xs:string
この関数をプロキシ・パイプラインで使用して、ユニークな識別子を生成できます。生成されたユニークな識別子を、要素としてXMLドキュメントに挿入できます。システム変数にユニークな識別子は生成できません。これを、メッセージ・ペイロードの変更に使用できます。
たとえば、トラッキング用にユニークな識別子を生成してメッセージに追加するとします。この関数を使用してユニークな識別子を生成できます。関数が返す文字列をSOAPヘッダーに追加できます。
fn-bea:execute-sql()
関数を使用すると、Oracle Service Busのメッセージ・フローでXQueryから低レベルのデータベースにアクセスできます。詳細は、37.9項「XQueryを使用したデータベースへのアクセス」を参照してください。問合せは、型付きデータを含むフラットな行要素のシーケンスを返します。
関数には以下の署名が含まれます。
fn-bea:execute-sql( $datasource as xs:string, $rowElemName as xs:QName, $sql as xs:string, $param1, ..., $paramk) as element()*
説明:
$datasource
はデータソースのJNDI名。
$rowElemName
は行要素の名前。$rowElemName
を、結果の要素シーケンスの各要素に付けるQNameとして指定します。
$sql
はSQL文。
$param1, ..., $paramk
は1 - k個のパラメータ。
element()*
は返された要素のシーケンスを表します。
戻り値は、型付きデータを含むフラットな行要素のシーケンスで、SQL/JDBCデータ・モデルとXQueryデータ・モデル間で値を自動的に変換します。サポート対象のデータベースについてXQueryエンジンが生成する、またはサポートするデータ型マッピングの詳細は、付録H「XQuery-SQLマッピング参照」を参照してください。
Oracle Service Busメッセージ・フローからfn-bea:execute-sql()
関数を実行する場合、返された要素をユーザー定義の変数に格納できます。
以下の例では、Oracle Service Busでのfn-bea:execute sql()
関数の使用方法について説明します。
Oracle Service Busプロキシ・サービスでは、実行時のメッセージのルーティング(動的)先であるURIの仕様をサポートしています。詳細は、37.8項「動的ルーティングの使用」を参照してください。例43-1は、動的ルーティング・シナリオでデータベースからURIを取得するfn-bea:execute-sql()
関数の使用例を示しています。
例43-1 データベースからのビジネス・サービスのURIの取得
<ctx:route><ctx:service> { fn-bea:execute-sql( 'ds.myJDBCDataSource', xs:QName('customer'), 'SELECT targetService FROM DISPATCH_MAPPING WHERE customer_priority=?', xs:string($body/m:Request/m:customer_pri/text()) )/TARGETSERVICE/text() } </ctx:service></ctx:route>
例43-1では、次のようになります。
ds.myJDBCDataSource
はデータ・ソースのJNDI名。
xs:string($body/m:Request/m:customer_pri/text())
は、リクエスト・メッセージを確認し、メッセージにcustomer_pri
の値を含むcustomer_priority=?
を生成します。
/TARGETSERVICE/text()
はSQL文の結果に適用されるパス。返される要素の文字列(CDATA)コンテンツを生成します。
<ctx:route><ctx:service> ... </ctx:service></ctx:route>
は、動的ルーティング・シナリオのXQuery文に必須の要素。
DISPATCH_MAPPING
の表定義を次に示します。
create table DISPATCH_MAPPING ( customer_priority varchar2(256), targetService varchar2(256), soapPayload varchar2(1024) );
例43-2に示すように、DISPATCH_MAPPING
表に値が設定されます。
例43-2 DISPATCH_MAPPING表
INSERT INTO DISPATCH_MAPPING (customer_priority, targetService, soapPayload) VALUES ('0001', 'system/UCGetURI4DynamicRouting_proxy1', '<something/>'); INSERT INTO DISPATCH_MAPPING (customer_priority, targetService, soapPayload) VALUES ('0002', 'system/UCGetURI4DynamicRouting_proxy2', '<something/>');
注意: このシナリオでは、表の3列目( |
例3のfn-bea:execute-sqlの実行
プロキシ・サービスが例43-3のリクエスト・メッセージ(リクエスト・メッセージの<customer_pri>
の値は0001
)を受信した結果として、 例43-1のXQueryが実行された場合、動的ルーティング・シナリオで返されるURIは次のようになります。
system/UCGetURI4DynamicRouting_proxy1
(例43-2も参照してください。)
サポート対象のデータベースについてXQueryエンジンが生成またはサポートするデータ型マッピングの詳細は、付録H「XQuery-SQLマッピング参照」を参照してください。SQLのXMLType
列タイプはサポートされていません。ただし、XMLType
オブジェクトの getStringVal()
メソッドを使用してXMLType
列のデータにアクセスし、文字列値に変換できます。
以下のシナリオでは、Oracle DatabaseのXMLType
列からデータを選択する際に使用できる手順について説明します。
プロキシ・サービスのメッセージ・フローで割当てアクションを使用して、次のXQueryの結果を変数($result
)に割り当てます。
例43-4 データベースからのXMLTypeデータの取得
fn-bea:execute-sql( 'ds.myJDBCDataSource', 'Rec', 'SELECT a.purchase_order.getStringVal() purchase_order from datatypes a' )
説明:
ds.myJDBCDataSource
はデータ・ソースのJNDI名。
Rec
は$rowElemName
。したがって、Recは結果の要素シーケンスの各要素に指定されたQNameです。
select a.purchase_order.getStringVal() ...
は、文字列値に変換するために、XMLType
オブジェクトのgetStringVal()
メソッドを使用するSQL文。
datatypes
は、XMLの値の読込み元である表(この場合、datatypes
表には1つの行が含まれています)。
注意:
create table datatypes ( purchase_order xmltype ); |
次の置換アクションを使用して、$body
のノードのコンテンツを(前の手順で$result
に割り当てた)fn-bea:execute-sql()
問合せの結果に置き換えます。
Replace [ node contents ] of [ undefined XPath ] in [ body ] with [ $result/purchase_order/text() ]
以下のサンプル・コードは、置換後の$body
を示します。
例43-5 XMLコンテンツをfn-bea:execute-sql()の結果に置き換えた後の$body
<soap-env:Body> <openuri:orders xmlns:openuri="http://openuri.com/"> <openuri:order> <openuri:customerID>123</openuri:customerID> <openuri:orderID>123A</openuri:orderID> </openuri:order> <openuri:order> <openuri:customerID>345</openuri:customerID> <openuri:orderID>345B</openuri:orderID> </openuri:order> <openuri:order> <openuri:customerID>789</openuri:customerID> <openuri:orderID>789C</openuri:orderID> </openuri:order> </openuri:orders> </soap-env:Body>
XMLドキュメントをXML要素としてではなく文字列として表す必要がある場合は、fn-bea:serialize()
関数を使用します。たとえば、EJBインタフェースを介してXMLドキュメントを交換する場合、EJBメソッドは引数を文字列として受け取ります。関数には以下の署名が含まれます。
fn-bea:serialize($input as item()) as xs:string