本家 : 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 1343件 [詳細] filevacation1.png 1251件 [詳細] fileVariableProcess.png 2204件 [詳細] filevacation_form.png 1370件 [詳細] fileactiviti_subprocess.png 1374件 [詳細] fileSubProcess.png 1394件 [詳細] filemulti.png 1252件 [詳細] filebpmn.receive.task.png 1369件 [詳細] filebpmn.manual.task.png 1361件 [詳細] filemail3.png 1592件 [詳細] filemail2.png 1639件 [詳細] filemail1.png 1894件 [詳細] filetask_icons.png 1490件 [詳細] filemail_properties.png 1549件 [詳細] filebpmn.java.service.email.png 1379件 [詳細] fileusertask_properteis.png 1572件 [詳細] filegw_condition.png 1931件 [詳細] filegw_icons.png 1786件 [詳細] filecreate_sequence_flow.png 1895件 [詳細] fileevents.png 2504件 [詳細] filebpmn.user.task.png 1390件 [詳細] filebpmn.sequence.flow.png 1651件 [詳細] filebpmn.scripttask.png 1680件 [詳細] filebpmn.parallel.gateway.png 1613件 [詳細] filebpmn.java.service.task.png 1503件 [詳細] filebpmn.inclusive.gateway.png 1770件 [詳細] filebpmn.exclusive.gateway.png 1520件 [詳細] filebpmn.event.based.gateway.example.png 1643件 [詳細] fileevent_property.png 1864件 [詳細] fileb_timer.png 1791件 [詳細] fileb_signal.png 1617件 [詳細] fileb_message.png 1631件 [詳細] fileb_error.png 1535件 [詳細] filebpmn01.png 1689件 [詳細] filedeploy.png 1831件 [詳細] fileer.png 1992件 [詳細] filevacation.png 1860件 [詳細] filedesigner2.png 1825件 [詳細] filedesigner1.png 1736件 [詳細]

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