Javaを使ったActivitiのガイド

Javaを使用したActivitiのガイド

1. 概要

Activiti APIは、ワークフローおよびビジネスプロセス管理システムです。 APIで提供されるサービスを使用して、さまざまな方法でプロセスを定義、実行、操作できます。 JDK 7が必要です。

APIを使用した開発は、どのIDEでも実行できますが、Activiti Designerを使用するには、Eclipseが必要です。

BPMN 2.0標準を使用して、プロセスを定義できます。 もう1つの、あまり一般的ではない方法があります。StartEventEndEventUserTaskSequenceFlowなどのJavaクラスを使用します。

プロセスを実行したり、サービスにアクセスしたりする場合は、ProcessEngineConfigurationを作成する必要があります。

いくつかの方法でProcessEngineConfiguration,を使用してProcessEngineを取得できます。これについては、この記事で詳しく説明します。._ the _ProcessEngineを介して、ワークフローおよびBPMN操作を実行できます。

2. Mavenの依存関係

このAPIを使用するには、Activiti依存関係を含める必要があります。


    org.activiti
    activiti-engine

3. ProcessEngineの作成

ActivitiのProcessEngineは、通常、XMLファイルactiviti.cfg.xmlを使用して構成されます。 この構成ファイルの例は次のとおりです。


    
        
        
        
        
        
    

これで、ProcessEnginesクラスを使用してProcessEngineを取得できます。

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

このステートメントは、クラスパスでactiviti.cfg.xmlファイルを検索し、ファイルの構成に基づいてProcessEngineを作成します。

構成ファイルのサンプルコードは、Springベースの構成であることを示しています。 しかし、これは、ActivitiをSpring環境でしか使用できないという意味ではありません。 Springの機能は、ProcessEngineを作成するために内部的に使用されるだけです。

上記の構成ファイルを使用してProcessEngineを作成するJUnitテストケースを作成しましょう。

@Test
public void givenXMLConfig_whenGetDefault_thenGotProcessEngine() {
    ProcessEngine processEngine
      = ProcessEngines.getDefaultProcessEngine();
    assertNotNull(processEngine);
    assertEquals("root", processEngine.getProcessEngineConfiguration()
      .getJdbcUsername());
}

4. Activiti Process EngineAPIおよびサービス

APIとの相互作用のエントリポイントはProcessEngineです。 ProcessEngine,を介して、ワークフロー/ BPMNメソッドを提供するさまざまなサービスにアクセスできます。 ProcessEngineとすべてのサービスオブジェクトはスレッドセーフです。

image

ProcessEnginesクラスは、activiti.cfg.xmlファイルとactiviti-context.xmlファイルをスキャンします。 前述のように、すべてのactiviti.cfg.xmlファイルについて、ProcessEngineは通常の方法で作成されます。

一方、すべてのactiviti-context.xmlファイルについては、Springの方法で作成されます— Springアプリケーションコンテキストを作成し、そこからProcessEngineを取得します。 プロセスの実行中、すべてのステップはBPMNファイルで定義された順序でアクセスされます。

プロセスの実行中、すべてのステップはBPMNファイルで定義された順序でアクセスされます。

A ProcessDefinition represents a business process.プロセスのさまざまなステップの構造と動作を定義するために使用されます。 プロセス定義の展開とは、プロセス定義をActivitiデータベースにロードすることを意味します。

プロセス定義は、主にBPMN 2.0標準によって定義されています。 Javaコードを使用して定義することもできます。 このセクションで定義されているすべての用語は、Javaクラスとしても利用できます。

プロセス定義の実行を開始すると、それをプロセスと呼ぶことができます

ProcessInstanceは、ProcessDefinition.の1回の実行です。

A StartEvent is associated with every business process. It indicates the entry point of the process.同様に、プロセスの終了を示すEndEventがあります。 これらのイベントに対する条件を定義できます。

開始と終了の間のすべてのステップ(または要素)は、Tasksと呼ばれます。 Tasksにはさまざまなタイプがあります。 最も一般的に使用されるタスクはUserTasksServiceTasksです。

UserTasksは、その名前が示すように、ユーザーが手動で実行する必要があるようなものです。

一方、ServiceTasksは、コードの一部で構成されます。 実行がそれらに到達するたびに、コードのブロックが実行されます。

SequenceFlowsTasksを接続します。 SequenceFlowsは、接続するソース要素とターゲット要素によって定義できます。 ここでも、SequenceFlowsに条件を定義して、プロセスに条件付きパスを作成することもできます。

4.2. サービス内容

Activitiが提供するサービスについて簡単に説明します。

  • RepositoryServiceは、プロセス定義のデプロイメントを操作するのに役立ちます。 このサービスは、プロセス定義に関連する静的データを処理します

  • RuntimeServiceは、ProcessInstances(現在実行中のプロセス)とプロセス変数を管理します

  • TaskServiceUserTasksを追跡します。 ユーザーが手動で実行する必要のあるTasksは、ActivitiAPIの中核です。 タスクの作成、タスクの要求と完了、タスクの担当者の操作などを行うことができます。 このサービスを使用して

  • FormServiceはオプションのサービスです。 APIは、それなしで、またその機能を犠牲にすることなく使用できます。 プロセスの開始フォームとタスクフォームを定義するために使用されます。

  • IdentityServiceUsersGroupsを管理します

  • HistoryServiceは、ActivitiEngineの履歴を追跡します。 さまざまな履歴レベルを設定することもできます。

  • ManagementServiceはメタデータに関連しており、通常、アプリケーションの作成時には必要ありません。

  • DynamicBpmnServiceは、プロセスを再デプロイせずにプロセス内の何かを変更するのに役立ちます

5. Activitiサービスの操作

さまざまなサービスを操作してプロセスを実行する方法を学ぶために、「従業員の休暇申請」のプロセスの例を見てみましょう。

image

このプロセスのBPMN2.0ファイルVacationRequest.bpmn20.xmlには、開始イベントが次のように定義されています。


    
        
        
        
     

同様に、ユーザーグループ「管理」に割り当てられた最初のユーザータスクは次のようになります。


    ${employeeName} would like to take ${numberOfDays} day(s)
      of vacation (Motivation: ${reason}).
    
        
        
    
    
      
        management
      
    

ServiceTask,を使用して、実行するコードを定義する必要があります。 このコードはJavaクラスとしてあります。


条件付きフローは、“sequenceFlow”:“conditionExpression”タグを追加することで示されます。


    
      
    

ここで、vacationApprovedは、上記のUserTaskformPropertyです。

図からわかるように、非常に簡単なプロセスです。 従業員は休暇のリクエストを行い、休暇の日数と開始日を提供します。 要求はマネージャーに送られます。 彼らはリクエストを承認/不承認にすることができます。

承認された場合、確認メールを送信するために定義されたサービスタスクがあります。 不承認の場合、従業員はリクエストを変更して再送信するか、何もしないことを選択できます。

サービスタスクには、実行するコードの一部が(ここではJavaクラスとして)提供されます。 クラスにSendEmailServiceTask.java.を与えました

これらのタイプのクラスはJavaDelegate.を拡張する必要があります。また、プロセスの実行がこのステップに達したときに実行されるexecute()メソッドをオーバーライドする必要があります。

5.1. プロセスの展開

プロセスをActivitiエンジンに知らせるには、プロセスを展開する必要があります。 RepositoryService.を使用してプログラムで実行できます。これを示すJUnitテストを作成しましょう。

@Test
public void givenBPMN_whenDeployProcess_thenDeployed() {
    ProcessEngine processEngine
      = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService
      = processEngine.getRepositoryService();
    repositoryService.createDeployment()
      .addClasspathResource(
      "org/activiti/test/vacationRequest.bpmn20.xml")
      .deploy();
    Long count=repositoryService.createProcessDefinitionQuery().count();
    assertEquals("1", count.toString());
}

デプロイメントとは、エンジンがBPMNファイルを解析し、実行可能なものに変換することを意味します。 また、各デプロイメントのリポジトリテーブルにレコードが追加されます。

したがって、後で、Repositoryサービスにクエリを実行して、デプロイされたプロセスを取得できます。 ProcessDefinitions

5.2. ProcessInstanceの開始

ProcessDefinitionをActiviti Engineにデプロイした後、ProcessInstancesを作成してプロセスを実行できます。 ProcessDefinitionは青写真であり、ProcessInstanceはその実行時の実行です。

単一のProcessDefinitionの場合、複数のProcessInstancesが存在する可能性があります。

ProcessInstancesに関連するすべての詳細には、RuntimeServiceからアクセスできます。

この例では、開始イベントで、休暇日数、開始日、および理由を渡す必要があります。 プロセス変数を使用し、ProcessInstance.を作成するときにそれらを渡します

より良いアイデアを得るために、JUnitテストケースを書いてみましょう。

@Test
public void givenDeployedProcess_whenStartProcessInstance_thenRunning() {
    //deploy the process definition
    Map variables = new HashMap>();
    variables.put("employeeName", "John");
    variables.put("numberOfDays", 4);
    variables.put("vacationMotivation", "I need a break!");

    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance processInstance = runtimeService
      .startProcessInstanceByKey("vacationRequest", variables);
    Long count=runtimeService.createProcessInstanceQuery().count();

    assertEquals("1", count.toString());
}

単一のプロセス定義の複数のインスタンスは、プロセス変数によって異なります。

プロセスインスタンスを開始する方法は複数あります。 ここでは、プロセスのキーを使用しています。 プロセスインスタンスを開始した後、RuntimeServiceをクエリすることで、プロセスインスタンスに関する情報を取得できます。

5.3. タスクの完了

プロセスインスタンスの実行が開始されると、最初のステップはユーザータスクであり、ユーザーグループ“management”.に割り当てられます。

ユーザーは、自分が実行するタスクのリストを含む受信トレイを持っている場合があります。 ここで、プロセスの実行を継続する場合、ユーザーはこのタスクを完了する必要があります。 Activiti Engineの場合、これは「タスクの完了」と呼ばれます。

TaskService,にクエリを実行してタスクオブジェクトを取得し、それを完了することができます。

このために記述する必要があるコードは次のようになります。

@Test
public void givenProcessInstance_whenCompleteTask_thenGotNextTask() {
    // deploy process and start process instance
    TaskService taskService = processEngine.getTaskService();
    List tasks = taskService.createTaskQuery()
      .taskCandidateGroup("management").list();
    Task task = tasks.get(0);

    Map taskVariables = new HashMap<>();
    taskVariables.put("vacationApproved", "false");
    taskVariables.put("comments", "We have a tight deadline!");
    taskService.complete(task.getId(), taskVariables);

    Task currentTask = taskService.createTaskQuery()
      .taskName("Modify vacation request").singleResult();
    assertNotNull(currentTask);
}

TaskServicecomplete()メソッドも必要なプロセス変数を取り込むことに注意してください。 マネージャーからの返信を渡します。

この後、プロセスエンジンは次の手順に進みます。 ここで、次のステップでは、休暇申請を再送信するかどうかを従業員に尋ねます。

したがって、ProcessInstanceは、“Modify vacationリクエストという名前のこのUserTask,で待機しています。

5.4. プロセスの一時停止とアクティブ化

ProcessDefinitionProcessInstanceを一時停止できます。 ProcessDefinition,を一時停止すると、一時停止中はインスタンスを作成できません。 RepositoryService:を使用してこれを行うことができます

@Test(expected = ActivitiException.class)
public void givenDeployedProcess_whenSuspend_thenNoProcessInstance() {
    // deploy the process definition
    repositoryService.suspendProcessDefinitionByKey("vacationRequest");
    runtimeService.startProcessInstanceByKey("vacationRequest");
}

再度アクティブにするには、repositoryService.activateProcessDefinitionXXXメソッドの1つを呼び出す必要があります。

同様に、RuntimeService.を使用してProcessInstance,を一時停止できます

6. 結論

この記事では、ActivitiをJavaで使用する方法を説明しました。 ProcessEngineの作成に役立つサンプルProcessEngineCofigurationファイルを作成しました。

これを使用して、APIが提供するさまざまなサービスにアクセスしました。 これらのサービスは、ProcessDefinitionsProcessInstancesUserTasksなどを管理および追跡するのに役立ちます。

いつものように、この記事で見た例のコードはover on GitHubにあります。