本家 : http://www.activiti.org/userguide/

1. Introduction

2. Getting Started

3. Configuration


  1. 設定ファイルを明示する
    ProcessEngine processEngine 
    = ProcessEngineConfiguration
      .createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine()
  2. プログラム中で設定を行う (Activiti-Explorer、Activiti-Rest はこのやり方)
    • デフォルト設定
      ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
      ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
    • デフォルト設定に個別設定を追加
      ProcessEngine processEngine 
      = ProcessEngineConfiguration
         .createStandaloneInMemProcessEngineConfiguration()
         .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE)
         .setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000")
         .setAsyncExecutorEnabled(true)
         .setAsyncExecutorActivate(false)
         .buildProcessEngine();

3.16. Loggin

3.18. Event handlers

4. The Activiti API

4.1~4.3 ワークフローを実行するコンソールアプリ

開発環境

サンプルプロジェクト

activiti.cfg.xml

ここでは、テスト用の Table をロードする設定(StandaloneInMemProcessEngineConfiguration?)を使う

https://github.com/kagyuu/ActivitiExam/blob/master/src/main/resources/activiti.cfg.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">
 
  <!-- 3.2.processEngineConfiguration
  Stand alone app          : org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration
  Test (Use in-memory h2)  : org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration
  Spring integration       : org.activiti.spring.SpringProcessEngineConfiguration
  Stand alone app with JTA : org.activiti.engine.impl.cfg.JtaProcessEngineConfiguration
  -->
  <bean id="processEngineConfiguration"
  class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
 
    <!-- 3.3-3.8.database connection 
    support h2, musql, oracle, postgres, db2, mssql
    -->
    <property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
    <property name="jdbcDriver" value="org.h2.Driver" />
    <property name="jdbcUsername" value="sa" />
    <property name="jdbcPassword" value="" />
    <!-- Optional database connection properties * The unit of XXXTime is millisec *
    <property name="jdbcMaxActiveConnections" value="10" />
    <property name="jdbcMaxIdleConnections" value="" />
    <property name="jdbcMaxCheckoutTime" value="20000" />
    <property name="jdbcMaxWaitTime" value="20000" />
    -->
    <!-- Schema Update
    false (default) : If the db schema version != activiti lib version then abend
    true            : If the db schema version != activiti lib version then update db schema
    create-drop     : Always create and drop schema
    <property name="databaseSchemaUpdate" value="false" />
    -->
 
    <!-- 3.9-3.11 Job Executor
    By default, the JobExecutor is activated when the process engine boots.
    By default, the AsyncExecutor is not enabled and the JobExecutor is used
    due to legacy reasons.
    It?'s however recommended to use the new AsyncExecutor instead.
    -->
    <!--
    <property name="jobExecutorActivate" value="false" />
    <property name="asyncExecutorEnabled" value="true" />
    <property name="asyncExecutorActivate" value="true" />
    -->
 
    <!-- 3.12. Mail Configuration (for email task)
    |======================|=======================|    
    |property name         | Default value         |
    |======================|=======================|
    |mailServerHost        | localhost             |
    |mailServerPort        | 25                    |
    |mailServerDefaultFrom | activiti@activiti.org |
    |mailServerUsername    | (not set)             |
    |mailServerPassword    | (not set)             |
    |mailServerUseSSL      | (not set)             |
    |mailServerUseTLS      | (not set)             |
    |======================|=======================|
    -->
    <property name="mailServerHost" value="localhost" />
    <property name="mailServerPort" value="50025" />
 
    <!-- 3.13. History (for logging task execution)
    <property name="history" value="audit" />
    -->
 
    <!-- 3.15. Cache (default is no limit)
    <property name="processDefinitionCacheLimit" value="10" />
    -->
  </bean>
 
</beans>

テスト用BPMN (VacationRequest?.bpmn20.xml)

ActivitiExplorerのデモアプリ で使った休暇申請のワークフローを /src/main/resources/org/activiti/test に配置

vacation.png

Java コンソールアプリ

BMMNの配備(DB格納) → プロセス開始 (休暇申請) → 否決 → 再申請
の流れをやってみる

https://github.com/kagyuu/ActivitiExam/blob/master/src/main/java/com/snail/exam/MyProcess.java

package com.snail.exam;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyProcess {

    private static final Logger log = LoggerFactory.getLogger(MyProcess.class);

    public static void main(String[] args) {
        try {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

            // ----- 4.3.1. Deploying the process
            log.info("--- #1. Deploying the process");
            RepositoryService repositoryService = processEngine.getRepositoryService();
            repositoryService.createDeployment()
                    .addClasspathResource("org/activiti/test/VacationRequest.bpmn20.xml")
                    .deploy();

            log.info("Number of process definitions {}", repositoryService.createProcessDefinitionQuery().count());
            for (ProcessDefinition p : repositoryService.createProcessDefinitionQuery().list()) {
                log.info("PROCESS DEF [id={},name={},key={}]", p.getId(), p.getName(), p.getKey());
            }

            // ----- 4.3.2. Starting a process instance
            log.info("--- #2. Starting a process instance");

            //  VacationRequest.bpmn20.xml L3-10
            //  --------------------------------------------------------------------------
            //  <process id="vacationRequest" name="Vacation request" isExecutable="true">
            //               ^^^^^^^^^^^^^^^
            //    <startEvent id="request" activiti:initiator="employeeName">
            //                    ^^^^^^^*1                    ^^^^^^^^^^^^ $employeeName = the user name
            //      <extensionElements>
            //        <activiti:formProperty id="numberOfDays" name="Number of days" type="long" required="true">
            //                                   ^^^^^^^^^^^^                              ^^^^
            //        </activiti:formProperty>
            //        <activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" type="date"
            //                                   ^^^^^^^^^                                                ^^^^
            //        datePattern="dd-MM-yyyy hh:mm" required="true"></activiti:formProperty>
            //        <activiti:formProperty id="vacationMotivation" name="Motivation" type="string">
            //                                   ^^^^^^^^^^^^^^^^^^                          ^^^^^^
            //        </activiti:formProperty>
            //      </extensionElements>
            //    </startEvent>
            // <activiti:formProperty>
            Map<String, Object> variables = new HashMap<String, Object>();
            variables.put("employeeName", "Kermit");
            variables.put("numberOfDays", new Integer(4));
            variables.put("startDate", DateUtils.parseDate("1999-12-31", "yyyy-MM-dd"));
            variables.put("vacationMotivation", "I'm really tired!");

            // the process to run
            // id        : <process id="vacationRequest">
            // arguments : <activiti:formProperty>
            RuntimeService runtimeService = processEngine.getRuntimeService();
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vacationRequest", variables);

            log.info("Number of process instances: " + runtimeService.createProcessInstanceQuery().count());
            for (ProcessInstance p : runtimeService.createProcessInstanceQuery().list()) {
                log.info("PROCESS INSTANCE [id={},pid={},pname={},pkey={}]"
                        , p.getId()
                        , p.getProcessDefinitionId()
                        , p.getProcessDefinitionName()
                        , p.getProcessDefinitionKey());
            }
            
            // ----- 4.3.3. Completing tasks (Reject Request)
            //  VacationRequest.bpmn20.xml L11-21
            //  --------------------------------------------------------------------------
            //    <sequenceFlow id="flow1" sourceRef="request" targetRef="handleRequest"></sequenceFlow>
            //                                        ^^^^^^^*1           ^^^^^^^^^^^^^*2
            //    <userTask id="handleRequest" name="Handle vacation request" activiti:candidateGroups="management">
            //                  ^^^^^^^^^^^^^*2                                                         ^^^^^^^^^^
            //      <documentation>${employeeName} would like to take ${numberOfDays} day(s) of vacation
            //      (Motivation: ${vacationMotivation}).</documentation>
            //      <extensionElements>
            //        <activiti:formProperty id="vacationApproved" name="Do you approve this vacation" type="enum"
            //                                   ^^^^^^^^^^^^^^^^
            //        required="true">
            //          <activiti:value id="true" name="Approve"></activiti:value>
            //          <activiti:value id="false" name="Reject"></activiti:value>
            //        </activiti:formProperty>
            //        <activiti:formProperty id="managerMotivation" name="Motivation" type="string"></activiti:formProperty>
            //                                   ^^^^^^^^^^^^^^^^^
            //      </extensionElements>
            //    </userTask>
            log.info("--- #3. Completing tasks (Reject Request)");
            
            // Fetch all tasks for the management group
            TaskService taskService = processEngine.getTaskService();
            List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
            for (Task task : tasks) {
                if (task.getProcessDefinitionId().startsWith("vacationRequest")){
                    if (task.getTaskDefinitionKey().equals("handleRequest")) {
                        // Description is <documentation>.
                        log.info("TASK REJECT REQ [{}]", task.getDescription());
                        
                        // Do task (reject application)
                         Map<String, Object> taskVariables = new HashMap<String, Object>();
                         taskVariables.put("vacationApproved", "false");
                         taskVariables.put("managerMotivation", "We have a tight deadline!");
                         taskService.complete(task.getId(), taskVariables);
                    }
                }
            }
            
            // ----- 4.3.3. Completing tasks (Adjust rejected request)
			//  VacationRequest.bpmn20.xml L22-23
			//  --------------------------------------------------------------------------
			//  <sequenceFlow id="flow2" sourceRef="handleRequest" targetRef="requestApprovedDecision"></sequenceFlow>
			//                                      ^^^^^^^^^^^^^*2           ^^^^^^^^^^^^^^^^^^^^^^^*3
			//  <exclusiveGateway id="requestApprovedDecision" name="Request approved?"></exclusiveGateway>
			//                        ^^^^^^^^^^^^^^^^^^^^^^^*3
			//
			//  VacationRequest.bpmn20.xml L30-35
			//  --------------------------------------------------------------------------
			//  <sequenceFlow id="flow5" name="denied" sourceRef="requestApprovedDecision" targetRef="adjustVacationRequestTask">
			//                                                    ^^^^^^^^^^^^^^^^^^^^^^^*3           ^^^^^^^^^^^^^^^^^^^^^^^^^*4
			//            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${vacationApproved == 'false'}]]>
			//                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            //            </conditionExpression>
			//  </sequenceFlow>
			//  <userTask id="adjustVacationRequestTask" name="Adjust vacation request" activiti:assignee="${employeeName}">
			//                ^^^^^^^^^^^^^^^^^^^^^^^^^*4
			//            <documentation>Your manager has disapproved your vacation request for ${numberOfDays} days.
			//              Reason: ${managerMotivation}</documentation>
            log.info("--- #4. Completing tasks (Adjust rejected request)");

            taskService = processEngine.getTaskService();
            tasks = taskService.createTaskQuery().active().list();
            for (Task task : tasks) {
                if (task.getProcessDefinitionId().startsWith("vacationRequest")){
                    if (task.getTaskDefinitionKey().equals("adjustVacationRequestTask")) {
                        // Description is <documentation>.
                        log.info("ADJUST REJECT REQ [{}]", task.getDescription());
                    }
                }
            }
            

        } catch (Throwable th) {
            log.error("ERROR", th);
        }
    }
}

BPMNの配備 (RepositoryService?)

log.info("--- #1. Deploying the process");
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createDeployment()
        .addClasspathResource("org/activiti/test/VacationRequest.bpmn20.xml")
        .deploy()

プロセス開始 (RuntimeService?)

Map<String, Object> variables = new HashMap<String, Object>();
variables.put("employeeName", "Kermit");
variables.put("numberOfDays", new Integer(4));
variables.put("startDate", DateUtils.parseDate("1999-12-31", "yyyy-MM-dd"));
variables.put("vacationMotivation", "I'm really tired!");

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

タスク実行 (TaskService?)

TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
for (Task task : tasks) {
    if (task.getProcessDefinitionId().startsWith("vacationRequest")){
        if (task.getTaskDefinitionKey().equals("handleRequest")) {
            // Description is <documentation>.
            log.info("TASK REJECT REQ [{}]", task.getDescription());
            
            // Do task (reject application)
             Map<String, Object> taskVariables = new HashMap<String, Object>();
             taskVariables.put("vacationApproved", "false");
             taskVariables.put("managerMotivation", "We have a tight deadline!");
             taskService.complete(task.getId(), taskVariables);
        }
    }
}

4.3.4.プロセスの Suspend と Activate

https://github.com/kagyuu/ActivitiExam/blob/master/src/main/java/com/snail/exam/MyProcess2.java

package com.snail.exam;

import java.util.HashMap;
import java.util.Map;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyProcess2 {

    private static final Logger log = LoggerFactory.getLogger(MyProcess2.class);

    public static void main(String[] args) {
        try {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

            // ----- 4.3.1. Deploying the process
            log.info("--- #1. Deploying the process");
            RepositoryService repositoryService = processEngine.getRepositoryService();
            repositoryService.createDeployment()
                    .addClasspathResource("org/activiti/test/VacationRequest.bpmn20.xml")
                    .deploy();
            
            // ----- 4.3.4. Suspending and activating a process
            log.info("--- #2. Suspend Process");
            repositoryService.suspendProcessDefinitionByKey("vacationRequest");

            // ----- 4.3.2. Starting a process instance
            log.info("--- #3. Starting a process instance (will fail)");

            Map<String, Object> variables = new HashMap<String, Object>();
            variables.put("employeeName", "Kermit");
            variables.put("numberOfDays", new Integer(4));
            variables.put("startDate", DateUtils.parseDate("1999-12-31", "yyyy-MM-dd"));
            variables.put("vacationMotivation", "I'm really tired!");

            // the process to run
            // id        : <process id="vacationRequest">
            // arguments : <activiti:formProperty>
            RuntimeService runtimeService = processEngine.getRuntimeService();
            try {
                ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vacationRequest", variables);
            } catch (ActivitiException e) {
                log.error("ERROR", e);
            }
            
            // ----- 4.3.4. Suspending and activating a process
            log.info("--- #5. Activate Process");
            repositoryService.activateProcessDefinitionByKey("vacationRequest");
            
            log.info("--- #6. Starting a process instance (will success)");            
            try {
                ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vacationRequest", variables);
                log.info("{} was started", processInstance.getProcessDefinitionId());
            } catch (ActivitiException e) {
                log.error("ERROR", e);
            }
 
        } catch (Throwable th) {
            log.error("ERROR", th);
        }
    }
}

4.4 Query API

4.5.Variables

4.7 Unit Test

public class MyBusinessProcessTest {

  @Rule
  public ActivitiRule activitiRule = new ActivitiRule();

  @Test
  @Deployment
  public void ruleUsageExample() {
    RuntimeService runtimeService = activitiRule.getRuntimeService();
    runtimeService.startProcessInstanceByKey("ruleUsage");

    TaskService taskService = activitiRule.getTaskService();
    Task task = taskService.createTaskQuery().singleResult();
    assertEquals("My Task", task.getName());

    taskService.complete(task.getId());
    assertEquals(0, runtimeService.createProcessInstanceQuery().count());
  }
}

@Deployment で BPMN を配備することもできる

@Deplpyment(resources = {"org/activiti/examples/bpmn/executionListener/ExecutionListenersFieldInjectionProcess.bpmn20.xml"})

4.9 The process engine in a web application

@WebServletContextListener
public class ProcessEnginesServletContextListener implements ServletContextListener {

  public void contextInitialized(ServletContextEvent servletContextEvent) {
    ProcessEngines.init();
  }

  public void contextDestroyed(ServletContextEvent servletContextEvent) {
    ProcessEngines.destroy();
  }

}

コンソールアプリと同じように ProcessEngines?.getDefaultProcessEngine?() で ProcessEngine? を取得するが、アプリ再起動で確実に設定ファイルが反映されるように ServletContextListener?ProcessEngine?.init(), ProcessEngine?.destroy() を実行する

6. Deployment

7.標準 BPMN 2.0

8.Activiti 拡張 BPMN 2.0

8.2.Event

a graph image

8.3 Sequence Flow

a graph image

8.4 Gateways

a graph image

8.5 Task

a graph image

task_icons.png

8.5.1. User Task

bpmn.user.task.png

8.5.2. Script Task

bpmn.scripttask.png

8.5.3. Java Task

bpmn.java.service.task.png

8.5.6. Email Task

bpmn.java.service.email.png
    <serviceTask id="mailtask1" name="Mail Task" activiti:type="mail">
      <extensionElements>
        <activiti:field name="from">
          <activiti:string><![CDATA[order-shipping@thecompany.com]]></activiti:string>
        </activiti:field>
        <activiti:field name="to">
          <activiti:expression><![CDATA[foo@example.com]]></activiti:expression>
        </activiti:field>
        <activiti:field name="subject">
          <activiti:string><![CDATA[ENGLISH SUBJECT 日本語の件名]]></activiti:string>
        </activiti:field>
        <activiti:field name="charset">
          <activiti:string><![CDATA[iso-2022-jp]]></activiti:string>
        </activiti:field>
        <activiti:field name="text">
          <activiti:string><![CDATA[ENGLISH MESSAGE
日本語の本文]]></activiti:string>
        </activiti:field>
      </extensionElements>
    </serviceTask>

8.5.8. Camel Task (つかえない)

8.5.9. Manual Task

bpmn.manual.task.png

8.5.10. Java Receive Task

bpmn.receive.task.png

8.5.11. Shell Task (つかえない)

<serviceTask id="shellEcho" activiti:type="shell" >
  <extensionElements>
    <activiti:field name="command" stringValue="cmd" />
    <activiti:field name="arg1" stringValue="/c" />
    <activiti:field name="arg2" stringValue="echo" />
    <activiti:field name="arg3" stringValue="EchoTest" />
    <activiti:field name="wait" stringValue="true" />
    <activiti:field name="outputVariable" stringValue="resultVar" />
  </extensionElements>
</serviceTask>

8.15.12.Execution listener

8.5.13. Task listener

8.5.14 Multi-instance (for each)

8.6. Sub-Processes and Call Activities

9. Form


11.History

13. Activiti Explorer 14. Modeler

Java Activiti Explorer

15. REST API

Java Activiti REST API


Java#Activiti


*1 audit
*2 audit

添付ファイル: filevacation2.png 1522件 [詳細] filevacation1.png 1430件 [詳細] fileVariableProcess.png 2373件 [詳細] filevacation_form.png 1540件 [詳細] fileactiviti_subprocess.png 1533件 [詳細] fileSubProcess.png 1585件 [詳細] filemulti.png 1441件 [詳細] filebpmn.receive.task.png 1539件 [詳細] filebpmn.manual.task.png 1528件 [詳細] filemail3.png 1792件 [詳細] filemail2.png 1810件 [詳細] filemail1.png 2074件 [詳細] filetask_icons.png 1636件 [詳細] filemail_properties.png 1734件 [詳細] filebpmn.java.service.email.png 1564件 [詳細] fileusertask_properteis.png 1743件 [詳細] filegw_condition.png 2109件 [詳細] filegw_icons.png 1969件 [詳細] filecreate_sequence_flow.png 2088件 [詳細] fileevents.png 2693件 [詳細] filebpmn.user.task.png 1569件 [詳細] filebpmn.sequence.flow.png 1833件 [詳細] filebpmn.scripttask.png 1848件 [詳細] filebpmn.parallel.gateway.png 1811件 [詳細] filebpmn.java.service.task.png 1680件 [詳細] filebpmn.inclusive.gateway.png 1985件 [詳細] filebpmn.exclusive.gateway.png 1701件 [詳細] filebpmn.event.based.gateway.example.png 1835件 [詳細] fileevent_property.png 2038件 [詳細] fileb_timer.png 1977件 [詳細] fileb_signal.png 1785件 [詳細] fileb_message.png 1817件 [詳細] fileb_error.png 1703件 [詳細] filebpmn01.png 1867件 [詳細] filedeploy.png 1994件 [詳細] fileer.png 2198件 [詳細] filevacation.png 2050件 [詳細] filedesigner2.png 2000件 [詳細] filedesigner1.png 1924件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2018-01-30 (火) 01:18:32 (2504d)
Short-URL: http://at-sushi.com/pukiwiki/index.php?cmd=s&k=ef43fa2fec
ISBN10
ISBN13
9784061426061