本家 : 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 1357件 [詳細] filevacation1.png 1263件 [詳細] fileVariableProcess.png 2215件 [詳細] filevacation_form.png 1380件 [詳細] fileactiviti_subprocess.png 1384件 [詳細] fileSubProcess.png 1404件 [詳細] filemulti.png 1267件 [詳細] filebpmn.receive.task.png 1380件 [詳細] filebpmn.manual.task.png 1369件 [詳細] filemail3.png 1603件 [詳細] filemail2.png 1647件 [詳細] filemail1.png 1905件 [詳細] filetask_icons.png 1501件 [詳細] filemail_properties.png 1558件 [詳細] filebpmn.java.service.email.png 1387件 [詳細] fileusertask_properteis.png 1582件 [詳細] filegw_condition.png 1940件 [詳細] filegw_icons.png 1796件 [詳細] filecreate_sequence_flow.png 1906件 [詳細] fileevents.png 2516件 [詳細] filebpmn.user.task.png 1398件 [詳細] filebpmn.sequence.flow.png 1661件 [詳細] filebpmn.scripttask.png 1691件 [詳細] filebpmn.parallel.gateway.png 1624件 [詳細] filebpmn.java.service.task.png 1518件 [詳細] filebpmn.inclusive.gateway.png 1780件 [詳細] filebpmn.exclusive.gateway.png 1530件 [詳細] filebpmn.event.based.gateway.example.png 1652件 [詳細] fileevent_property.png 1877件 [詳細] fileb_timer.png 1807件 [詳細] fileb_signal.png 1627件 [詳細] fileb_message.png 1641件 [詳細] fileb_error.png 1545件 [詳細] filebpmn01.png 1702件 [詳細] filedeploy.png 1843件 [詳細] fileer.png 2001件 [詳細] filevacation.png 1871件 [詳細] filedesigner2.png 1836件 [詳細] filedesigner1.png 1746件 [詳細]

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