原文はこちら。
https://blogs.oracle.com/bpmtech/entry/handling_humantask_attachments_in_oracle1
アップロードした添付ファイルを取り出す -UCMのドキュメントの場合-
前のエントリでお伝えした通り、Oracle BPM 11g 11.1.1.5.1 (PS4FP) では、Oracle WebCenter Content(以前はOracle UCMとして知られていました)をHuman Taskの添付ドキュメントのリポジトリとして利用できるという新しいクールな機能が導入されました。この機能の使い方や機能を有効にする方法の詳細は以下のリンクをご確認下さい。
Oracle Fusion Middleware Oracle Business Process Managementモデリングおよび実装ガイド
11g リリース1(11.1.1.6.0)
27.7.2 タスクの添付を格納するようにOracle UCMリポジトリを構成する方法
http://docs.oracle.com/cd/E28389_01/doc.1111/b61409/designing_human_tasks_bpmpd.htm#CIHBBFBE (日本語)
Oracle Fusion Middleware Modeling and Implementation Guide for Oracle Business Process Management 11g Release 1 (11.1.1.6.0)
27.7.2 How to Configure Oracle UCM Repository to Store Task Attachments
http://docs.oracle.com/cd/E23943_01/doc.1111/e15176/designing_human_tasks_bpmpd.htm#CIHBBFBE (英語)
添付ファイルのスコープ(TASKもしくはPROCESS)はUCM添付ファイルにおいても有効です。しかし、この他の機能を使っていても、UCMの添付ファイルを使用している場合には一つの疑問、「プロセス内からどうやって取り出すことができるのか」という疑問が浮かぶかもしれません。
最初の答えは、以前のエントリで説明した同じgetTaskAttachmentContents() XPath関数を使用することです。実際に、これがあるべき姿です。しかし、Oracle BPM11g 11.1.1.5.1(PS4FP)および11.1.1.6.0(PS5)では、バグのせいで使えません。UCMの添付ファイルに対して、この関数を呼び出す場合は、NULLコンテンツの応答を受け取ることになるでしょう (bug#13907552)。添付ファイルが正常にアップロードされた場合でも同様です。
このバグが修正されるまでの間、UCMの添付ドキュメントをBPMプロセスから取り出す次のような回避策をご紹介しましょう。また、サンプルでは、BPMのプロセス内からWebCenterContent APIと対話する方法もご紹介します。
[注意]Human Taskの添付ファイルに関する前回のエントリをご覧になっていることを前提としています。
execData/attachment[]
構造体なども使います。
サンプルプロセス
次のようなサンプルプロセスを使います。
"HumanTask2" Human Taskを使うダミーの UserTaskに続いて、添付ファイルのペイロードを取り出す組み込みサブプロセスが続きます。この場合、WebCenter Content Web Service API (IDC) を使うところがこの例のキーポイントです。
添付ファイルを取り出したら、それぞれをFile Adapterを使ってサーバにファイルとして書き戻します。
詳細
- 前回のエントリと同じ、
attachmentCollection
XMLスキーマと BusinessObject 定義を使いますが、別の変数名を付けます( attachmentUCM
)。
- We will still need to keep a copy of the HumanTaskの出力
execData
構造体のコピーを保持しておく必要があるので、 TaskExecutionData
型の新しい変数を作成します(この TaskExecutionData
型はUCMを使わない添付ファイルで使っているものとは異なります)。
- UCMを使わない添付ファイルの場合と同様、 UserTaskのマッピングのoutputタブで、
execData
構造体をコピーしておきます。
- では、組み込みサブプロセスにて、添付ファイルのペイロードを取り出しましょう。まず、XSLT変換を使って、
attachmentUCM
変数に以下の情報を格納します。
- 各添付ファイルの名前(
execData/attachment/name
要素から)
- アップロードされた添付ファイルのWebCenter Content ID。この情報は
execData/attachment/URI
要素に ecm://<id>
の形式で保存されています。数値の <id>
だけが必要なので、protocol prefix、つまり ecm://
を取り除く必要があります。そのためには、以下のようなXPath関数を使います。
これらの2個の関数をそれぞれ呼び出しています。
- 前回のエントリと同様、ターゲットのペイロード要素に空文字を設定して
<payload></payload>
タグを作成します。
完全なXSLT変換は以下のようになります。XSLTの
for-each
ノードを使って必要なだけのターゲットの構造を作成していることを覚えておいて下さい。
attachmentsUCM
構造体に値を設定されると、各添付ファイルの名前がWebCenter ContentのユニークなID (dID
) と共に入っていますので、反復処理をしてペイロードを取り出しましょう。そのため、新しく MultiInstance
タイプの組み込みサブプロセスを使って attachmentsUCM/attachment[]
要素を反復処理します。
- 各反復処理にて、サービスアクティビティを使いWebCenter ContentのAPIをWebサービス経由で呼び出します。以下の手順で必要なパートナーリンクを作成・設定します。
- WebCenter Contentのコンソールに管理者(weblogic)としてログインします。管理メニュー(Administration)に移動して、"Soap Wsdls"のリンクをクリックします。今回は GetFile サービスを使って
dID
に基づくファイルを取り出します。そのため、このサービスのWSDL定義が必要で、GetFile
のリンクをクリックすればダウンロードできます。JDeveloperのプロジェクトフォルダにWSDLファイルを保存します。
- In the BPMプロジェクトのコンポジットビューで、Webサービスアダプタをドラッグアンドドロップし、先ほど取り込んだGetFile.wsdlを元にして新たに外部参照を作成し、名前を
UCM_GetFile
としておきます。
- WebCenter ContentサービスはベーシックHTTP認証で保護されていますので、作成した参照が使えるよう、以下の設定をしておきます。
- 参照を右クリックして、WSポリシーの構成を選択
- 「セキュリティ」セクションで "+" をクリックして "
oracle/wss_username_token_client_policy
" ポリシーを追加
- 最後に、セキュリティポリシーの資格証明を設定します。サンプルとして、WebCenter Contentの管理ユーザ(
weblogic
/welcome1
)を使うことにします。composite.xml
ファイルを開き、ソースビューを選択します。
UCM_GetFile
エントリを検索し、以下のXMLのうち、赤で強調した要素を追加します。
<reference name="UCM_GetFile" ui:wsdlLocation="GetFile.wsdl">
<interface.wsdl interface="http://www.stellent.com/GetFile/#wsdl.interface(GetFileSoap)"/>
<binding.ws port="http://www.stellent.com/GetFile/#wsdl.endpoint(GetFile/GetFileSoap)"
location="GetFile.wsdl" soapVersion="1.1">
<wsp:PolicyReference URI="oracle/wss_username_token_client_policy"
orawsp:category="security" orawsp:status="enabled"/>
<property name="weblogic.wsee.wsat.transaction.flowOption"
type="xs:string" many="false">WSDLDriven</property>
<property name="oracle.webservices.auth.username"
type="xs:string">weblogic</property>
<property name="oracle.webservices.auth.password"
type="xs:string">welcome1</property>
</binding.ws>
</reference>
- 外部参照が作成できたので、BPMプロセスより使えるようになっているはずです。しかしここで問題があります。WebCenter Contentの GetFile サービスのオペレーションを使おうとしていますが、GetFileByID は入力パラメータとしてこれと類似の構造を受け入れるのですが、全ての要素タグが必須ではないのです。
<get:GetFileByID xmlns:get="http://www.stellent.com/GetFile/"
>
<get:dID>?</get:dID>
<get:rendition>?</get:rendition>
<get:extraProps>
<get:property>
<get:name>?</get:name>
<get:value>?</get:value>
</get:property>
</get:extraProps>
</get:GetFileByID>
そして、
<get:dID>
タグ要素のみ埋めたいのですが、WebCenter Contentの制限もしくは不具合のために、残りのタグ要素を送信してはいけません。それは空要素(つまり、
<get:rendition></get:rendition>
や
<get:rendition/>
)であってもです。
dID
でのみ問い合わせを実行するリクエストのサンプルは以下のような形式で記述する必要があります。
<get:GetFileByID
xmlns:get="http://www.stellent.com/GetFile/"
>
<get:dID>12345</get:dID>
</get:GetFileByID>
簡単なBPMでのマッピングでは以下のような結果のサンプルのように空タグを作成するところに問題があります。
<get:GetFileByID xmlns:get="http://www.stellent.com/GetFile/">
<get:dID>12345</get:dID>
<get:rendition/>
<get:extraProps/>
</get:GetFileByID>
上記の構造は完全に妥当ではありますが、WebCenter Contentは受け入れないので、この問題を回避する必要があります。回避策は数多ありますが、今回は、単に入力データをBPMからコピーするというMediatorコンポーネントをBPMプロセスとサービス間に配置し、空タグを取り除きます。以下の手順に従ってMediatorコンポーネントを構成します。
- Mediatorコンポーネントをドラッグアンドドロップしてコンポジットに貼り付けます。
- 「SOAPバインディングの作成」のチェックを外し、「WSDLからインターフェースを定義」のテンプレートを使って、既存の GetFile.wsdl を選択します。
- Mediatorコンポーネントをダブルクリックして編集します。
GetFileByID
オペレーションへの静的ルーティングルールを追加して、サービスタイプから References/UCM_GetFile/GetFileByID
をターゲットのサービスに指定します。
- リクエストとリプライのXSLTマッパーを作成します。
リクエストでは dID 要素のみマッピングします。
レスポンスは全体を自動マッピングします。
- ようやくサービスアクティビティをBPMプロセスに追加し設定することができます。組み込みサブプロセスにドラッグアンドドロップして
NormalizedGetFile
サービスと getFileByID
オペレーションを選択します。
- 組み込みサブプロセスの作業が終了したら、全ての添付ファイル(名前とペイロード)が
attachmentsUCM
変数に入っていることになり、このサンプルの主要な目的が完了します。しかし、全てが良好に動作することを確認するため、サンプルに添付ファイルをファイルに書き出させましょう。その目的のために最後に組み込みサブプロセスを追加して同時に各 attachmentsUCM/attachment[]
要素を反復処理させます。
- 各反復処理にて、サービスアクティビティを使ってFile Adapterのwriteサービスを呼び出します。ここで設定すべき2個の重要なパラメータがあります。一つはペイロードそのものです。File Adapterはbase64形式(文字列)のバイナリデータを期待しているため、XPathを使ってマッピングする必要があります(単純なマッピングだとbase64バイナリの妥当なターゲットとして文字列が認識されません)。
もう一つは、ターゲットの
filename
をサービスプロパティダイアログボックスを使って設定する必要があります。
組み込みサブプロセスの反復処理にて、インデックス変数
loopCounter
を使って適切な要素を取得していることに着目して下さい。
添付ファイルに関するエントリの最後として、ドキュメントをBPMプロセスからHuman Taskに注入する方法をご紹介します。また、異なるUser Task間で添付ファイルを共有する方法についても取り上げます。
添付ファイルに関連するエントリが全て終了したら、サンプルプロジェクトをjava.netにUpする予定にしています。
Oracle BPM 11gサンプルコード
http://java.net/projects/oraclesoasuite11g/pages/BPM