第 2 章 Route 构建的基本原则

摘要

Apache Camel 提供了几个处理器和组件,您可以在路由中连接在一起。本章介绍了使用提供的构建块构建路由原则的基础。

2.1. Pipeline 处理

概述

在 Apache Camel 中,pipelining 是路由定义中连接节点的主要范式。管道概念可能对 UNIX 操作系统的用户最熟悉,其中用于加入操作系统命令。例如, ls | 更多 是一个命令示例,它将目录列表传送到 page-scrolling 实用程序,更多。管道的基本概念是,一个命令的输出 将进入下一个 输入 中。如果路由的情况是,从一个处理器的 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 示例

InOnly 交换的管道示例

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.vmto() 命令在将交换模式发送到 Velocity 端点之前,将交换模式更改为 InOut,然后将它改回到 InOnly 后。有关速率端点的详情,请参阅 Apache Camel 组件参考指南 中的 Velocity

InOut 交换的管道

图 2.4 “InOut Exchanges 的 Pipeline 示例” 演示了 InOut 交换的处理器管道示例,您通常会用来支持远程过程调用(RPC)语义。处理器 A、B 和 C 以管道的形式链接,以及每个处理器的输出进入下一版本的输入。制作者端点生成的最终 Out 消息将将所有方式发送到消费者端点,在其中提供原始请求的回复。

图 2.4. InOut Exchanges 的 Pipeline 示例

InOut 交换的管道示例

请注意,为了支持 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:addAccountDetailscxf:bean:bean:getCreditRatingcxf: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 交换,则会将 nullOut 消息复制到管道中下一节点的 In 消息。相反,如果是 In Out 交换,则会丢弃 nullOut 消息,并且当前节点中的原始 In 消息将被复制到下一节点的 In 消息中。