第 2 章 Route 构建的基本原则
摘要
Apache Camel 提供了几个处理器和组件,您可以在路由中连接在一起。本章介绍了使用提供的构建块构建路由原则的基础。
2.1. Pipeline 处理
概述
在 Apache Camel 中,pipelining 是路由定义中连接节点的主要范式。管道概念可能对 UNIX 操作系统的用户最熟悉,其中用于加入操作系统命令。例如,
是一个命令示例,它将目录列表传送到 page-scrolling 实用程序,ls
| 更多更多
。管道的基本概念是,一个命令的输出 将进入下一个 输入 中。如果路由的情况是,从一个处理器的 Out 消息被复制到下一处理器的 In 消息,则类似情况。
处理器节点
路由中的每个节点(除初始端点外)都是一个 处理器,它的确是从 org.apache.camel.Processor
接口继承的意义。换句话说,处理器构成 DSL 路由的基本构建块。例如: DSL 命令,如 filter
()、delayer()、
setBody()、
setHeader()
和 to()
所有代表的处理器。当考虑到处理器如何连接路由时,务必要区分两种不同的处理方法。
第一种方法是,处理器只需要修改交换的消息,如 图 2.1 “处理器修改信息” 所示。在这种情况下,交换的 Out 消息仍保持 null
。
图 2.1. 处理器修改信息
以下路由显示了一个 setHeader()
命令,它通过添加(或修改) BillingSystem
标题来修改当前的 In 消息:
from("activemq:orderQueue") .setHeader("BillingSystem", xpath("/order/billingSystem")) .to("activemq:billingQueue");
第二种方法是,处理器创建 Out 信息来表示处理的结果,如 图 2.2 “处理器创建 Out 消息” 所示。
图 2.2. 处理器创建 Out 消息
以下路由显示了一个 transform()
命令,该命令会 创建一个带有包含字符串 DummyBody
的消息正文:
from("activemq:orderQueue") .transform(constant("DummyBody")) .to("activemq:billingQueue");
其中 常量("DummyBody")
代表一个恒定表达式。您不能直接传递字符串 DummyBody
,因为对 transform()
的参数必须是表达式类型。
用于 InOnly 交换的管道
图 2.3 “InOnly Exchanges 的 Pipeline 示例” 显示用于 InOnly 交换的处理器管道示例。处理器 A 通过修改 In 消息,而处理器 B 和 C 创建 Out 消息。路由构建器按照所示将处理器链接在一起。特别是,B 和 C 以 管道 的形式链接在一起:也就是说,处理器 B 的 Out 消息移到 In 消息,在向处理器 C 传输交换前,处理器 C 的 Out 消息移到 In 消息,然后再将处理器 C 的 Out 消息移到 In 消息中。因此,处理器的输出和输入被加入到持续管道中,如 图 2.3 “InOnly Exchanges 的 Pipeline 示例” 所示。
图 2.3. InOnly Exchanges 的 Pipeline 示例
Apache Camel 默认使用管道模式,因此您无需使用任何特殊语法在路由中创建管道。例如,以下路由从 userdataQueue
队列拉取消息,通过 Velocity 模板管道消息(以便以文本格式生成客户地址),然后将生成的文本地址发送到队列,envelopeAddresses
:
from("activemq:userdataQueue") .to(ExchangePattern.InOut, "velocity:file:AdressTemplate.vm") .to("activemq:envelopeAddresses");
在文件系统中,Velocit y:file:AddressTemplate.vm
指定 Velocity 模板文件的位置,file:AddressTemplate.vm
。to()
命令在将交换模式发送到 Velocity 端点之前,将交换模式更改为 InOut,然后将它改回到 InOnly 后。有关速率端点的详情,请参阅 Apache Camel 组件参考指南 中的 Velocity。
InOut 交换的管道
图 2.4 “InOut Exchanges 的 Pipeline 示例” 演示了 InOut 交换的处理器管道示例,您通常会用来支持远程过程调用(RPC)语义。处理器 A、B 和 C 以管道的形式链接,以及每个处理器的输出进入下一版本的输入。制作者端点生成的最终 Out 消息将将所有方式发送到消费者端点,在其中提供原始请求的回复。
图 2.4. InOut Exchanges 的 Pipeline 示例
请注意,为了支持 InOut 交换模式,重要的是,路由中最后一个节点(无论是制作者端点还是其他类型的处理器)会创建一个 Out 消息。否则,连接到消费者端点的任何客户端都会挂起并无限期等待回复消息。您应该注意,并非所有制作者端点都会创建 Out 消息。
通过处理传入的 HTTP 请求来考虑以下处理支付请求的路由:
from("jetty:http://localhost:8080/foo") .to("cxf:bean:addAccountDetails") .to("cxf:bean:getCreditRating") .to("cxf:bean:processTransaction");
如果传入的支付请求通过通过 Web 服务管道、cxf:bean:addAccountDetails
、cxf:bean:bean:getCreditRating
、cxf:bean:processTransaction
来处理。最后的 Web 服务 processTransaction
生成通过 JETTTY 端点发回的响应(Out 消息)。
当管道只由一系列端点组成时,也可以使用以下替代语法:
from("jetty:http://localhost:8080/foo") .pipeline("cxf:bean:addAccountDetails", "cxf:bean:getCreditRating", "cxf:bean:processTransaction");
In OptionalOut Exchanges 的管道
In OptionalOut Exchanges 的管道基本上与 图 2.4 “InOut Exchanges 的 Pipeline 示例” 中的管道相同。In Out 和 InoptionalOut 之间的区别在于,可以使用" 可选Out 交换"模式交换作为答复。也就是说,如果是 In OptionalOut 交换,则会将 null
Out 消息复制到管道中下一节点的 In 消息。相反,如果是 In Out 交换,则会丢弃 null
Out 消息,并且当前节点中的原始 In 消息将被复制到下一节点的 In 消息中。