第 2 章 路由构建的基本原则
摘要
Apache Camel 提供了多个处理器和组件,您可以在路由中链接它们。本章通过解释使用提供的构建块构建路由的原则来提供基本情况。
2.1. Pipeline 处理
概述
在 Apache Camel 中,pipelining 是在路由定义中连接节点的主要范例。管道概念可能对 UNIX 操作系统的用户最熟悉,它用于加入操作系统命令。例如,
是一个将目录列表传送至 page-scrolling 工具( ls
| 更多更多
)的命令示例。管道的基本概念是,一个命令的输出 被放入下一个 输入 中。路由时的自然模拟是让从一个处理器的 Out 消息复制到下一个处理器的 In 消息。
处理器节点
路由中的每个节点(除初始端点)都是 处理器,即它们从 org.apache.camel.Processor
接口继承的意义。换句话说,处理器由 DSL 路由的基本构建块组成。例如,contextctl 命令(如 filter ()
、delayer ()
、setBody ()
、setHeader ()
和 to ()
)代表处理器。在考虑处理器如何连接以构建路由时,务必要区分两种不同的处理方法。
第一种方法是处理器只是修改交换的 In 消息的位置,如 图 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
的消息正文的 Out 消息:
from("activemq:orderQueue") .transform(constant("DummyBody")) .to("activemq:billingQueue");
其中 constant ("DummyBody")
代表一个常量表达式。您无法直接传递字符串 DummyBody
,因为参数 to transform ()
必须是表达式类型。
InOnly exchanges 的管道
图 2.3 “InOnly Exchanges 的 Pipeline 示例” 显示 InOnly exchanges 的处理器管道示例。处理器 A 通过修改 In 消息来运作,而处理器 B 和 C 创建 Out 消息。路由构建器将处理器链接在一起,如下所示。特别是,处理器 B 和 C 以 管道的形式链接在一起:也就是说,处理器 B 的 Out 消息会在将交换发送到处理器 C 之前移到 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");
其中 Velocity 端点 velocity:file:AddressTemplate.vm
,指定文件系统中ociy 模板文件的位置,file:AddressTemplate.vm
。to ()
命令将交换模式更改为 InOut,然后将交换发送到 Velocity 端点,然后在之后将其重新更改为 InOnly。有关 Velocity 端点的更多详细信息,请参阅 Apache Camel 组件参考指南 中的 Velocity。
InOut 交换的管道
图 2.4 “InOut Exchanges 的 Pipeline 示例” 显示 InOut 交换的处理器管道示例,通常用于支持远程过程调用(RPC)语义。处理器 A、B 和 C 以管道的形式链接在一起,每个处理器的输出被放入下一个输入中。producer 端点生成的最终 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:bean:addAccountDetails ,
, 和 cxf:
bean:bean:getCreditRatingcxf:bean:processTransaction
.最终的 Web 服务( 流程交易
)生成通过 JETTY 端点发回的响应(传出消息)。
当管道只由一系列端点组成时,也可以使用以下替代语法:
from("jetty:http://localhost:8080/foo") .pipeline("cxf:bean:addAccountDetails", "cxf:bean:getCreditRating", "cxf:bean:processTransaction");
InOptionalOut 交换的管道
InOptionalOut 交换的管道基本与 图 2.4 “InOut Exchanges 的 Pipeline 示例” 中的管道相同。InOut 和 InOptionalOut 之间的区别在于,允许 InOptionalOut 交换模式的交换具有 null Out 消息作为回复。也就是说,如果是 In OptionalOut 交换,则会将 null
Out 消息复制到管道中下一节点的 In 消息。相反,如果是 In Out 交换,则会丢弃 null
Out 消息,并且当前节点中的原始 In 消息将被复制到下一节点的 In 消息中。