Worklist の使い方

     前  次    新しいウィンドウで目次を開く     
ここから内容

ワークリスト イベント ベースのサービス

この節では、Java プログラマが Workshop for WebLogic で参考にできるように、高度なトピックについて説明します。内容は以下のとおりです。

 


タスク変更イベント

ワークリストは、タスクの状態に変更が生じたときにトリガできる、タスク変更イベントを定義します。ワークリストは関連するパーティ (リスナ) からイベントのサブスクリプションを受け付け、指定されたイベントの発生時にそれを通知します。リスナは、発生したイベントに基づいてタスクに適切なアクションを実行できます。

イベント配信パス

ワークリストによって生成されたイベントがたどるパスとしては、ワークリスト レポート サブシステム、Web サービス リスナ、プレーン Java リスナが考えられます。

図 5-1 イベント配信パス

イベント配信パス

注意 : この図に示されるリスナはすべてワークリスト イベント リスナであり、内部システムレベルのリスナです。カスタムのタスク イベント リスナは .listener ファイルを使用してこのツリーにプラグインされ、ワークリストのデフォルト イベント リスナの兄弟として登録されます。

イベント

ワークリストは、実行時イベントとレポート イベントの両方に対応できるように、一連のイベント タイプを定義します。イベントの 2 つの用途における実質的な違いは、レポートではタスクの変更の古い値と新しい値の両方が、より明示的に必要とされるという点のみであると想定されています。おそらく実行時イベントでは、タスクから現在の値を取得するだけで目的が達せられます。このため、タスク プロパティが変更された場合は、そのイベントのコンシューマがワークリスト API を使用してプロパティの現在の値をクエリするものと想定されます。

以下の表は、タスクに対するさまざまな処理に応じてワークリストが生成するイベントを示しています。すべてのイベントには、以下のデータ項目が含まれます (com.bea.wli.worklist.api.events.data.TaskEvent インタフェースで Java メソッドを使用してアクセスできます)。

以下の表は、特定タイプのイベントに追加されるフィールドを示しています。

イベント タイプ
発生状況
追加フィールド
イベント オブジェクト タイプ
CREATE
タスクが作成された。このイベントの後には、STEP_CHANGE イベントと、CREATE イベントの後に別々に届いた割り当て済みまたは申請済みのイベントが発生する。
TaskData、およびタスクの初期プロパティ名
(同期リスナのみ : 初期プロパティ値)
TaskCreateEvent
ASSIGN
タスクが直接割り当てられたか、新しい手順に移動した結果として、または手順において割り当てアクションを実行した結果としてタスクが割り当てられた。
NewAssigneeList、OldAssigneeList
TaskAssignEvent
CLAIM
タスクが直接申請されたか、新しい手順に移動した結果として、または手順において割り当てアクションを実行した結果としてタスクが申請された。タスクが自動申請される場合は、申請済みイベントのみが送信される。割り当て済みイベントは送信されない。
NewClaimant、OldClaimant
(自動申請の場合 : NewAssigneeList、OldAssigneeList)
TaskClaimEvent
RETURN
タスクが返された。
Reason、OldClaimant
TaskReturnEvent
TAKE_ACTION
アクションが実行された。以下のイベントが続く場合がある。
  • STEP_CHANGE イベント (別のステップを対象とする作業アクションの後)
  • タスクが割り当て済みまたは申請済みである場合は、ASSIGN イベントまたは CLAIM イベント (作業アクションの後で新しいステップに達した後、または割り当てアクションの後)
  • RETURN イベント (戻りアクションの後)
  • 新しい現在のステップが完了ステップまたは中止ステップである場合は、COMPLETE イベントまたは ABORT イベント (作業アクションの後)
NewStep、OldStep、Action、アクションのプロパティ名
(同期リスナのみ : プロパティの NewValue)
TaskStepActionEvent
STEP_CHANGE
タスクの現在の手順が変更された。このイベントは、管理操作または作業アクションによって発生する。
NewStep、OldStep
TaskStepChangeEvent
SET_USER_PROPERTY
WorklistTaskUser.setTaskProperties() によって、タスク プラン定義のプロパティが直接更新された。このプロパティがアクションの実行の一部として変更された場合は、変更されたプロパティの名前が TAKE_ACTION イベントによって示される。
PropertyName
(同期リスナのみ : OldValue、NewValue)
TaskUpdate PropertyEvent
SUSPEND
タスクがサスペンドされた。
Reason
TaskAdminEvent
RESUME
タスクが再開された。
Reason
TaskAdminEvent
SET_ERROR
タスクがエラー状態に設定された。
Reason
TaskAdminEvent
CLEAR_ERROR
タスクがエラー状態からリセットされた。
Reason
TaskAdminEvent
COMPLETE
タスクが完了した。
Reason
TaskAdminEvent
ABORT
タスクが中止された。
Reason
TaskAdminEvent
REACTIVATE
タスクが再アクティブ化された。
Reason、NewCurrentStep、OldCurrentStep
TaskReactivateEvent
SET_CURRENT_STEP
タスクの現在のステップが強制的に設定された。このイベントの後には、タスクが新しいステップに達したことを示す STEP_CHANGE イベントが発生する。
また、新しい現在のステップによっては、このイベントの後に ASSIGN、CLAIM、COMPLETE、または ABORT イベントが発生する場合がある。
Reason、OldCurrentStep、NewCurrentStep
TaskSetCurrentStep Event
SET_SYSTEM_PROPERTY
WorklistTaskUser.setTaskProperties() またはいずれかの setTask<Name>() メソッドによって、何らかのシステム プロパティが直接設定された。
このタイプのイベントを生成するシステム プロパティの詳細については、「システム プロパティと TaskUpdateBuiltInProperty イベント」を参照。
PropertyName
(同期リスナのみ : OldValue、NewValue)
TaskUpdateBuiltIn PropertyEvent
STEP_EXPIRE
タスクの手順が、スケジュールされた完了期日までに完了しなかった。
ScheduledExpireDateTime、StepName
TaskStepExpireEvent
TASK_EXPIRE
タスクが、スケジュールされた完了期日までに完了しなかった。
ScheduledExpireDateTime
TaskExpireEvent

システム プロパティと TaskUpdateBuiltInProperty イベント

以下のシステム プロパティを更新すると、ワークリストから TaskUpdateBuiltInProperty イベントが配信されることがあります。その他のシステム プロパティは読み取り専用であり、更新イベントが発生することはありません。これらのプロパティ名は、ワークリストの com.bea.wli.worklist.api.taskplan.SystemProperty 列挙からの列挙値と一致します。

タスク プランごとのイベントの制御

BEA が提供するさまざまな種類のイベント リスナは、プロデューササイドでフィルタリングを実行して、外部エンドポイントに送信されるイベントの数を制限できます。このフィルタリングは、EventHandler コンフィグレーション モジュールに含まれるイベント コンフィグレーションによって制御されます。詳細については、「EventHandler モジュール」を参照してください。

イベント ディスパッチ モード (サービスの品質)

ワークリストは、タスク インスタンスに変更が生じた場合に Java クライアントがイベントの受信に使用できる、Java リスナ インタフェース (「カスタムのタスク イベント リスナ」を参照) を定義します。リスナは、ワークリストに要求するサービス品質を指定できます。このサービス品質は、以下の条件によって定義されます。

同期配信とは、イベント生成の原因となったスレッドのスタックでリスナが呼び出されることです。非同期配信とは、イベントがまずキューに配置され、イベント生成の原因となったスレッドとは異なるスレッドのリスナに配信されることです。

リスナは、.listener ファイルによる登録時に、優先ディスパッチ モードを示すことができます。

クリティカル リスナは、サブスクライブしているすべてのイベントを必ず受信して処理し、イベントを正しく使用できない場合にはタスクにエラーを設定できるリスナです。非クリティカル リスナは、イベントの消失を許容でき、何らかのイベントを正しく処理できなくても、そのイベントのタスクにエラーを設定しないことが許可されるリスナです。非同期のクリティカル リスナに送信されるイベントは、信頼性がある永続キューに配置され、サーバ クラッシュが発生したような場合でも配信されます。非クリティカル リスナに送信されるイベントは、永続性の保証なく配信されます。このため、サーバ クラッシュが発生した場合は、配信されないこともあります。

同期クリティカル リスナとして登録されるリスナは、onTaskEvent() メソッドから例外を送出することで、タスクの変更をある程度制御することができます。同期クリティカル リスナが onTaskEvent() から例外を送出すると、現在のトランザクション (イベント発生の原因となったトランザクション) はロール バックされます。この場合、変更は事実上取り消されます。タスク インスタンスをエラー状態に設定すると、コミット可能なライブ データベース トランザクションが必要となるため、エラー状態には設定されません。

すべてのクリティカル リスナには、非クリティカル リスナの前にイベントが通知されます。クリティカル リスナが例外を送出した場合は、現在のイベントのディスパッチはそれ以後行われなくなります (また、タスク変更を保持するトランザクションはロール バックされます)。

注意 : システム管理者は、.listener ファイルを持つワークリスト アプリケーションを慎重に調べる必要があります。特に、それ自体を同期ユーザとして登録する .listener ファイルは精査が必要です。このようなリスナは、イベントの発生原因となったタスク更新を実行したユーザの ID で実行されます。このためリスナ コードは、そのユーザが実行できることであれば、どのようなことでも実行できます。同期リスナとしてのデプロイを許可するのは、信頼性のあるコードのみにする必要があります。

EventListener インタフェース

リスナは Java リスナ インタフェースを実装し、このリスナ実装を使用してイベント配信メカニズムにプラグインされます。Java リスナは、以下のリスナ インタフェースを実装する必要があります。

public interface TaskEventListener {
    /**
     * このリスナに割り当てられる名前を取得する。
     */
    public String getName();
    /**
     * このリスナの名前を取得する。
     */
    public void setName(String name);
    /**
     * この TaskEventListener をデプロイしたカスタム モジュールで、TaskEventListener に
     * コンフィグレーションされるプロパティを設定する。このメソッドは、プロパティが
     * 使用可能な場合にのみ呼び出される (カスタム モジュールのデプロイメント記述子に 
     * 例が指定されている)。
     * @param properties
     */
    public void setProperties(Map<String, Property> properties);
    /**
     * onTaskEvent() でのイベント処理の開始に必要なリソースを
     * 初期化する。
     * @throws com.bea.wli.worklist.api.ManagementException
     */
    public void initialize()
        throws ManagementException;
    /**
     * このインスタンスを破棄し、初期化時または onTaskEvent() への呼び出し中に取得された
     * リソースを解放する。
     * @throws ManagementException
     */
    public void destroy()
        throws ManagementException;
    /**
     * 対象となるイベントを処理する。
     * @throws VetoException イベントの処理時にエラーが発生した場合。 
     * ワークリストがこの例外をどのように処理するかは、リスナがどのように登録されているか
     * (同期/非同期、クリティカル/非クリティカル) によって異なる。
     */
    public void onTaskEvent(TaskEvent event)
        throws VetoException;
}

この TaskEvent は以下のとおりです。

public interface TaskEvent
    extends Serializable {
    /**
     * このイベント インスタンスが表すイベントのタイプ。リスナは、簡単な
     * フィルタリングにこのプロパティを使用できる。イベントからイベント 
     * タイプに固有のプロパティを取得するために、リスナは、このイベント
     * インスタンスの実行時タイプに基づいて、このイベントを適切なイベント
     * クラスにキャストする必要がある。
     */
    public TaskEvent.Type getEventType();
    /**
     * 変更されたタスクの ID。
     */
    public String getTaskId();
    /**
     * 変更されたタスクの名前。
     */
    public String getTaskName();
    /**
     * 変更されたタスクの ID。
     */
    public TaskPlanId getTaskPlanId();
    /**
     * このタスクを作成したユーザ。
     */
    public String getCreator();
    /**
     * このイベントが生成された時点でのオーナ。
     */
    public String getOwner();
    /**
     * このイベントが生成された時点での申請者。
     */
    public String getClaimant();
    /**
     * このイベントが生成された時点での割り当て対象リスト。
     */
    public AssigneeDefinition[] getAssigneeList();
    /**
     * このイベントが生成された時点での管理状態。
     */
    public AdminState.Type getAdminState();
    /**
     * このイベントが生成された時点での作業状態。
     */
    public WorkingState.Type getWorkingState();
    /**
     * 変更を行ったユーザのユーザ名。
     */
    public String getCaller();
    /**
     * タイムスタンプ (ローカル システム時刻を表す LONG 値)。
     */
    public long getTimestamp();
    /**
     * タスクの変更が行われたサーバの名前。
     */
    public String getServerName();
    /**
     * このイベントの最も重要な情報の概要
     * (100 文字以内)。
     */
    public String getSummary();
    /**
     * 別タイプのイベントの列挙。CLAIM_EXPIRE、START、STOP の
     * 各イベント タイプは非推奨であるため、新しい開発では
     * 使用できない。
     */
    public enum Type {
        CREATE,
        ASSIGN,
        CLAIM,
        RETURN,
        TAKE_ACTION,
        STEP_CHANGE,
        SET_USER_PROPERTY,
        //PROPERTY_SET_LOCKSTATE,
        SUSPEND,
        RESUME,
        SET_ERROR,
        CLEAR_ERROR,
        COMPLETE,
        ABORT,
        REACTIVATE,
        SET_CURRENT_STEP,
        SET_SYSTEM_PROPERTY,
        CLAIM_EXPIRE_81X, // 非推奨
        STEP_EXPIRE,
        TASK_EXPIRE,
        START_81X, // 非推奨
        STOP_81X;  // 非推奨
        public String getValue() {
            return this.name();
        }
        public static Type getFromOrdinal(int ordinal) {
            Type[] types = Type.class.getEnumConstants();
            for (int i=0; i < types.length; i++) {
                if (types[i].ordinal() == ordinal) {
                    return types[i];
                }
            }
            return types[0];
        }
    };
}
Notes: リスナをコーディングするときは、以下の点に注意してください。

このように開発者は、使用されるすべてのイベントをリスナが受信することが不可欠な場合にのみ、リスナをクリティカルとして登録するようにしてください。また、どうしても必要な場合を除き、例外が送出されないよう措置を講じる必要があります。

EventListener のインストール

詳細については、「カスタムのイベント リスナのデプロイ」を参照してください。

イベント リスナと実行名

同期リスナ (クリティカルまたは非クリティカル) は、処理しているイベントの作成に使用されたスレッドの ID で実行されます。非同期リスナは、TaskEventDispatcher MDB にコンフィグレーションされた ID で実行されます (デフォルトでは匿名。ただし WebLogic Server Administration Console でコンフィグレーション可能)。

注意 : システム管理者は、.listener ファイルを持つワークリスト アプリケーションを慎重に調べる必要があります。特に、それ自体を同期ユーザとして登録する .listener ファイルは精査が必要です。このようなリスナは、イベントの発生原因となったタスク更新を実行したユーザの ID で実行されます。このためリスナ コードは、そのユーザが実行できることであれば、どのようなことでも実行できます。同期リスナとしてのデプロイを許可するのは、信頼性のあるコードのみにする必要があります。

 


EventHandler モジュール

EventHandler モジュールは、レポート、電子メール通知、およびその他のタイプのイベントの配信をコンフィグレーションするためのコンフィグレーション モジュールです。

EventHandler モジュールは、ワークリスト ホスト アプリケーションの一部としてデプロイされます。この WebLogic Server コンフィグレーション モジュールは、ホスト アプリケーションにタイプが定義されているタスクのイベント配信をコンフィグレーションするために、そのホスト アプリケーションに追加できます。

イベント ハンドラのコンフィグレーションには、一般的な情報のほかに、リスナ タイプに固有の要素が含まれます。イベント ハンドラが定義する内容は以下のとおりです。

イベント サブスクリプションにも、一般的な要素とリスナ タイプに固有の要素が含まれます。イベント サブスクリプションが定義する内容は以下のとおりです。

リスナ タイプに固有のセクションは、以下のタイプのリスナからの要求を満たすために定義されます。

実行時に、ハンドラ内のイベント サブスクリプションは、アプリケーション内のその他すべてのハンドラからのイベント サブスクリプションとともに収集されます。これらのサブスクリプションは、互いに付加的です。特定のイベント ハンドラのイベント コンフィグレーションは、その他すべてのイベント ハンドラ (デフォルトのワークリスト イベント ハンドラを含みます) のコンフィグレーションと付加的にマージされます。

イベント ハンドラ ファイル

EventHandler は、XML ドキュメントとして .handler ファイルに定義されます。XML コンテンツは、EventHandler のスキーマに準拠している必要があります。EventHandler (.handler) ファイルは、EventHandler エディタ プラグインを使用して、Workshop IDE で編集できます。

注意 : アプリケーションに存在する .handler ファイルは、Worklist Console を使用して、そのコンフィグレーション内容を編集できます。これにより、処理が必要なイベント タイプに最適な調整を行い、実行時の処理を微調整できます。

デプロイメント

EventHandler モジュールは、ホスト アプリケーション (およびそこに含まれるタスク プラン) のデプロイ時にデプロイされます。実行時に、さまざまなタイプのリスナはデプロイされた EventHandler を調べてイベントがリスナのタイプに該当するものであるかどうかを判断し、該当する場合にはそれをリスナのエンドポイントに配信します。この配信は、ハンドラに指定された、リスナ タイプに固有のコンフィグレーションによって制御およびコンフィグレーションされます。

詳細については、「イベント ハンドラのデプロイ」を参照してください。

イベント ハンドラ エディタ

Worklist Console には、イベント ハンドラと、その中のリスナ タイプに固有のコンフィグレーションを編集するための機能が用意されています。詳細については、『Worklist Console の使い方』の「ワークリスト管理」にある「イベント ハンドラの詳細の変更」を参照してください。

Workshop for WebLogic IDE は、.handler.listener などのファイルの編集を直接的にはサポートしていません。しかし、IDE はこれらのタイプのファイルをカスタム モジュールとして登録します。これにより、ファイルを自動的にデプロイできます (ユーザ側でその他のアクションを行う必要はありません)。ただし、これらのファイルの編集は、このドキュメントの該当する節に記載されている例に従って手動で行う必要があります。

デフォルトのイベント コンフィグレーション

ワークリストは、以下のリスナ タイプのイベント配信を定義する、WorklistEventHandler という単一のデフォルト イベント ハンドラをデプロイします。

このファイルは、ワークリストの J2EE アプリケーション ライブラリの一部としてインクルードされ、すべてのタスク プランに適用されるグローバル イベント ハンドラです。このハンドラのデフォルトのイベント コンフィグレーションは、Worklist Console を使用して変更できます。詳細については、『Worklist Console の使い方』の「ワークリスト管理」にある「イベント ハンドラの詳細の変更」を参照してください。

 


デフォルトのレポート ストア

顧客がワークリストの実行時リポジトリに対する変更を検出し、対応する変更を各自のレポート リポジトリに反映するための、イベントベースのメカニズムが用意されています。ワークリストは、顧客のレポート リポジトリの設計に影響したり、これを認識することは一切ありません。さらに、ワークリスト クライアントがタスク履歴情報を利用できるように、顧客が準備するレポート リポジトリへのインタフェースが定義されます。

レポート機能を直ちに利用できるように、ワークリストにはデフォルトのレポート リポジトリとデフォルトのレポート機能が用意されています。このため、独自のレポート リポジトリを実装しなくても、ある程度の長期的レポート情報を収集できます。

注意 : アプリケーションにおいて、デフォルトのレポート リポジトリでは容易に収集できない情報が必要となる場合は、独自のレポート リポジトリの定義を検討してください。このリポジトリをワークリスト イベントに適用し、必要に応じてデフォルトのレポート ストアを完全に無効にすることができます。詳細については、「タスク変更イベント」を参照してください。

タスク履歴

一部のタイプのタスクでは、タスクがどこに存在していたかという情報は、タスクがどこに移動するよう定義されているかという情報と同様に重要です。このようなケースでは多くの場合、広範な対象ステップの間を移動できるよう、タスクを緩やかに定義できますが、一般的には、タスクの実際の経路や関連付けられるヒューマン アクターなどの情報を事前に得ることはできません。

こうしたタスクの例として、顧客サービスのトラブル チケットの処理や、ソフトウェアまたはハードウェア製品の欠陥を追跡および解決するための処理が挙げられます。このような場合、あらゆるタイプのトラブルや欠陥を追跡するために一般的な手順が用意されますが、それぞれのケースにはユニークな検討事項が存在します。このとき、後で同じタスクに遭遇するヒューマン アクターや、そのタスクに関連付けられるヒューマン アクターを支援するには、タスクの履歴が重要となります。たとえば、最初はあるソフトウェア コンポーネントに欠陥があると考えられ、そのコンポーネントに関連するソフトウェア エンジニアが調査を行った結果、欠陥は別のソフトウェア コンポーネントにあることが結論付けられたとします。この場合、別のエンジニアが問題を調査および解決する際には、最初のエンジニアによる分析と所見が重要となる可能性があります。

タスク履歴プロバイダ

タスク履歴インタフェースは以下のように定義されます。

package com.bea.wli.worklist.api.config;
/**
 * タスク履歴情報のプロバイダを定義する。このプロバイダは、すべての
 * タスク プラン、または選択したタスク プランを対象とするように定義できる。
 */
public interface TaskHistoryProvider {
    public void setProperties(Property[] props);
    public void initialize()
        throws ManagementException;
    public TaskHistory getTaskHistory(String taskId)
        throws RemoteException, ManagementException;
    public void destroy()
        throws ManagementException;
}
public interface TaskHistory {
    /**
     * startDate から endDate の間 (指定日を含む) でこのタスクに
     * ついて発生したすべてのイベントに対するイテレータを取得する。
     */
    public TaskEventIterator
    getTaskEvents(Date startDate, Date endDate)
        throws RemoteException, ManagementException;
    /**
     * 指定日のタスクの状態を再構築する。返される TaskData を
     * 構築する際には、プロバイダは指定日までの履歴情報を使用する 
     * 必要がある。プロバイダがこれをサポートしない場合は、
     * NotSupportedException が送出される。
     */
    public TaskData getTaskAtDate(Date date)
        throws NotSupportedException, ManagementException, RemoteException;
}
public interface TaskEventIterator {
    public boolean hasNext()
        throws RemoteException;
    public TaskChangeEvent next()
        throws RemoteException, ManagementException;
}

カスタム レポート リポジトリを実装するときは、オプションとして独自の TaskHistoryProvider 実装を定義し、その実装をグローバルに、または選択したタスク プランを対象に登録することができます。TaskHistoryProvider は、TaskHistoryProvider カスタム モジュールをデプロイすることで登録されます。詳細については、「カスタムのタスク履歴プロバイダのデプロイ」を参照してください。

ワークリストには、サーバサイドの TaskHistoryProvider に対するフロントエンドとして WorklistTaskUser.getTaskHistory() メソッドが用意されています。

public interface WorklistTaskUser {
    ...
    /**
     * タスク プランがタスク履歴プロバイダに関連付けられて
     * いる (true が返される) 場合は、getTaskEvents() から
     * 空以外の結果が得られる可能性が高くなる。
     */
    public boolean isTaskHistoryProvided(TaskPlan taskType);
    /**
     * 開始日から終了日までの間 (指定日を含む) でこのタスクに
     * ついて発生したすべてのイベントを、日付順にソートして
     * 取得する。このタスクに関するタスク履歴を利用できない場合は、
     * 空の配列が返される。これは、指定した日付範囲がタスクの
     * 非アクティブ期間に該当する場合や、そのタイプのタスクに
     * ついてタスク履歴が収集されていない場合に生じる。
     */
    public TaskEvent[] getTaskEvents(String taskId,
                                     Date startDate, Date endDate)
        throws ManagementException, RemoteException;
    ...
}

ワークリストには、ワークリストのデフォルト レポート ストア用の TaskHistoryProvider 実装が用意されています。このデフォルトの TaskHistoryProvider は自動的にグローバル プロバイダとして登録されるため、すべてのタスク プランに適用されます。

ある特定のタスク プランに関連付けることができる TaskHistoryProvider は 1 つに限られます。特定のタスク プランに適用するカスタム TaskHistoryProvider を登録した場合、そのプロバイダは、そのタスク プラン向けにタスク履歴情報を提供する唯一のプロバイダとなります (デフォルト/グローバル TaskHistoryProvider は置き換えられます)。グローバル TaskHistoryProvider を登録した場合は、デフォルト TaskHistoryProvider が置き換えられます。この登録は慎重に行い、すべてのタスク プランのタスク履歴の生成に必要なタスク イベントを収集する、グローバル TaskEventListener が登録された場合にのみ行ってください。

レポート ストアの設計

レポート ストアの目的は、少なくとも 8.1 のワークリストにおけるレポート機能と同等の機能と、現行データおよび履歴データをクエリできる追加機能を提供することにあります (8.1 では、アーカイブ済みのレコードはワークリストの実行時ストアの情報とは別にクエリする必要がありました)。

レポート ストアの技術的な設計目標は、できるだけ多くのデータを、できるだけ少ない処理オーバーヘッドで格納することです。つまり、実行時に生成されるすべてのイベントを対象として、実行時に処理を行うよりも、レポート ストア内のタスクに限定して、レポート プロセスまたはユーザ インタフェースで処理したほうが、より容易であると考えられます。

ビジネス目標

レポート ストアのビジネス上の目標は、以下のような一般タイプのクエリをサポートすることです。

データベース スキーマ

以下の図は、レポート ストア スキーマの例を示しています。「ビジネス目標」に記載されているようなビジネス目標を達成するために、レポート ストアを利用してデータを取得する例については、「サンプル クエリ」を参照してください。

図 5-2 レポート ストア スキーマ

レポート ストア スキーマ

サンプル クエリ

例 : 今日までに、タスク XYZ に関して生じたすべての事象

select * from WLI_WORKLIST_RPT_TASKEVENT
  where TASK_ID='XYZ'
  order by TIMESTAMP

例 : タスク XYZ をステップ A からステップ B に移動させるアクションを実行したのは誰か。また、いつ実行されたか

select e.CALLER, e.TIMESTAMP
  from WLI_WORKLIST_RPT_TASKEVENT e, WLI_WORKLIST_RPT_TASKACTION a
  where e.TASK_ID = 'XYZ' and
        e.TASK_EVENT_ID = a.TASK_EVENT_ID and
        a.OLD_STEP_NAME = 'A' and a.NEW_STEP_ID = 'B'

例 : ボブ (Bob) が CustomerRefund タスクを完了するには、どれだけの時間が必要か

select avg(complete.TIMESTAMP - create.TIMESTAMP)
  from WLI_WORKLIST_RPT_TASKEVENT create, WLI_WORKLIST_RPT_TASKEVENT complete,
       WLI_WORKLIST_RPT_TASKINFO info
  where create.EVENT_TYPE = 'TaskCreate' and
        complete.EVENT_TYPE = 'TaskComplete' and
        create.TASK_ID = complete.TASK_ID and
        info.TASK_ID = create.TASK_ID and
        info.TASK_TYPE_ID = 'CustomerTasks:1.0/CustomerRefund:1.0'
        info.OWNER = 'Bob'
  group by info.TASK_ID

例 : CustomerRefund タスクは今週いくつ処理されたか

select count(TASK_ID)
  from WLI_WORKLIST_RPT_TASKEVENT
  where EVENT_TYPE = 'TaskComplete' and
        TASK_TYPE_ID = 'CustomerTasks:1.0/CustomerRefund:1.0' and
        TIMESTAMP > [long millis for start of week] and
        TIMESTAMP < [long millis for end of week]
  group by EVENT_TYPE

例 : 今四半期の支出レポートに基づくと、ホテルの宿泊費としていくら支払われたか

注意 : このクエリでは、ExpenseReport タスクの宿泊費プロパティを使用できます。タスク プランの設計者は、ホテル宿泊費へのクエリの必要性を見越して、支出レポート ドキュメントにおける他の情報とは別に、宿泊費の情報を保持するフィールドを作成しておく必要があります。ここでは、月の初日から最終日の間に発生したホテル宿泊費を把握する必要があると仮定します。
select event.TASK_ID, prop.VALUE, event.TIMESTAMP
  from WLI_WORKLIST_RPT_TASKEVENT event, WLI_WORKLIST_RPT_TASKPROPERTY prop
  where event.EVENT_TYPE = 'TaskComplete' and
        event.TASK_TYPE_ID = 'EmployeeTasks:1.0/ExpenseReport:1.0' and
        prop.TASK_ID = event.TASK_ID and
        event.TIMESTAMP > [long millis for the start of month] and
        event.TIMESTAMP < [long millis for the end of month] and
        prop.NAME = 'Hotel Charges'
  order by event.TASK_ID, event.TIMESTAMP
注意 : ここでは、各 ExpenseReport タスクのホテル宿泊費を実際には計算できないことを前提としています。一部のデータベースでは、あるデータ型から別のデータ型にフィールド値を変換できます。このような変換をサポートするデータベースでは、宿泊費 (Hotel Charges) を浮動小数点値または通貨値に変換し、その結果をグループ化して集計できます。

レポート対象イベントのフィルタ処理

プロデューササイドのフィルタ処理によって、特定のイベント タイプをデフォルト レポート ストアのレポート対象から除外することができます。詳細については、「タスク プランごとのイベントの制御」を参照してください。

レポート イベントのコンフィグレーション セクションは、EventHandler イベント サブスクリプション内に定義され、サブスクリプションのイベント タイプをデフォルト レポート ストアに配信するかどうかを決定します。このようなコンフィグレーションがサブスクリプションに定義されていない場合は、実行時にそのサブスクリプションを処理してもレポート イベントは配信されません。ホスト アプリケーションのどのハンドラのサブスクリプションにも、特定のイベント タイプがデフォルト レポート ストアに配信されるよう定義されていない場合は、デフォルト レポート ストアはそのイベントを無視します。

デフォルト レポート ストアの対象となるすべてのイベント タイプは、ワークリストのデフォルト イベント ハンドラによって定義されます。このデフォルト コンフィグレーションは、必要に応じて Worklist Console を使用して変更できます。

 


電子メール通知

ワークリストには、人的な操作が必要なビジネス タスクを制御するための方法が用意されています。以下に示すように、タスクはいくつかの方法でヒューマン アクターと関連付けられます。

これらのヒューマン アクターに対しては、多くの場合、関連付けられているタスクに変更が生じた場合に通知が必要となります。たとえば、同じタスクが複数のヒューマン アクターに割り当てられているときは通知が必要です。このときヒューマン アクターが、自分がタスクに関連付けられていたことを即座に認識できるとは限りません。Worklist User Portal (または任意のカスタム タスク UI) を定期的に開いて更新することが義務付けられていれば、Worklist User Portal の [担当タスク] ポートレットで各自のタスクを確認できます。ただし、Worklist User Portal を定期的に使用したり、更新したりしない環境では、別の通知方法が必要です。現在では、多くの人が常に電子メール クライアントを開いています。このため、電子メールは効果的な通知手段となります。

ここでは、ワークリストがどのように電子メール通知をサポートしているかを説明します。

ワークリストでは、タスク プラン定義を通じて電子メール通知をコンフィグレーションできます。このコンフィグレーションには、電子メール通知をトリガするイベント タイプ、通知の送信先となるヒューマン アクター、電子メールの本文の内容の設定が含まれます。

電子メール通知のアクターの指定

アクターは、タスクに対するアフィニティ (作成者、オーナ、申請者、割り当て対象) によって指定したり、ユーザ名を使用して直接指定する (タスクに対して直接的な関連性のないユーザの場合) ことができます。また、カスタムの電子メール受信者カリキュレータを使用して、アクターの電子メール アドレスを実行時に動的に導き出すこともできます。詳細については、「電子メール受信者カリキュレータのデプロイ」を参照してください。

電子メールの受信者としてタスク アフィニティまたはユーザ名を指定した場合、それらのアクターの電子メール アドレスを Worklist Console で確実にコンフィグレーションしておく必要があります。詳細については、『Worklist Console の使い方』の「ワークリスト管理」にある「ユーザの電子メール アドレスの設定」を参照してください。

注意 : 指定されているアクターの電子メール アドレスが見つからない場合、電子メール通知サブシステムは警告をログに記録します。

電子メール受信者カリキュレータ

特定タイプの電子メール通知に対する適切な受信者を事前に確認できない場合は、使用する電子メール アドレスを実行時に動的に導き出すことができます。

このようなカリキュレータを使用することで、ワークリスト タスク イベントに応じて受信者に送信される電子メール メッセージの To: リストを増補できます。たとえば、注文書の承認の取り扱い方法を定義するタスク プランがあるとします。注文が極めて高額になる場合は、注文書の作成時に事業部の経理責任者に電子メールで通知する必要があります。電子メール通知のデフォルトのコンフィグレーションでは、この要件を表現できません。このような場合は、EmailRecipientCalculator インタフェースを実装し、タスク プランのホスト アプリケーションにこれを配置します。そして、PurchaseOrderAmount プロパティが指定金額を超過している Create タスク イベントを受信するたびに、経理責任者の電子メール アドレスを返すよう設定します。

注意 : カリキュレータの実装をデプロイ時にパラメータ化し (ホスト アプリケーションでカスタム モジュール記述子の .email ファイルを使用)、金額を指定できるようにしたり、金額をルックアップするための外部サービスのアドレスを通過させます。
/**
 * 特定の TaskEvent に関して電子メール通知を受信するアクターの
 * 電子メール アドレスを生成するカリキュレータの、プラグイン可能な実装を
 * 定義する。このインタフェースは、ワークリストのデフォルトの 
 * 電子メール サブシステムからすでに電子メールが送信されている 
 * To: リストを増補するという、単純な機能の提供のみを目的として 
 * いる。送信する電子メールの件名や本文などの属性を制御する 
 * 場合は、カスタム電子メールの送信元となる独自のカスタム イベント * リスナを定義する必要がある。
 * <p>
 * このインタフェースの実装では、デフォルトの (引数なしの) パブリック
 * コンストラクタを提供する必要がある。この実装は、それ自体の 
 * インスタンスのライフサイクルや、別のインスタンスとの関係について、 
 * 推測を行うことはできない。ライフサイクルは、全体が
* initialize() および destroy() メソッドによって制御される。
 */
public interface EmailRecipientCalculator {
    /**
     * この EmailRecipientCalculator をデプロイしたカスタム モジュールで、
     * このメソッドのプロパティを設定する。このメソッドは、プロパティが
     * 使用可能である (たとえば、カスタム モジュールのデプロイメント記述子に指定
     * されている) 場合にのみ呼び出される。このメソッドが呼び出されるのは、
     * ライフサイクル初期化メソッドの前である。
     * @param properties
     */
    public void setProperties(Property[] properties);
    /**
     * getEmailRecipientsForEvent() による電子メール アドレスの計算に
     * 必要なリソースを初期化する。
     * @throws com.bea.wli.worklist.api.ManagementException
     */
    public void initialize()
        throws ManagementException;
    /**
     * このインスタンスを破棄し、初期化時または getEmailRecipientsForEvent()
     * への呼び出し中に取得されたリソースを解放する。
     * @throws ManagementException
     */
    public void destroy()
        throws ManagementException;
    /**
     * 指定したイベントの電子メール通知の受信を必要とするアクターの
     * 電子メール アドレスを計算する。電子メール通知が送信されない
     * 場合は、このメソッドは null または空の配列を返す。
     * @param event 電子メール通知の送信対象となるイベント。
     * @param currentRecipients このイベントに関する電子メール通知が
     *        すでに送信されている電子メール アドレスのセット。このセットは、電子
     *        メールの To: リストに入力されるアドレス セットのコピーであるため、
     *        このセットの項目の追加/削除は効力を持たない。
     * @return イベントに応じた電子メール通知の受信を必要とするアクターの
     *         電子メール アドレスの配列。これらのアクターは、事前に
     *         定義された件名と本文を持つ電子メールを受信する。本文には、
     *         このイベントをトリガしたタスクへの URL が含まれる。
     *         オプションとして、TaskURLCalculator をインストールして
     *         URL を計算することもできる。
     * @throws ManagementException 受信者の計算時にエラーが発生した場合に
     *         送出される。このエラーはサーバ ログに記録されるが、それ以外に
     *         このイベントの処理に影響することはない。
     * @see TaskURLCalculator
     */
    public String[] getEmailRecipientsForEvent(TaskEvent event,
                                               Set<String> currentRecipients)
        throws ManagementException;
}

上記インタフェースを実装する電子メール受信者カリキュレータをインストールするには、実装のクラス名と、受信者の計算前にインスタンスの初期化に必要となるプロパティを定義する、カスタム モジュールをホスト アプリケーションに定義します。詳細については、「電子メール受信者カリキュレータのデプロイ」を参照してください。

電子メール配信メカニズム

電子メールの送信には、JavaMail API が使用されます。電子メールの送信に使用されるメール セッションは、Worklist Console のワークリスト システム インスタンスのコンフィグレーションに指定されます。このコンフィグレーションは、WebLogic Server にコンフィグレーションされる (WebLogic Server Administration Console を使用) メール セッションの名前です。詳細については、『Worklist Console の使い方』の「ワークリスト管理」にある「ワークリスト システム インスタンスのコンフィグレーションの変更」、WebLogic Server Administration Console オンライン ヘルプの「メール セッションの作成」、『WebLogic Server アプリケーションの開発』の「WebLogic Server での JavaMail のプログラミング」を参照してください。

JavaMail セッションでは、ワークリストが電子メールを配信する SMTP ホストの名前を定義する必要があります。これは、名前のセッション プロパティの指定によって定義されます。

mail.smtp.host=<SMTP Host name or IP Address>

たとえば、Microsoft Exchange サーバや ISP SMTP サーバをここに指定できます。

注意 : コンフィグレーションされた JavaMail セッションが実行時に見つからないと、電子メール通知サブシステムはエラーをログに記録します。

イベント タイプ

ワークリストでは、タスクへの変更に応じてさまざまなイベント タイプを配信できます。ワークリストは、ヒューマン アクターにとって重要な以下の一般的なイベントを定義します。

タスク プランに特定のイベント タイプをコンフィグレーションしなかった場合は、上記リストが使用されます。タスク プランの設計者とワークリストの管理者は、特定のビジネス要件に合わせてこのリストを自由に変更できます。

デフォルトでは、上記の各イベント タイプは、変更されたタスクに関連付けられているヒューマン アクターの特定セットに対して送信されるようにコンフィグレーションされています。以下の表は、各イベント タイプのデフォルトの電子メール受信者と、電子メールの件名と本文の作成に使用される電子メール テンプレートを示しています。この場合も、タスク プランの設計者とワークリストの管理者は、必要に応じてこのコンフィグレーションを自由に変更できます。

デフォルトでは、電子メール テンプレートはサーバ (電子メール クライアントではありません) のデフォルト ロケールに合わせてローカライズされます。イベント通知は、必要に応じて別のロケールで配信するようにコンフィグレーションできます。

注意 : このデフォルト コンフィグレーションは、WorklistMailSession という JNDI 名を持つ JavaMail セッションを指定します。このデフォルト コンフィグレーションを利用するには、この名前の JavaMail セッションを定義する必要があります。詳細については、WebLogic Server Administration Console オンライン ヘルプの「メール セッションの作成」を参照してください。

タスク URL の計算

上の表に示される各電子メール テンプレート (本文テンプレート) には、タスクの UI に直接移動するための URL のマーカが含まれます。これを生成するために、TaskURLCalculator インタフェースが用意されています。

public interface TaskURLCalculator {
    public URL getURLForTask(String taskId)
        throws ManagementException;
}

これは、各ワークリスト ホスト アプリケーションが独自のカスタム URL カリキュレータを指定するためのカスタム モジュールです。ワークリスト ホスト アプリケーションが、タスクへの移動に特定の URL またはカスタム URL を必要とするカスタム ワークリストまたはタスク UI も提供する場合に、このモジュールが必要となります。一度に登録できる TaskURLCalculator は 1 つだけです。

ワークリストは、デフォルトの Worklist User Portal での使用に適した URL を計算する、デフォルトの TaskURLCalculator 実装を提供します。

ワークリスト API の WorklistTaskUser には、タスクの URL を計算する新しい方法が用意されています (登録済み、またはデフォルトのカリキュレータを使用)。

public interface WorklistTaskUser {
    ...
    public URL getURLForTask(String taskId)
        throws ManagementException, RemoteException;
    ...
}

電子メール テンプレート

表 5-1 は、電子メール メッセージの件名と本文として使用されるテキスト テンプレートを示しています。基底のワークリスト タスク イベントからの情報がテンプレートに挿入され、電子メール メッセージで使用される完全なテキストを生成します。

これらのテンプレートは WorklistEMail テキスト フォーマッタ ファイルに定義され、WebLogic Integration がサポートする任意の言語にローカライズされます。必要に応じて worklist.jar ファイル内の WorklistEmailTextFormatter.properties ファイルを直接編集することで、これらのテンプレートをカスタマイズできます。

電子メール通知のコンフィグレーションと EventHandler モジュール

電子メール通知のコンフィグレーションは、EventHandler モジュールのリスナ タイプに固有のセクションに定義されます。このモジュールは、レポート イベントやその他のタイプのイベントのコンフィグレーション定義にも使用されます。詳細については、「EventHandler モジュール」を参照してください。

イベント ハンドラの電子メール コンフィグレーションは、指定したタイプのイベントの発生時に電子メール通知を受信するアクターと、タスクのイベント タイプをマッピングします。任意のタスク プランのアクターへのイベント タイプのマッピングは、そのタスク プランのデフォルトのイベント通知コンフィグレーションに追加されます (置換されるわけではありません)。つまり、コンフィグレーション モジュールに指定した電子メール コンフィグレーションは、タスク プランのデフォルトのコンフィグレーションにマージされます。

 


MessageBroker と JPD の統合

ワークリストは、Worklist Portal から直接使用するか、ワークリスト API 経由で使用することができます。この API で使用されるワークリストへの主要インタフェースの 1 つがワークリスト コントロールです。ワークリスト コントロールは、主に WebLogic Integration Process Definitions (JPD) でホスティングされます。このコントロールにより、連携するタスクのタスク ID を JPD がインスタンス化する、または認識する場合に、強力な統合を保証することができます。しかし、連携するタスクの ID を JPD が認識していない場合や、タスクの作成または変更によって JPD インスタンスを作成したい場合もあります。

このような場合は、JPD MessageBroker を使用してイベント チャネルから JPD にメッセージを配信します。これらのチャネルにはセマンティクスを適用することができ、メッセージ フィルタを使用してコンシューマへのメッセージの配信を制御できます。これは、既存の JPD インスタンスが必要に応じてタスク インスタンスを認識するための理想的なメカニズムです (インスタンスの特定タスク プランからの特定タイプのイベントに応答します)。静的なサブスクリプションを通じてこのメカニズムを利用することで、タスク イベントに応じて JPD インスタンスを作成することもできます。

ワークリスト チャネル

任意のタイプのタスクに変更が生じると、ワークリストは以下のワークリスト チャネルを使用して MessageBroker チャネルにイベントを配信します。

/WorklistEvent

JPD は、/WorklistEvent のチャネル名 (およびフィルタ内の関連するヘッダ フィールド) を使用して、静的または動的な MessageBroker サブスクリプションを定義し、関心のあるワークリスト イベントを受信することができます。このチャネルは rawdata チャネルで、シリアライズされた TaskEvent インスタンスを本文とするメッセージを持ちます。TaskEvent インスタンスの実際の実行時タイプは、イベントのタイプによって異なります。詳細については、「タスク変更イベント」を参照してください。

ObjectInputStream.readObject() を使用して MessageBroker メッセージのバイトを非シリアル化し、結果として生じるオブジェクトを TaskEvent にキャストする必要があります。以下に JPD の例を示します。

@com.bea.wli.jpd.Process(
        process="<process name=\"WorklistControlStatefulControlReceive\">\n" +
                "  <clientRequest name=\"Client Request\" method=\"clientRequest\"/>\n" +
                "</process>"
)
public class HandleTaskEvent implements com.bea.jpd.ProcessDefinition
{
    public String _x0;
    static final long serialVersionUID = 1L;
    
    @MessageBroker.StaticSubscription(channelName = "/WorklistEvent",
                                      messageMetaData="{meta}",
                                      messageBody = "{body}")
    public void clientRequest(TaskEventMetadataDocument meta,
                              Object body)
        throws IOException, ClassNotFoundException {
        RawData rawData = (RawData)body;
        ByteArrayInputStream bais = new ByteArrayInputStream(rawData.byteValue());
        ObjectInputStream ois = new ObjectInputStream(bais);
        TaskEvent event = (TaskEvent)ois.readObject();
        System.out.println("## Got TaskEvent in JPD: " + event.getSummary());
        this._x0 = event.getSummary();
    }
}

イベント タイプ

イベントは、ワークリスト エンジンでの発生時にワークリストの MessageBroker チャネルに配信されます。MessageBroker リスナは、定義済みの任意のタスク イベントを MessageBroker に送信できます。デフォルトでは、以下のイベントのみが MessageBroker 経由で配信されます。

イベントの配信は、タスク プランごとに、またはグローバル ベースでカスタマイズできます。詳細については、「MessageBroker イベントのコンフィグレーションと EventHandler モジュール」を参照してください。

メッセージ ヘッダ フィールド

MessageBroker にポストされる各タスク イベントは、単一のワークリスト チャネルにポストされます。このメッセージには、JPD での使用時にメッセージをフィルタリングするためのヘッダ フィールドが数多く含まれます。以下のようなメッセージ ヘッダ フィールドがあります。

このメッセージ ヘッダ フィールドは、以下のタイプの XMLBean イベント メタデータ オブジェクトとして配信されます。

com.bea.wli.worklist.xml.TaskEventMetadataDocument

これは、Worklist.xsd スキーマに定義されています。

注意 : ユーティリティ プロジェクトを使用してワークリスト アプリケーションを作成し、そのプロジェクトにシステム スキーマを追加することで、Workshop for WebLogic IDE からこのスキーマを利用できるようになります。XMLBean は、worklist-client.jar (パブリック jar) ファイルに用意されています。
Example Process:
package process;
import java.util.Date;
import com.bea.jpd.ProcessDefinition;
import com.bea.jpd.JpdContext;
import org.apache.beehive.controls.api.bean.Control;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
@com.bea.wli.common.XQuery(prolog="declare namespace ns0 = \"http://www.bea.com/wli/worklist/xml\";")
@com.bea.wli.jpd.Process(process = 
"<process name=\"StaticMBWithNoXQuery\">" + 
"  <clientRequest name=\"Subscription\" method=\"subscription\"/>" + 
"  <perform name=\"Print Event Info\" method=\"perform\"/>" + 
"</process>")
public class StaticMBWithAndFilterValue implements ProcessDefinition {
    public com.bea.wli.worklist.xml.TaskEventMetadataDocument _e1;
    public com.bea.data.RawData _rd;
    @com.bea.wli.jpd.Context
    JpdContext context;
    static final long serialVersionUID = 1;
    @com.bea.wli.control.broker.MessageBroker.StaticSubscription(xquery = "fn:concat($metadata/ns0:taskPlanId,  $metadata/ns0:eventType)", filterValueMatch = "/Loans/Loan Approval:1.0:LoanAppCREATE", channelName = "/WorklistEvent", messageBody = "{x0}", messageMetaData = "{x1}")
    public void subscription(com.bea.data.RawData x0,
                             com.bea.wli.worklist.xml.TaskEventMetadataDocument x1) {
        //#START: CODE GENERATED - PROTECTED SECTION - このメソッドのこのコメントより前であれば、安全にコードを追加できる。#//
        // トランスフォームを入力する
        // パラメータの割り当て
        this._rd = x0;
        this._e1 = x1;
        //#END  : CODE GENERATED - PROTECTED SECTION - このメソッドのこのコメントより後であれば、安全にコードを追加できる。#//
    }
    public void perform() throws Exception {
        Date dt = new Date();
        StringBuffer sb = new StringBuffer();
        sb.append("\n\n[" + dt.getTime() + "]\t ++++++++ StaticMBWithAndFilterValue : GOT MB Event in JPD with Filter Value Match +++++ " + new Date());
        sb.append("[" + dt.getTime() + "]\t Event Info: " + this._e1);
        sb.append("[" + dt.getTime() + "]\t Is Raw Data NULL? " + (this._rd == null ? true、false));
        sb.append("[" + dt.getTime() + "]\t ----------------------------------------------------------------------------");
        try {
            ByteArrayInputStream baos =
                new ByteArrayInputStream(_rd.byteValue());
            ObjectInputStream ois = new ObjectInputStream(baos);
            TaskEvent event = (TaskEvent)ois.readObject();
            sb.append("[" + dt.getTime() + "]\t Event object summary: " + event.getSummary());
        } catch (Exception e) {
            sb.append("[" + dt.getTime() + "]\t Event object (error): " + e.toString());
        }
        System.out.println(sb);
    }
}     

MessageBroker イベントのコンフィグレーションと EventHandler モジュール

タスク イベントは EventHandler 経由で MessageBroker に配信されます。デフォルトでは、ワークリストはデフォルト イベント コンフィグレーションを適用して単一の EventHandler を定義します。詳細については、「イベント タイプ」を参照してください。ただしワークリストの管理者は、Worklist Console を使用して、このコンフィグレーションをグローバルに、または特定のタスク プランを対象に変更することができます。詳細については、『Worklist Console の使い方』の「ワークリスト管理」にある「イベント ハンドラの詳細の変更」を参照してください。

MessageBroker イベントの配信のコンフィグレーションは、EventHandler モジュールの一部として定義されます。このモジュールは、電子メール通知イベントやレポート イベント、およびその他のタイプのイベントのコンフィグレーション定義にも使用されます。詳細については、「EventHandler モジュール」を参照してください。

イベント ハンドラの MessageBroker イベントのコンフィグレーションは、MessageBroker に送信されるタスク イベントのタイプを指定します。MessageBroker イベントのコンフィグレーションにイベント タイプを指定することで、そのイベントの MessageBroker 経由の配信が有効になります。任意のタスク プランで有効化されたイベント タイプは、そのタスク プランのデフォルトのイベント通知コンフィグレーションに追加されます (置換されるわけではありません)。つまり、コンフィグレーション モジュールに指定したコンフィグレーションは、タスク プランのデフォルトのコンフィグレーションにマージされます。

 


カスタムのタスク イベント リスナ

ワークリストを使用することで、実行時イベントをリスンし (「タスク変更イベント」を参照)、そのイベントに応じてアクションを実行できます。リスナは、同期または非同期のイベント配信を要求したり、クリティカルまたは非クリティカル リスナとして登録されるように要求することができます。詳細については、「イベント ディスパッチ モード (サービスの品質)」を参照してください。

カスタムのタスク イベント リスナは、TaskEventListener インタフェースを実装します (「タスク変更イベント」を参照)。その後、アプリケーションに .listener ファイルをインクルードすることで、リスナを登録できます。詳細については、「カスタムのイベント リスナのデプロイ」を参照してください。

 


カスタムの割り当てハンドラ

ワークリストを使用することで、特定のタスクにユーザを割り当てることができます。このデフォルトの割り当て機能により、大半のケースの割り当てに対応できます。しかし、ワークリストのデフォルトの割り当て機能では不十分な場合もあります。このようなときは、タスクの割り当てプロセスを制御できるカスタムの割り当てハンドラを使用します。

カスタムの割り当てハンドラは、割り当てプロセスを完全に制御します。特別なロード バランシングや可用性チェック ロジックが必要なときは、カスタム ハンドラが適している可能性があります。カスタムの割り当てハンドラは、特定のタスク プランに適用することも、すべてのタスク プランにグローバルに適用することもできます。

注意 : 一度に存在できるグローバル割り当てハンドラは 1 つだけであるため、このオプションの使用には注意が必要です。グローバル割り当てハンドラを適用すると、それまでに適用されていたハンドラ (ワークリストのデフォルトの割り当てハンドラを含みます) は上書きされます。

カスタムの割り当てハンドラは、以下のインタフェースを実装する必要があります。

com.bea.wli.worklist.api.config.AssignmentHandler

また、デフォルトの (引数なしの) パブリック コンストラクタを提供する必要があります。カスタムの割り当てハンドラに、インスタンス化されるハンドラ インスタンスの数や、特定のインスタンスのライフサイクルについて制御させることはできません。特定のハンドラ インスタンスのライフサイクルは、initialize() および destroy() ライフサイクル メソッドによって制御されます。

このインタフェースの概要を以下に示します。完全なインタフェースの詳細については、http://edocs.bea.com/wli/docs92/worklist.javadoc/index.html でワークリスト API の JavaDoc を参照してください。

/**
 * 特定タイプのタスクを、そのタスクの申請候補者としてユーザに割り当てる際に使用する
 * 割り当てアルゴリズムを説明する。このアルゴリズムには、指定された候補ユーザの
 * 名前でタスクを申請するように設定するオプションもある。このインタフェースの
 * 実装は、デフォルトの (引数を持たない) パブリック コンストラクタを提供しなければ
 * ならない。この実装は、それ自体のインスタンスのライフサイクルや、別のインスタンス
 * との関係について、推測を行うことはできない。ライフサイクルは、全体が
 * initialize() および destroy() メソッドによって制御される。
 */
public interface AssignmentHandler {
    /**
     * ワークリストがタスクの割り当てを要求するときに割り当て
     * ハンドラに渡される要求オブジェクト。
     */
    public class Request {
        private String _taskId;
        private String[] _candidateUserIds;
        private CandidateListHandling _handling;
        private boolean _availabilityCheckEnabled;
        private WorkloadRequest _workloadRequest;
        ...
    }
    /**
     * そのタスクについて決定された割り当てを説明するために
     * 割り当てハンドラが返す応答オブジェクト。
     */
    public interface Response {
        /**
         * 割り当てハンドラによって計算された割り当て対象。
         * 候補ユーザの ID リストの生成に使用された割り当て対象
         * リストを受け入れる場合は null。
         */
        AssigneeDefinition[] getNewAssigneeList();
        /**
         * タスクの申請者となるユーザのユーザ ID。
         * 申請者が選択されない場合は null。
         */
        String getClaimant();
    }
    /**
     * この割り当てハンドラを使用してコンフィグレーションされる
     * プロパティを設定する。値は、提供されるプロパティのデフォルト値
     * から取得する必要がある。
     * @param props
     */
    public void setProperties(Property[] props);
    /**
     * assignTask() を呼び出す準備としてこのインスタンスを初期化する。
     * @throws ManagementException このインスタンスが assignTask() への呼び出しを正しく処理
     *         できなくなるようなエラーが発生した場合に送出される。
     */
    public void initialize()
        throws ManagementException;
    /**
     * 該当するタスクの割り当てを決定する。このメソッドでは、申請候補
     * ユーザ名として提供されたリストを使用することも、無視することも
     * できる。候補ユーザ名のリストは、タスクの現在のステップの割り当て
     * 対象リスト、または WorklistTaskAdmin.assignTask() に渡される割り当て
     * 対象リストから得られる。このメソッドにより、選択した申請者に合わせて
     * タスクを実際に変更したり (選択した場合)、タスクに対してその他の
     * 影響をもたらすことはできない。割り当ての決定は、返される応答インスタンスを
     * 通じて呼び出し元に通知される。
     * @param request タスクの割り当てに必要な情報を含む
     *        要求インスタンス。
      * @return このタスクで使用される、新たに計算された割り当て
     *         対象リスト、およびタスクについて選択された申請者を示す
     *         応答インスタンス。
     * @throws AssignmentException 割り当て時に認証エラーまたは論理エラーが生じた場合に
     *         送出される。
     * @throws ManagementException 割り当て時にその他のエラーが生じた場合に送出される。
     */
    public Response
    assignTask(Request request)
        throws AssignmentException, ManagementException;
    ...
    /**
     * assignTask() を初期化する呼び出しで、または assignTask() への呼び出しで
     * 取得したリソースを解放する。
     * @throws ManagementException リソースの解放時にエラーが発生した場合に送出される。
     */
    public void destroy()
        throws ManagementException;
}

割り当てハンドラの実装は、ワークリスト ホスト アプリケーションに割り当てハンドラ コンフィグレーション モジュールをデプロイすることで登録されます。詳細については、「カスタムの割り当てハンドラのデプロイ」を参照してください。

登録された割り当てハンドラは、実行時に assignTask メソッドを通じて呼び出されます。ハンドラは、候補リスト、割り当てられているタスクの ID、カスタムの割り当てハンドラの実行を進めるためのヒントとなるパラメータを受け取ります。割り当てハンドラは handling パラメータと enableLoadBalancingAvailabilityCheck パラメータを使用できますが、使用は必須ではありません。

割り当てと申請に関する決定を行う上で、割り当てハンドラはタスクに含まれる情報 (タイプやプロパティなど) を自由に使用できます。ハンドラが下した決定は、返される応答インスタンスを通じて assignTask() メソッドの呼び出し元に通知されます。

応答オブジェクトは、新たに計算された割り当て対象リスト (古いリストの使用を継続する場合は null) と、タスクの申請者 (申請者が選択されなかった場合は null) を定義できます。割り当てハンドラは、タスクの申請を強制したり (たとえば、WorklistTaskUser.claimTask() の使用)、タスクに影響を与えるメソッドをワークリスト API 内で呼び出すことはできません。

ワークリストは、結果が返された後に更新された割り当て対象リストや申請者情報をタスクに適用するために、割り当てハンドラの assignTask() メソッドを使用します。

注意 : 割り当てハンドラのコンフィグレーション モジュールは、割り当てハンドラが実行時に使用できるコンフィグレーション プロパティを指定できます。このようなプロパティは、実行時のハンドラの動作をパラメータ化および制御します。割り当てハンドラについて指定されるコンフィグレーション プロパティは、setProperties() メソッドへの呼び出しによってハンドラ インスタンスが作成されるときに、割り当てハンドラの実装に渡されます。詳細については、「カスタムの割り当てハンドラのデプロイ」を参照してください。

  ページの先頭       前  次