1.5.4 Implementing a simple book order process (实现一个简单的订书流程)(上)
It would be a bit of a shame to stop chapter 1 with an example that contains just a start and an end event. So let’s enhance our simple book order process with a script task and a user task, so we can see a bit of action on the Activiti engine. First the script task will print an ISBN number that will be been given as input to the book order process when started. Then a user task will be used to handle the book ordering manually. So this is not the most efficient process, but it’s good for learning about BPMN 2.0 and Activiti.
用一个只包含开始和结束事件的示例草草了结本章,那会让人感到羞耻。所以让我们用脚本任务和用户任务来加强我们简单的订书流程,这样我们能看见Activiti 引擎的一些动作。首先脚本任务将打印ISBN好,当启动时将ISBN数字作为订书流程的输入。然后采用用户任务手动处理订书流程。所以这并不是最有效的流程,但是对于学习BPMN 2.0和Activiti大有裨益。
Activiti provides the possibility to use the scripting language you want, but Groovy is supported by default. So we’ll use a line of Groovy to print the ISBN process variable. In code listing 1.3 a revised version of the book order process of code listing 1.1 is shown.
尽管Activiti为使用脚本语言提供了可能性,但是缺省,只提供对Groovy的支持。所以,我们将使用一行Groovy打印ISBN变量。代码列表1.1的一个修订的订书流程如代码列表1.3所示。
Listing 1.3 A book order process with a script and user task
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
targetNamespace="http://www.bpmnwithactiviti.org">
<process id="bookorder" name="bookorder">
<startEvent id="startevent1" name="Start"/>
<scriptTask id="scripttask1" #A
name="Validate order"
scriptFormat="groovy">
<script>
out:print "validating order for isbn " + isbn + "\n"; #1
</script>
</scriptTask>
<sequenceFlow id="sequenceflow1" name="Validate order"
sourceRef="startevent1" targetRef="scripttask1"/>
<userTask id="usertask1" name="Complete order"> #2
<documentation>book order user task</documentation>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>sales</formalExpression> #B
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<sequenceFlow id="sequenceflow2" name="Sending to management"
sourceRef="scripttask1" targetRef="usertask1"/>
<endEvent id="endevent1" name="End"/>
<sequenceFlow id="sequenceflow3" name="Ending process"
sourceRef="usertask1" targetRef="endevent1"/>
</process>
</definitions>
#A Definition of a script task
#B Assign task to sales group
#1 Print the isbn
#2 Definition of a user task
With the two additional tasks added to the process definition, the number of lines of the XML file grows quite a bit. In the next chapter we’ll show the Activiti designer, which abstract you from the XML file when designing the process.
随着两项额外的任务添加到进程的定义,该行数XML的文件增长了不少。下一章我们将讨论Activiti设计器,当设计流程时时,让您从XML文件脱身。
The script task contains a out:print variable #1, which is a reserved word within the Activiti script task for printing text to the system console. Also notice that the isbn variable can be used directly in the script code without any additional programming.
脚本任务包含了out:print 变量 #1,它是Activiti脚本任务的保留字,它将文本打印到任务控制台。也要注意在脚本里可以直接使用isbn变量,而不需任何额外的编程。
The user task #2 contains a potential owner definition, which means that the task can be claimed and completed by users that are part of the group sales. When we run this process in a minute, we can see in the Activiti Explorer that this user task is available in the task list for the user kermit, who is part of the sales group.
用户任务#2包括一个潜在的用户定义,它意味着Sales组的用户可以领取和完成任务。当我们运行这个流程一会儿,在Activiti Explorer里,对于用户kermit的任务列表,有任务可用,因为kermit是sales组的人。
Now that we added more logic to the process, we also need to change our unit test. One thing we need to add is a process variable isbn when starting the process. And to test if the user task is created, we need to query the Activiti engine database for user tasks that can be claimed by the user kermit. Let’s take a look at the changed unit test in code listing 1.4.
既然我们把更多的逻辑加入到流程,那么也需要改变我们的单元测试。。当启动流程时,需要增加的一件事是增加流程变量isbn。为了测试是否建立了用户任务,我们需要查询Activiti引擎数据库能够由用户kermit领取的任务。让来看看代码列表1.2里的变化的单元测试。
Listing 1.4 A unit test with a process variable and user task query
public class BookOrderTest {
@Test
public void startBookOrder() {
ProcessEngine processEngine = new ProcessEngineBuilder()
.configureFromResource("activiti.cfg.xml")
.buildProcessEngine();
RuntimeService runtimeService =
processEngine.getRuntimeService();
RepositoryService repositoryService =
processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService(); #1
repositoryService.createDeployment()
.addClasspathResource("bookorder.bpmn20.xml")
.deploy();
Map<String, Object> variableMap = new HashMap<String, Object>();
variableMap.put("isbn", "123456");
ProcessInstance processInstance = #2
runtimeService.startProcessInstanceByKey( #2
"bookorder", variableMap); #2
assertNotNull(processInstance.getId());
System.out.println("id " + processInstance.getId() + " "
+ processInstance.getProcessDefinitionId());
List<Task> taskList = taskService.createTaskQuery() #A
.taskCandidateUser("kermit") #A
.list() #A
assertEquals(taskList.size(), 1);
for(Task task : taskList) {
System.out.println("found task " + task.getName());
}
}
}
#1 Get a TaskService instance
#2 Start a process with a variable
#A Find tasks available for kermit
The BookOrderTest unit test has been changed to start a process instance with a map of variables #2 that contains one variable with a name of isbn and a value of 123456. In addition, when the process instance has been started a TaskService instance #1 is used to retrieve the tasks available to claim by the user kermit. Because there is only one process instance running with one user task we test that the number of tasks retrieved is 1.
BookOrderTest单元测试已经用一个变量#2的map而变化之后启动了一个流程实例。这个马屁变量包含名为isbn,值为123456。另外,当流程变量已经启动TaskService实例#1时,用来检索用户kermit所领取的任务。因为只有一个流程变量运行一个用户任务,所以检索任务为1.
With the book order process in place and a new unit test we can run the unit test to see if our changes work. In the console you should see a similar output like:
因为订书流程准备就绪,运行一个新的单元测试来检查我们的改变是否发生作用。在控制台,您应该看到如下的输出:
validating order for isbn 123456
id 112 bookorder:1
found task Complete order
The first line is printed by the Groovy script task in the running process instance. The last line confirms that one user task is available for claim for the user kermit. Because a user task is created we should be able to see this task in the Activiti Explorer. Confirm that Tomcat has been started as part of the installation procedure. If this is not the case you canstart Tomcat with the Ant build script in the setup directory with the following command:
由运行的流程实例的Groovy脚本任务打印第一行。最后确定用户Kermit可领取的用户任务。因为已建立一个用户任务,所以我们应该在Activiti Explorer里看见这个任务。确认Tomcat已经作为安装过程的一部分已经启动。如果不是这种情况,你能够用setup目录下的Ant 构建以下面的命令启动Tomcat:
ant tomcat.start