Activiti CamelTask(骆驼任务)

作者:邓家海

人生想讲个不成熟的建议

前言:

Camel任务可以从Camel发送和介绍消息,由此强化了activiti的集成功能。 注意camel任务不是BPMN 2.0规范定义的官方任务。 (它也没有对应的图标)。 在activiti中,camel任务时由专用的服务任务实现的。

什么是Camel?

Camel能够在大量的领域语言中让你定义路由以及中间规则,包括基于Java的Fluent API,Spring或者Blueprint XML配置文件,甚至是Scala(是一种基于JVM,集合了面向对象编程和函数式编程优点的高级程序设计语言)DSL。 您能够通过你的IDE或者Java、Scala或者XML编辑器里获得智能化路由规则补全功能。

camel首先是一个规则引擎。其次才是一个开源项目。

Apache Camel是Apache基金会下的一个开源项目,它是一个基于规则路由和中介引擎,提供企业集成模式的Java对象的实现,通过应用程序接口(或称为陈述式的Java领域特定语言(DSL))来配置路由和中介的规则。领域特定语言意味着Apache Camel支持你在的集成开发工具中使用平常的,类型安全的,可自动补全的Java代码来编写路由规则,而不需要大量的XML配置文件。同时,也支持在Spring中使用XML配置定义路由和中介规则。

Camel提供的基于规则的路由(Routing)引擎

from().to().to()

这种表述可以使用Camel定义的DSL语言,xml语言以及scala语言。如下例:

from(“file:path").to("activemq:queue:queuename") 将某文件,读入并写入到ActiveMQ的JMS中。

form("file:path").to("ftp://url")将一个文件,读入并写入到ftp某目录中。

 

开发涉及的jar包

camel-core-2.19.1.jar

camel-spring-2.19.1.jar

activiti-camel-5.22.0.jar

Camel任务图标

注意:camel任务不是BPMN 2.0标准,它只是Activiti的一个扩展。

流程图设计以及配置:

这是一个非常简单的流程图,只有开始和结束、camel任务节点。实际应用中根据实际情况扩展。

流程图源码:

 1 <?xml version='1.0' encoding='UTF-8'?>
 2
 3 <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
 4
 5   <process id="CamelProcess" isExecutable="true">
 6
 7     <startEvent id="sid-80400B65-221F-4DE2-A7AF-1788341E7FAA">
 8
 9       <extensionElements>
10
11         <activiti:executionListener event="start" class="light.mvc.workflow.taskListener.CamelListenerImpl" />
12
13       </extensionElements>
14
15     </startEvent>
16
17     <serviceTask id="MyCamelCall" name="camel任务" activiti:type="camel" />
18
19     <endEvent id="sid-6920138F-F17F-43A3-8C54-D339AC234DF8" />
20
21     <sequenceFlow id="sid-23D8E093-77BF-4D8A-8954-3730952ADEF6" sourceRef="MyCamelCall" targetRef="sid-6920138F-F17F-43A3-8C54-D339AC234DF8" />
22
23     <sequenceFlow id="sid-7B6E8FB0-B1F6-425A-8897-C9CF6A2050CB" sourceRef="sid-80400B65-221F-4DE2-A7AF-1788341E7FAA" targetRef="MyCamelCall" />
24
25   </process>
26
27   <bpmndi:BPMNDiagram id="BPMNDiagram_CamelProcess">
28
29     <bpmndi:BPMNPlane bpmnElement="CamelProcess" id="BPMNPlane_CamelProcess">
30
31       <bpmndi:BPMNShape bpmnElement="sid-80400B65-221F-4DE2-A7AF-1788341E7FAA" id="BPMNShape_sid-80400B65-221F-4DE2-A7AF-1788341E7FAA">
32
33         <omgdc:Bounds height="30.0" width="30.0" x="223.75" y="86.0" />
34
35       </bpmndi:BPMNShape>
36
37       <bpmndi:BPMNShape bpmnElement="MyCamelCall" id="BPMNShape_MyCamelCall">
38
39         <omgdc:Bounds height="80.0" width="100.36219727999998" x="356.56890136" y="61.0" />
40
41       </bpmndi:BPMNShape>
42
43       <bpmndi:BPMNShape bpmnElement="sid-6920138F-F17F-43A3-8C54-D339AC234DF8" id="BPMNShape_sid-6920138F-F17F-43A3-8C54-D339AC234DF8">
44
45         <omgdc:Bounds height="28.0" width="28.0" x="600.0" y="87.0" />
46
47       </bpmndi:BPMNShape>
48
49       <bpmndi:BPMNEdge bpmnElement="sid-23D8E093-77BF-4D8A-8954-3730952ADEF6" id="BPMNEdge_sid-23D8E093-77BF-4D8A-8954-3730952ADEF6">
50
51         <omgdi:waypoint x="456.93109863999996" y="101.0" />
52
53         <omgdi:waypoint x="600.0" y="101.0" />
54
55       </bpmndi:BPMNEdge>
56
57       <bpmndi:BPMNEdge bpmnElement="sid-7B6E8FB0-B1F6-425A-8897-C9CF6A2050CB" id="BPMNEdge_sid-7B6E8FB0-B1F6-425A-8897-C9CF6A2050CB">
58
59         <omgdi:waypoint x="253.75" y="101.0" />
60
61         <omgdi:waypoint x="356.56890136" y="101.0" />
62
63       </bpmndi:BPMNEdge>
64
65     </bpmndi:BPMNPlane>
66
67   </bpmndi:BPMNDiagram>
68
69 </definitions>

这里在开始任务设置了一个监听类:

监听类实现代码:

 

  1 /**
  2
  3  *
  4
  5  */
  6
  7 package light.mvc.workflow.taskListener;
  8
  9
 10
 11 import java.util.HashMap;
 12
 13 import java.util.Map;
 14
 15
 16
 17 import light.mvc.service.workflow.impl.DelegateServiceImpl;
 18
 19 import light.mvc.workflow.model.DelegateInfo;
 20
 21
 22
 23 import org.activiti.engine.delegate.DelegateExecution;
 24
 25 import org.activiti.engine.delegate.DelegateTask;
 26
 27 import org.activiti.engine.delegate.JavaDelegate;
 28
 29 import org.activiti.engine.delegate.TaskListener;
 30
 31 import org.springframework.beans.factory.annotation.Autowired;
 32
 33
 34
 35 /**
 36
 37  *
 38
 39  * 项目名称:lightmvc
 40
 41  * 类名称:TaskAsigneeListenerImpl
 42
 43  * 类描述:
 44
 45  * 创建人:邓家海
 46
 47  * 创建时间:2017年6月1日 下午11:48:55
 48
 49  * 修改人:deng
 50
 51  * 修改时间:2017年6月1日 下午11:48:55
 52
 53  * 修改备注:
 54
 55  * @version
 56
 57  *
 58
 59  */
 60
 61
 62
 63 public class CamelListenerImpl implements TaskListener,JavaDelegate {
 64
 65 @Override
 66
 67 public void notify(DelegateTask delegateTask) {
 68
 69  System.out.println("CamelListenerImpl notify is running");
 70
 71   Map<String,Object> map = delegateTask.getVariables();
 72
 73
 74
 75
 76
 77   Map<String, Object> variables = new HashMap<String, Object>();
 78
 79
 80
 81   variables.put("input", "Hello");
 82
 83   Map<String, String> outputMap = new HashMap<String, String>();
 84
 85   variables.put("outputMap", outputMap);
 86
 87   delegateTask.setVariables(variables);
 88
 89 }
 90
 91
 92
 93 @Override
 94
 95 public  void execute(DelegateExecution delegateTask) throws Exception {
 96
 97 // TODO Auto-generated method stub
 98
 99  System.out.println("CamelListenerImpl execute is running");
100
101   Map<String,Object> map = delegateTask.getVariables();
102
103
104
105
106
107   Map<String, Object> variables = new HashMap<String, Object>();
108
109
110
111   variables.put("input", "Hello");
112
113   Map<String, String> outputMap = new HashMap<String, String>();
114
115   variables.put("outputMap", outputMap);
116
117   delegateTask.setVariables(variables);
118
119 }
120
121 }

Camel路由规则的配置:

路由的设置有两种方式,第一种是通过java类来配置,另外一种是通过Spring配置文件配置。

(1)Java类配置:

Spring的环境下扫描路由配置

1 <camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
2
3         <packageScan>
4
5                 <package>light.mvc.workflow.camelRoute</package>
6
7         </packageScan>
8
9 </camelContext>

Java配置类

 1 /**
 2
 3  *
 4
 5  */
 6
 7 package light.mvc.workflow.camelRoute;
 8
 9
10
11 import org.apache.camel.builder.RouteBuilder;
12
13
14
15 /**
16
17  *
18
19  * 项目名称:lightmvc
20
21  * 类名称:MyCamelCallRoute
22
23  * 类描述:
24
25  * 创建人:邓家海
26
27  * 创建时间:2017年6月24日 下午9:00:55
28
29  * 修改人:deng
30
31  * 修改时间:2017年6月24日 下午9:00:55
32
33  * 修改备注:
34
35  * @version
36
37  *
38
39  */
40
41
42
43 public class MyCamelCallRoute extends RouteBuilder  {
44
45     public MyCamelCallRoute(){
46
47      System.out.println("MyCamelCallRoute is running");
48
49     }
50
51 @Override
52
53 public void configure() throws Exception {
54
55 // TODO Auto-generated method stub
56
57 // from("activiti:CamelProcess:MyCamelCall").to("log:light.mvc.workflow.camelRoute");
58
59 System.out.println("MyCamelCallRoute is running");
60
61
62
63 from("activiti:CamelProcess:MyCamelCall").to("direct:start-activiti");
64
65 from("direct:start-activiti").to("activiti:CamelStartprocess");
66
67 //from("activiti:CamelProcess:MyCamelCall?copyCamelBodyToBody=true").transform().simple("${property.input} ,jesai");
68
69
70
71
72
73 }
74
75 }

(2)Spring配置文件配置:

 1 <camelContext id="testCamelContext" xmlns="http://camel.apache.org/schema/spring">
 2
 3          <route>
 4
 5              <from uri="file:d:/temp/inbox?delay=30000"/>
 6
 7               <process ref="fileConverter"/>
 8
 9              <to uri="file:d:/temp/outbox"/>
10
11          </route>
12
13      </camelContext>  

至此。一个简单的Activiti整合Camel的例子就已经完成了。运行部署就可以发现,控制台输出

CamelListenerImpl execute is running

 

同步和异步

之前的例子都是同步的。流程会等到camel规则返回之后才会停止。 一些情况下,我们需要activiti工作流继续运行。这时camelServiceTask的异步功能就特别有用。 你可以通过设置camelServiceTask的async属性来启用这个功能。

1 <serviceTask id="serviceAsyncPing" activiti:type="camel" activiti:async="true"/>

通过设置这个功能,camel规则会被activiti的jobExecutor异步执行。 当你在camel规则中定义了一个队列,activiti流程会在camelServiceTask执行时继续运行。 camel规则会以完全异步的方式执行。 如果你想在什么地方等待camelServiceTask的返回值,你可以使用一个receiveTask。

1 <receiveTask id="receiveAsyncPing" name="Wait State" />

 

关于Camel路由规则:

例如:

1 public class SimpleCamelCallRoute extends RouteBuilder {
2
3   @Override
4   public void configure() throws Exception {
5
6           from("activiti:SimpleCamelCallProcess:simpleCall").to("log: org.activiti.camel.examples.SimpleCamelCall");
7   }
8 }

 

注:部分 说明

终端URL 引用activiti终端

SimpleCamelCallProcess 流程名

simpleCall 流程中的Camel服务

 

(1)from("activiti:CamelProcess:MyCamelCall").to("log:light.mvc.workflow.camelRoute");

这个路由规则只是打印日志,什么也不做。

(2)

from("activiti:CamelProcess:MyCamelCall").to("direct:start-activiti");

from("direct:start-activiti").to("activiti:CamelStartprocess");

这个规则可以从已有的任务启动过程中去启动另外一个已经部署完成等待启动的任务。比如在这里,我们可以尝试去启动一个ServiceTask任务

1)首先我们有一个已经部署好的可以运行的ServiceTask任务。流程名称叫做CamelStartprocess

2)这个规则任务有一个监听类:

 1 /**
 2
 3  *
 4
 5  */
 6
 7 package light.mvc.workflow.serviceTask;
 8
 9
10
11 import org.activiti.engine.delegate.DelegateExecution;
12
13 import org.activiti.engine.delegate.Expression;
14
15 import org.activiti.engine.delegate.JavaDelegate;
16
17
18
19 /**
20
21  *
22
23  * 项目名称:lightmvc
24
25  * 类名称:ServiceTask
26
27  * 类描述:
28
29  * 创建人:邓家海
30
31  * 创建时间:2017年6月4日 下午6:18:11
32
33  * 修改人:deng
34
35  * 修改时间:2017年6月4日 下午6:18:11
36
37  * 修改备注:
38
39  * @version
40
41  *
42
43  */
44
45
46
47 public class ServiceTask implements JavaDelegate{
48
49 //流程变量
50
51 private Expression text1;
52
53
54
55 //重写委托的提交方法
56
57 @Override
58
59 public void execute(DelegateExecution execution) throws Exception {
60
61 System.out.println("serviceTask已经执行已经执行!");
62
63 String value1 = (String) text1.getValue(execution);
64
65 System.out.println(value1);
66
67     execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
68
69 }
70
71
72
73 }

3)部署这个流程

4)设置规则

from("activiti:CamelProcess:MyCamelCall").to("direct:start-activiti");

from("direct:start-activiti").to("activiti:CamelStartprocess");

5)启动我们的Camel任务。可以看到结果

注:这里,我们启动的是Camel任务,但是Camel任务的路由规则又去启动一个Server任务。所以这里一共运行了两个流程实例。

Table 8.5. 已有的camel行为:

行为

URL

描述

CamelBehaviorDefaultImpl

copyVariablesToProperties

把Activiti变量复制为Camel属性

CamelBehaviorCamelBodyImpl

copyCamelBodyToBody

只把名为"camelBody"Activiti变量复制成camel的消息体

CamelBehaviorBodyAsMapImpl

copyVariablesToBodyAsMap

把activiti的所有变量复制到一个map里,作为Camel的消息体

上面的表格解释和activiti变量如何传递给camel。下面的表格解释和camel的变量如何返回给activiti。 它只能配置在规则URL中。

Table 8.6. 已有的camel行为:

Url

描述

默认

如果Camel消息体是一个map,把每个元素复制成activiti的变量,否则把整个camel消息体作为activiti的"camelBody"变量。

copyVariablesFromProperties

将Camel属性以相同名称复制为Activiti变量

copyCamelBodyToBodyAsString

和默认一样,但是如果camel消息体不是map时,先把它转换成字符串,再设置为"camelBody"。

copyVariablesFromHeader

额外把camel头部以相同名称复制成Activiti变量

 

 

上面两个表是关于流程变量的设置。那么我们在规则里面去实验这几个变量启用会有什么效果:

我们设置了两个变量,一个字符串变量input和一个集合变量OutPutMap

Map<String, Object> variables = new HashMap<String, Object>();

variables.put("input", "Hello");

Map<String, String> outputMap = new HashMap<String, String>();

variables.put("outputMap", outputMap);

from("activiti:CamelProcess:MyCamelCall").transform().simple("${property.input} ,jesai");

Camel变量传递给Activiti

1)copyCamelBodyToBody

from("activiti:CamelProcess:MyCamelCall?copyCamelBodyToBody=true").transform().simple("${property.input} ,jesai");

可以看到camelBody只把名为"camelBody"Activiti变量复制成camel的消息体

2)copyVariablesToProperties

from("activiti:CamelProcess:MyCamelCall?copyVariablesToProperties=true").transform().simple("${property.input} ,jesai");

这里,已经把Activiti变量Input的Hello复制作为camelBody的消息

把Activiti变量复制为Camel属性

3)copyVariablesToBodyAsMap

from("activiti:CamelProcess:MyCamelCall?copyVariablesToBodyAsMap=true").transform().simple("${property.input} ,jesai");

变量放到OutPutMap里面去了。

Activiti变量传递给Camel

1)默认

如果Camel消息体是一个map,把每个元素复制成activiti的变量,否则把整个camel消息体作为activiti的"camelBody"变量。

2)copyVariablesFromProperties

from("activiti:CamelProcess:MyCamelCall?copyVariablesFromProperties=true").transform().simple("${property.input} ,jesai");

将Camel属性以相同名称复制为Activiti变量

3)copyCamelBodyToBodyAsString

from("activiti:CamelProcess:MyCamelCall?copyCamelBodyToBodyAsString=true").transform().simple("${property.input} ,jesai");

和默认一样,但是如果camel消息体不是map时,先把它转换成字符串,再设置为"camelBody"。

4)copyVariablesFromHeader

from("activiti:CamelProcess:MyCamelCall?copyVariablesFromHeader=true").transform().simple("${property.input} ,jesai");

额外把camel头部以相同名称复制成Activiti变量

注:路由规则是在启动部署系统的时候就已经初始化好了的。不支持热更改。而且系统一单部署完成,运行流程实例的时候,不会执行路由配置。

实验:我们在路由的配置类里面打印一个控制台:

启动系统就会看到:

你会发现,它是在系统启动的时候执行的。并不是在流程执行的时候。

 

 Activiti交流QQ群:634320089

转载于:https://www.cnblogs.com/dengjiahai/p/7078120.html

Activiti CamelTask(骆驼任务)相关推荐

  1. 14、flowable、camunda(卡蒙达) 等开源工作流引擎选择

    市场上比较有名的开源流程引擎有osworkflow.jbpm.activiti.flowable.camunda.其中:Jbpm4.Activiti.Flowable.camunda四个框架同宗同源, ...

  2. Activiti 自定义流程图颜色

    Activiti 自定义流程图颜色 流程图执行的为绿色,待执行为红色. 绘制流程图 package org.jeecg.common.config;/*** activiti6流程图绘制** @aut ...

  3. activiti 6.0 editor汉化详解

    添加汉化文件到如下: 源代码: 汉化文件 stencilset_bpmn.json {"title" : "BPMN 2.0标准工具","namesp ...

  4. springboot集成activiti汉化

    activiti的modeler汉化. 汉化步骤: 将en.json(路径:editor-app/i18n/en.json)文件汉化,改名zh-CN.json,放在en.json同目录. 同时将汉化后 ...

  5. Activiti——流程执行历史记录(七)

    转自:http://blog.csdn.net/zjx86320/article/details/50363544 之前的几篇文章,为大家简单的介绍了部署流程定义.启动流程实例.查看和办理个人任务以及 ...

  6. Activiti——流程变量(六)

    Activiti--流程变量 转自:http://lib.csdn.net/article/java/66665?knId=268 流程变量在整个工作流中扮演很重要的作用.例如:请假流程中有请假天数. ...

  7. Activiti——工作流之流程实例、任务的执行(五)

    转自:http://profound-accumulation.iteye.com/blog/2244881 一.流程图   二.部署流程定义 /**部署请假流程(从zip)*/ @Test publ ...

  8. Activiti——数据表结构

    备注: 本文转自:http://blog.csdn.net/hj7jay/article/details/51302829 转载目的在于个人学习使用,如有涉及著作权相关问题,请联系本人,本人将第一时间 ...

  9. Activiti——管理流程定义(四)

    Activiti--管理流程定义 1.设计流程定义文档 1.1.流程图 1.2.bpmn文件 <?xml version="1.0" encoding="UTF-8 ...

  10. Activiti——工作流程-核心API(二)

    .1 ProcessEngine 说明: 1) 在Activiti中最核心的类,其他的类都是由他而来. 2) 产生方式: 在前面看到了两种创建ProcessEngine(流程引擎)的方式(http:/ ...

最新文章

  1. 递归查询树状结构某个确定的节点
  2. 深入理解 Event Loop
  3. jboss 反序列化 getshell
  4. 智能骨传导眼镜vue_穿戴设备迎新机遇,智能音频眼镜或将是下一个风口
  5. 解决在使用 Qt 编译项目时出现 “C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode格式以防止数据丢失“ 的警告
  6. 如何做好一个开源项目之徽章(二)
  7. 数万字的0基础React知识大纲一定要藏藏好
  8. Hadoop系列-分布式集群
  9. HIbernate抽象出通用方法
  10. 聚类法 人脸识别 matlab,声纹识别 快速概览 + 详细了解N:N聚类算法是如何应用的...
  11. DS18B20 数字温度传感器实验
  12. 加减乘除等符号大全中英对照,在英语中的用法
  13. 咨询博客园文章如何维权
  14. AArch64架构内存布局及线性地址转换
  15. msfvenom生成木马的简单利用
  16. Zabbix Trapper items
  17. 混合波束成形|基础:深入浅出5G,毫米波,大规模MIMO与波束赋形
  18. always@(*)和assign的区别
  19. android电视盒子软件安装,安卓电视怎么安装软件 智能电视软件安装方法教程
  20. SQL Server 2008存储结构----不胜人生一场醉

热门文章

  1. Git--分布式版本控制系统
  2. 谈软件开发项目管理之需求变更
  3. zabbix 代理报错
  4. DIV+CSS样式表命名的规则方法
  5. 波形分析--串口数据
  6. js中获取时间new date()的用法和获取时间戳
  7. Oracle之外键(Foreign Key)使用方法具体解释(二)- 级联删除(DELETE CASCADE)
  8. RedHat Linux设置yum软件源为本地ISO
  9. 《ES6标准入门》学习笔记
  10. 林语堂:读书须有胆识,有眼光,有毅力