本家 : 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 1519件 [詳細] filevacation1.png 1424件 [詳細] fileVariableProcess.png 2371件 [詳細] filevacation_form.png 1538件 [詳細] fileactiviti_subprocess.png 1529件 [詳細] fileSubProcess.png 1578件 [詳細] filemulti.png 1438件 [詳細] filebpmn.receive.task.png 1537件 [詳細] filebpmn.manual.task.png 1526件 [詳細] filemail3.png 1787件 [詳細] filemail2.png 1807件 [詳細] filemail1.png 2072件 [詳細] filetask_icons.png 1633件 [詳細] filemail_properties.png 1731件 [詳細] filebpmn.java.service.email.png 1561件 [詳細] fileusertask_properteis.png 1740件 [詳細] filegw_condition.png 2107件 [詳細] filegw_icons.png 1967件 [詳細] filecreate_sequence_flow.png 2084件 [詳細] fileevents.png 2687件 [詳細] filebpmn.user.task.png 1564件 [詳細] filebpmn.sequence.flow.png 1830件 [詳細] filebpmn.scripttask.png 1846件 [詳細] filebpmn.parallel.gateway.png 1807件 [詳細] filebpmn.java.service.task.png 1675件 [詳細] filebpmn.inclusive.gateway.png 1979件 [詳細] filebpmn.exclusive.gateway.png 1697件 [詳細] filebpmn.event.based.gateway.example.png 1832件 [詳細] fileevent_property.png 2036件 [詳細] fileb_timer.png 1971件 [詳細] fileb_signal.png 1783件 [詳細] fileb_message.png 1813件 [詳細] fileb_error.png 1701件 [詳細] filebpmn01.png 1866件 [詳細] filedeploy.png 1992件 [詳細] fileer.png 2194件 [詳細] filevacation.png 2045件 [詳細] filedesigner2.png 1997件 [詳細] filedesigner1.png 1919件 [詳細]

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