本家 : 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 1525件 [詳細] filevacation1.png 1434件 [詳細] fileVariableProcess.png 2377件 [詳細] filevacation_form.png 1545件 [詳細] fileactiviti_subprocess.png 1538件 [詳細] fileSubProcess.png 1588件 [詳細] filemulti.png 1445件 [詳細] filebpmn.receive.task.png 1541件 [詳細] filebpmn.manual.task.png 1531件 [詳細] filemail3.png 1798件 [詳細] filemail2.png 1814件 [詳細] filemail1.png 2078件 [詳細] filetask_icons.png 1639件 [詳細] filemail_properties.png 1739件 [詳細] filebpmn.java.service.email.png 1570件 [詳細] fileusertask_properteis.png 1754件 [詳細] filegw_condition.png 2113件 [詳細] filegw_icons.png 1974件 [詳細] filecreate_sequence_flow.png 2096件 [詳細] fileevents.png 2697件 [詳細] filebpmn.user.task.png 1575件 [詳細] filebpmn.sequence.flow.png 1838件 [詳細] filebpmn.scripttask.png 1852件 [詳細] filebpmn.parallel.gateway.png 1818件 [詳細] filebpmn.java.service.task.png 1684件 [詳細] filebpmn.inclusive.gateway.png 1991件 [詳細] filebpmn.exclusive.gateway.png 1707件 [詳細] filebpmn.event.based.gateway.example.png 1841件 [詳細] fileevent_property.png 2041件 [詳細] fileb_timer.png 1980件 [詳細] fileb_signal.png 1790件 [詳細] fileb_message.png 1822件 [詳細] fileb_error.png 1706件 [詳細] filebpmn01.png 1870件 [詳細] filedeploy.png 2000件 [詳細] fileer.png 2204件 [詳細] filevacation.png 2054件 [詳細] filedesigner2.png 2003件 [詳細] filedesigner1.png 1927件 [詳細]

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