Flowable入门系列文章50 - 骆驼任务
Posted 分享牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flowable入门系列文章50 - 骆驼任务相关的知识,希望对你有一定的参考价值。
Camel任务允许您向Camel发送消息并从Camel接收消息,从而增强了Flowable的集成功能。请注意,骆驼任务不是 BPMN 2.0规范的官方任务(因此没有专门的图标)。因此,在可流动中,骆驼任务被实现为专用服务任务。另外请注意,您必须在项目中包含Flowable Camel模块以使用Camel任务功能。
1、定义一个骆驼任务
骆驼任务被实现为专用服务任务,并且通过设置所定义“骆驼”的类型的服务的任务。
<serviceTask id="sendCamel" flowable:type="camel">
流程定义本身只需要服务任务上的驼峰类型定义。整合逻辑全部委托给骆驼容器。默认情况下,Flowable引擎在Spring容器中查找camelContext bean。camelContext bean定义将由Camel容器加载的Camel路由。在下面的例子中,路由是从一个特定的Java包加载的,但是你也可以直接在Spring配置本身中定义路由。
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<packageScan>
<package>org.flowable.camel.route</package>
</packageScan>
</camelContext>
有关骆驼路线的更多文档,您可以在骆驼网站上查找。基本概念通过以下几个小样本来演示。在第一个示例中,我们将从Flowable工作流程中执行Camel调用的最简单形式。我们称之为SimpleCamelCall。
如果你想要定义多个Camel上下文bean,或者想要使用不同的bean名称,可以在Camel任务定义中重写,如下所示:
<serviceTask id="serviceTask1" flowable:type="camel">
<extensionElements>
<flowable:field name="camelContext" stringValue="customCamelContext" />
</extensionElements>
</serviceTask>
2、简单的骆驼呼叫示例
所有与这个例子相关的文件都可以在流程模块的org.flowable.camel.examples.simpleCamelCall包中找到。目标只是激活一个特定的骆驼路线。首先,我们需要一个包含前面介绍的路由的Spring上下文。以下是这个目的:
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<packageScan>
<package>org.flowable.camel.examples.simpleCamelCall</package>
</packageScan>
</camelContext>
public class SimpleCamelCallRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("flowable:SimpleCamelCallProcess:simpleCall").to("log:org.flowable.camel.examples.SimpleCamelCall");
}
}
该路由只是记录消息体,没有更多。注意来自端点的格式。它由三部分组成:
端点URL部分 | 描述 |
---|---|
流动性 | 指的是引擎端点 |
SimpleCamelCallProcess 进程的名称 | |
simpleCall | 过程中骆驼服务的名称 |
好的,我们的路线现在已经正确配置,骆驼可以访问。现在是工作流程的一部分。工作流程如下所示:
<process id="SimpleCamelCallProcess">
<startEvent id="start"/>
<sequenceFlow id="flow1" sourceRef="start" targetRef="simpleCall"/>
<serviceTask id="simpleCall" flowable:type="camel"/>
<sequenceFlow id="flow2" sourceRef="simpleCall" targetRef="end"/>
<endEvent id="end"/>
</process>
3、乒乓球的例子
我们的例子工作,但骆驼和流动之间没有真正的转移,所以没有太多的优点。在这个例子中,我们尝试向Camel发送数据和从Camel接收数据。我们发送一个字符串,Camel将它连接起来并返回结果。发件人部分是微不足道的,我们以变量的形式发送我们的消息给骆驼任务。这是我们的来电显示代码:
@Deployment
public void testPingPong() {
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("input", "Hello");
Map<String, String> outputMap = new HashMap<String, String>();
variables.put("outputMap", outputMap);
runtimeService.startProcessInstanceByKey("PingPongProcess", variables);
assertEquals(1, outputMap.size());
assertNotNull(outputMap.get("outputValue"));
assertEquals("Hello World", outputMap.get("outputValue"));
}
变量“input”实际上是Camel路径的输入,并且outputMap用于捕获来自Camel的结果。这个过程可能是这样的:
<process id="PingPongProcess">
<startEvent id="start"/>
<sequenceFlow id="flow1" sourceRef="start" targetRef="ping"/>
<serviceTask id="ping" flowable:type="camel"/>
<sequenceFlow id="flow2" sourceRef="ping" targetRef="saveOutput"/>
<serviceTask id="saveOutput" flowable:class="org.flowable.camel.examples.pingPong.SaveOutput" />
<sequenceFlow id="flow3" sourceRef="saveOutput" targetRef="end"/>
<endEvent id="end"/>
</process>
请注意,SaveOutput服务任务将“Output”变量的值从上下文存储到前面提到的OutputMap中。现在我们必须知道变量是如何发送给Camel的,然后返回。骆驼行为的概念发挥了作用。变量传递给骆驼的方式可以通过CamelBehavior进行配置。在这里我们使用我们的样本中的默认值,之后会有其他的简短描述。使用类似的代码,你可以配置所需的骆驼行为:
<serviceTask id="serviceTask1" flowable:type="camel">
<extensionElements>
<flowable:field name="camelBehaviorClass" stringValue="org.flowable.camel.impl.CamelBehaviorCamelBodyImpl" />
</extensionElements>
</serviceTask>
如果你没有给出具体的行为,那么org.flowable.camel.impl.CamelBehaviorDefaultImpl将被设置。此行为将变量复制到相同名称的骆驼属
性。作为回报,无论选择的行为如何,如果骆驼消息体是一个映射,那么它的每个元素都被复制为一个变量,否则整个对象被复制到一个名为“camelBody”的特定变量中。知道这一点,这骆驼路线结束我们的第二个例子:
public void configure() throws Exception {
from("flowable:PingPongProcess:ping").transform().simple("${property.input} World");
}
在这个路由中,字符串“world”连接到名为“input”的属性的末尾,结果将在消息体中设置。可以通过检查Java服务任务中的“camelBody”变量并复制到“outputMap”来访问它。现在让我们来看看其默认行为的例子,让我们看看其他的可能性。在启动每个Camel路由时,进程实例ID将被复制到具有“PROCESS_ID_PROPERTY”特定名称的Camel属性中。稍后用于关联流程实例和Camel路由。而且,它可以在骆驼路线中被利用。
Flowable中有三种不同的行为可用。行为可以被路由URL中的特定短语覆盖。以下是覆盖URL中已定义行为的示例:
from("flowable:asyncCamelProcess:serviceTaskAsync2?copyVariablesToProperties=true").
下表提供了三种可用的骆驼行为的概述:
行为 | 在URL中 | 描述 |
---|---|---|
CamelBehaviorDefaultImpl | copyVariablesToProperties | 复制可流动变量作为骆驼属性 |
CamelBehaviorCamelBodyImpl | copyCamelBodyToBody | 只复制名为“camelBody”的Flowable变量作为Camel消息主体 |
CamelBehaviorBodyAsMapImpl | copyVariablesToBodyAsMap | 将所有的Flowable变量作为Camel消息体复制到地图中 |
上表描述了可流动变量将如何传递给骆驼。下表描述了骆驼变量如何返回到Flowable。这只能在路由URL中进行配置。
网址 | 描述 |
---|---|
默认 | 如果骆驼体是一个映射,则将每个元素复制为一个Flowable变量,否则将整个骆驼体复制为一个“camelBody”流变量 |
copyVariablesFromProperties | 将Camel属性复制为同名的Flowable变量 |
copyCamelBodyToBodyAsString | 至于默认,但如果camelBody不是一张地图,首先将其转换为String,然后将其复制到“camelBody” |
copyVariablesFromHeader | 另外将Camel头文件复制到相同名称的Flowable变量 |
4、返回变量
上面提到的有关传递变量的内容只适用于变量传输的初始端,无论你是从骆驼来的流动还是从流动到骆驼。
需要注意的是,由于Flowable的特殊非阻塞行为,变量不会自动从Flowable返回到Camel。要做到这一点,可以使用特殊的语法。骆驼路由URL中可以有一个或多个参数,格式为var.return.someVariableName。所有名称等于这些参数之一(无var.return部分)的变量将被视为输出变量,并将作为具有相同名称的骆驼属性被复制。
例如,在如下路线中:
从( “直接:启动”)至( “流动性:工艺var.return.exampleVar?”)至( “模拟:结果”);
名称exampleVar为“流”的变量将被视为一个输出变量,并将作为名称相同的骆驼属性被复制回来。
5、异步Ping Pong示例
所有以前的例子都是同步的。流程实例一直等到骆驼路由结束并返回。在某些情况下,我们可能需要Flowable流程实例来继续。为了这样的目的,骆驼服务任务的异步能力是有用的。您可以通过将Camel服务任务的async属性设置为true 来使用此功能。
<serviceTask id="serviceAsyncPing" flowable:type="camel" flowable:async="true"/>
通过设置此功能,指定的骆驼路线由Flowable作业执行程序异步激活。在Camel路径中定义队列时,Flowable流程实例将继续在流程定义中的Camel服务任务之后定义的活动。骆驼路线将与流程执行完全异步执行。如果您想等待流程定义中某处的骆驼服务任务的响应,则可以使用接收任务。
<receiveTask id="receiveAsyncPing" name="Wait State" />
流程实例将等待,直到收到一个信号,例如从骆驼。在Camel中,您可以通过向适当的Flowable端点发送消息来向流程实例发送一个信号。
from("flowable:asyncPingProcess:serviceAsyncPing").to("flowable:asyncPingProcess:receiveAsyncPing");
- 常量字符串“流动”
- 进程名称
- 接收任务名称
6、从骆驼路线实例化工作流程
在前面的所有示例中,Flowable流程实例首先启动,Camel流程从流程实例启动。也可以通过其他方式来处理事务,从已经启动的骆驼路由中启动或调用流程实例。这与发送接收任务非常相似。这是一个示例路线:
from("direct:start").to("flowable:camelProcess");
正如您所看到的,URL有两个部分:第一个是常量字符串“flowable”,第二个是流程定义的名称。显然,流程定义应该已经部署到Flowable引擎。
也可以将流程实例的启动者设置为在Camel标头中提供的某个经过身份验证的用户标识。为此,首先必须在流程定义中指定一个启动器变量:
<startEvent id="start" flowable:initiator="initiator" />
然后,如果用户标识包含在一个名为CamelProcessInitiatorHeader的Camel标题中,骆驼路由可以定义如下:
from("direct:startWithInitiatorHeader")
.setHeader("CamelProcessInitiatorHeader", constant("kermit"))
.to("flowable:InitiatorCamelCallProcess?processInitiatorHeaderName=CamelProcessInitiatorHeader");
上面文章来自盘古BPM研究院:http://vue.pangubpm.com/
文章翻译提交:https://github.com/qiudaoke/flowable-userguide
了解更多文章可以关注微信公众号:
以上是关于Flowable入门系列文章50 - 骆驼任务的主要内容,如果未能解决你的问题,请参考以下文章