intra-mart Accel Platform IM-Workflow TERASOLUNA Server Framework プログラミングガイド 第5版 2019-12-01

6. ユーザプログラムの開発

IM-Workflow では、案件処理の様々なタイミングにて設定されたユーザプログラムを呼び出す機構を提供しています。
ユーザプログラムを利用して、独自の業務ロジックの実行やワークフローエンジンの制御を行うことが可能です。
本書では、ユーザプログラムのうち、よく利用される以下の4つに限定して説明を行います。
  • 「アクション処理」

    • 申請・承認など操作時に実行される処理です。画面操作のスレッドにて処理が実行されます。
  • 「到達処理」

    • ノードに到達した場合に実行される処理です。画面操作と別のスレッドにて処理が実行されます。
  • 「案件終了処理/案件終了処理(トランザクションなし)」

    • 案件が完了する直前に実行される処理です。画面操作と別のスレッドにて処理が実行されます。
../../_images/user_program.png
他のユーザプログラムについては、「 IM-Workflow プログラミングガイド 」-「 ユーザプログラムの作成 」 を参照してください。

6.1. DIコンテナの呼び出し

  • ユーザコンテンツ画面とは異なり、ユーザプログラムの呼び出し時にはDIコンテナによる自動バインディング(@Inject アノテーションを付与したフィールドへの自動設定)が有効ではありません。

    コンポーネントを使いたい場合には、ApplicationContextを使用して明示的に取得してください。
    ApplicationContext経由で取得したコンポーネント内の空間では、自動バインディングが有効です。

    コラム

    ユーザコンテンツ画面はSpring MVC経由で呼び出されるため、自動バインディングが有効です。

6.1.1. 明示的な自動バインディング呼び出しのコード例

  • ApplicationContextは、 intra-mart Accel Platform で提供されているAPI ApplicationContextProvider にて取得可能です。

    public class ActionProcess extends ActionProcessEventListener {
    
       // 申請
       @Override
       public final String apply(final ActionProcessParameter parameter,
         final Map<String, Object> userParameter) throws Exception {
    
           // アクション処理用のサービスを取得します。
           final ActionProcessService service = ApplicationContextProvider.getApplicationContext().
                                              getBean(ActionProcessService.class);
           return service.apply(parameter, userParameter);
       }
    
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    @Transactional(propagation = Propagation.MANDATORY)
    public class ActionProcessServiceImpl implements ActionProcessService {
    
        @Inject
        SampleImwTPurchaseRepository repository;
    
        private final String PURCHASE_MATTER_PROPERTY_KEY = "item_total";
    
        // 申請
        public final String apply(final ActionProcessParameter parameter,
          final Map<String, Object> userParameter) throws Exception {
    
            System.out.println("----- ActionProcessParameter - apply -----");
            outputLog(parameter);
            System.out.println("----- ActionProcessParameter - apply -----");
    
            // サーバサイドバリデーションの実行
            validate(parameter, userParameter);
    
            // 案件番号の採番
            String number = null;
            try {
                number = WorkflowNumberingManager.getNumber();
            } catch (final WorkflowException e) {
                throw new WorkflowExternalException(
                  MessageManager.getInstance().getMessage(
                     LocaleUtil.toLocale(parameter.getLocaleId()), "SAMPLE.IMW.ERR.003"));
            }
    
            // 入力データのテーブルへの登録
            SampleImwTPurchase entity = getEntity(parameter, userParameter);
            repository.insert(entity);
    
            // 入力データの案件プロパティへの登録
            createMatterProperty(
               parameter.getUserDataId(), PURCHASE_MATTER_PROPERTY_KEY, entity.getItemTotal());
            return number;
        }
    

6.2. アクション処理

標準申請・処理画面にて申請・処理ボタンを押下するなど、ユーザが案件に関する処理を行った際に呼ばれる処理です。

  • ワークフローデータに加えて、申請・処理画面で入力されたユーザアプリケーションデータをUserParameterとして受け取ることが可能です。
  • ユーザアプリケーションデータに対してサーバサイド・バリデーションとデータベースへの永続化などを行います。

6.2.1. トリガーとなるユーザ操作

  • 具体的には、以下のユーザ操作がアクション処理のトリガーです。

  • トリガーとなるユーザ操作ごとに呼び出されるメソッドが異なります。

    アクション処理 メソッド一覧
    処理種別 メソッド 説明
    申請 apply 標準申請画面にて「申請」ボタンを押下した際に呼び出されるメソッドです。
    再申請 reapply 標準処理画面にて、処理種別「再申請」を選択し、「処理」ボタンを押下した際に呼び出されるメソッドです。
    申請(一時保存) applyFromTempSave 一時保存の状態で、標準申請画面にて「申請」ボタンを押下した際に呼び出されるメソッドです。
    申請(未処理) applyFromUnapply 未申請の状態で、標準申請画面にて「申請」ボタンを押下した際に呼び出されるメソッドです。
    取止め discontinue 標準処理画面にて、処理種別「取止め」を選択し、「処理」ボタンを押下した際に呼び出されるメソッドです。
    引戻し pullBack
    処理済み一覧で「引戻し」ボタンを押下した際に表示される標準画面にて、「引戻し」ボタンを押下した際に呼び出されるメソッドです。

    ユーザコンテンツ画面での操作を経由しないため、UserParameterはnullです。
    差戻し後引戻し sendBackToPullBack
    差戻しされた状態にて、処理済み一覧で「引戻し」ボタンを押下した際に表示される標準画面にて、「引戻し」ボタンを押下した際に呼び出されるメソッドです。

    ユーザコンテンツ画面での操作を経由しないため、UserParameterはnullです。
    承認 approve
    標準処理画面にて、処理種別「承認」を選択し、「処理」ボタンを押下した際に呼び出されるメソッドです。

    自動処理による承認の場合、ユーザコンテンツ画面での操作を経由しないため、UserParameterはnullです。
    一括処理による承認の場合、ユーザコンテンツ画面での操作を経由しないため、UserParameterは空のMapです。
    承認終了 approveEnd 標準処理画面にて、処理種別「承認終了」を選択し、「処理」ボタンを押下した際に呼び出されるメソッドです。
    否認 deny
    標準処理画面にて、処理種別「否認」を選択し、「処理」ボタンを押下した際に呼び出されるメソッドです。

    自動処理による否認の場合、ユーザコンテンツ画面での操作を経由しないため、UserParameterはnullです。
    差戻し sendBack
    標準処理画面にて、処理種別「差戻し」を選択し、「処理」ボタンを押下した際に呼び出されるメソッドです。

    自動処理による差戻しの場合、ユーザコンテンツ画面での操作を経由しないため、UserParameterはnullです。
    保留 reserve 標準処理画面にて、処理種別「保留」を選択し、「処理」ボタンを押下した際に呼び出されるメソッドです。
    保留解除 reserveCancel 標準処理画面にて、処理種別「保留解除」を選択し、「処理」ボタンを押下した際に呼び出されるメソッドです。
    案件操作 matterHandle
    案件操作画面にてノード移動を行った際に呼び出されるメソッドです。

    ユーザコンテンツ画面での操作を経由しないため、UserParameterはnullです。
    一時保存(新規登録) tempSaveCreate 標準画面にて「一時保存」ボタンを押下した際に呼び出されるメソッドです。
    一時保存(更新) tempSaveUpdate 一時保存の状態で、標準画面にて「一時保存」ボタンを押下した際に呼び出されるメソッドです。
    一時保存(削除) tempSaveDelete
    一時保存一覧画面にて、一時保存データに対する「削除」ボタンを押下した際に呼び出されるメソッドです。

    ユーザコンテンツ画面での操作を経由しないため、UserParameterはnullです。

6.2.2. 同期処理

  • アクション処理は標準申請・処理画面からのHTTPリクエストと同期的に実行されます。処理結果のメッセージを標準申請・処理画面に表示することが可能です。

    ただし、Controllerクラスとして呼び出される訳ではないので、Spring MVCの機能は利用できません。
  • 標準画面の処理の非同期

    ワークフローパラメータのstandard-exec-jssp-asyncをtrueに変更した場合は、アクション処理はHTTPリクエストと非同期で実行されます。

    コラム

    standard-exec-jssp-asyncの仕様については、 「 IM-Workflow 仕様書 」-「3.22 標準画面の処理の非同期」を参照してください。

6.2.3. トランザクション制御

  • アクション処理は IM-Workflow エンジン側が張るトランザクションの内部で呼び出されるため、データの一貫性を保証する必要がある処理です。 @Transactionalアノテーション を付与してトランザクションの管理を行う必要があります。

  • アクション処理内でシェアードデータベースへの更新処理を行うことはできません。

    IM-Workflow エンジンがテナントデータベースへトランザクションを張っている、かつ intra-mart Accel Platform ではXAトランザクションが利用できないため。

6.2.4. エラー処理

  • WorkflowExternalException をスローすることで、指定したメッセージを画面に表示することが可能です。

    メッセージIDではなく、メッセージ本文にて指定します。
    throw new WorkflowExternalException(
         MessageManager.getInstance().getMessage(
            LocaleUtil.toLocale(parameter.getLocaleId()), "SAMPLE.IMW.ERR.003"));
    

6.3. 到達処理

ノードに到達したタイミングで実行される処理です。

  • 下記のような場合に実行されます。

    • 前ノードの処理者が、「申請」または「承認」を行って到達した場合
    • 他のノードから、「差戻し」され到達した場合
    • 「引戻し」を行って到達した場合
    • 案件操作で到達した場合
  • 外部データベース上のユーザアプリケーションデータの更新やワークフローエンジンの制御などを行います。

  • ワークフローデータのみパラメータとして、受け取ることが可能です。

6.3.1. 非同期処理

  • 標準申請・処理画面からのHTTPリクエストとは非同期で実行されます。

    到達処理では、HTTPリクエスト・セッションの情報を参照することはできません。
  • 同期/非同期制御

    ワークフローパラメータのarrive-process-asyncをfalseに変更した場合は、到達処理はHTTPリクエストと同期的に実行されます。

    コラム

    arrive-process-asyncの仕様については、 「 IM-Workflow 仕様書 」-「5.1.1.1.1 案件終了処理、到達処理、メール送信処理、IMBox 送信処理の同期/非同期制御の設定」を参照してください。

6.3.2. トランザクション制御

  • 到達処理が実行されるタイミングでは IM-Workflow エンジンによるトランザクションが確定しているため、独自にトランザクション制御を行う必要があります。

    通常は、データベースへの更新処理を行うメソッドに対して、@Transactionalアノテーション を付加します。
    public class ArriveProcess extends ArriveProcessEventListener {
    
       public ArriveProcess() {
           super();
       }
    
       public boolean execute(final ArriveProcessParameter parameter) throws Exception {
          // 到達処理用のサービスを取得します。
          final ArriveProcessService service = ApplicationContextProvider.getApplicationContext().
                                             getBean(ArriveProcessService.class);
          service.execute(parameter);
       }
    
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class ArriveProcessServiceImpl implements ArriveProcessService {
    
        @Inject
        ExternalDatabaseRepository repository;
    
        @Override
        @Transactional(rollbackFor=java.lang.Exception.class)
        public boolean execute(
            final ArriveProcessParameter parameter) throws Exception {
            SampleImwTPurchase entity = repository.insert(parameter.getUserDataId());
            return true;
        }
    }
    

注意

到達処理では独自にトランザクション制御を行うことが可能ですが、 intra-mart Accel Platform にてXAトランザクションが利用できないため、テナントデータベースとシェアードデータベースに対して一括でコミットを行うことはできません。

6.4. 案件終了処理・案件終了処理(トランザクションなし)

案件終了処理・案件終了処理(トランザクションなし)は、案件が終了する時に一度実行される処理です。

  • 下記の場合に実行されます。

    • 最後の承認者が「承認」を行った場合
    • 承認者が「承認終了」を行った場合
    • 承認者が「否認」を行った場合
    • 申請者が「取止め」を行った場合
    • 案件操作で終了ノードに到達した場合
  • ワークフローデータのみパラメータとして、受け取ることが可能です。

6.4.1. 非同期処理

  • 標準申請・処理画面からのHTTPリクエストとは非同期で実行されます。

    案件終了処理・案件終了処理(トランザクションなし)では、HTTPリクエスト・セッションの情報を参照することはできません。

6.4.2. トランザクション制御

  • 直前のアクション処理や到達処理とは独立した処理となるため、案件終了処理・案件終了処理(トランザクションなし)でエラーが発生した場合、直前の処理を戻す(ロールバック)することはできません。
  • 案件終了処理(トランザクションなし)は、案件終了処理の前に実行され、独自にトランザクション制御を行う必要があります。
  • 案件終了処理は IM-Workflow エンジン側が張るトランザクションの内部で呼び出されるあめ、データの一貫性を保証する必要がある処理です。 @Transactionalアノテーション を付与してトランザクションの管理を行う必要があります。

6.4.3. エラー処理

  • Exceptionクラスをスローすることで、案件終了処理・案件終了処理(トランザクションなし)をエラーとすることが可能です。

    • 案件終了処理(トランザクションなし)

      ユーザプログラム側でトランザクション制御を行うため、エラー時にはユーザプログラム側でロールバックを行ってください。
    • 案件終了処理

      IM-Workflow エンジンの内部処理にてトランザクションを管理しているため、エラー時にユーザプログラム側でロールバックを行わないでください。
  • 案件終了処理・案件終了処理(トランザクションなし)がエラーとなった場合は、案件が完了せず、終了ノードで停止した状態に変化します。