12.3. wire Tap
wire Tap
与 图 12.1 “wire Tap Pattern” 所示,有线 tap 模式允许您将消息的副本路由到单独的 tap 位置,而原始消息转发到最终目的地。
图 12.1. wire Tap Pattern
Wiretap 节点
Apache Camel 2.0 引入了用于线 taps 的 wireTap
节点。wireTap
节点将原始交换复制到 tap 的交换中,其交换模式被设置为 InOnly,因为被交换交换应该以 一种方式 传播。交换会在单独的线程中处理,以便它可以与主路由同时运行。
wireTap
支持两种不同的方法来利用交换:
- 排除原始交换的副本。
- 使用一个新的交换实例,您可以自定义被利用的交换。
从 Camel 2.16,Wire Tap EIP 会在将交换发送到线 tap 目的地时发出事件通知。
自 Camel 2.20 起,Wire Tap EIP 在关闭时将完成任意有线流交换。
TAP 原始交换的副本
使用 Java DSL:
from("direct:start") .to("log:foo") .wireTap("direct:tap") .to("mock:result");
使用 Spring XML 扩展:
<route> <from uri="direct:start"/> <to uri="log:foo"/> <wireTap uri="direct:tap"/> <to uri="mock:result"/> </route>
TAP 和修改原始交换的副本
使用 Java DSL 时,Apache Camel 支持使用处理器或表达式来修改原始交换的副本。使用处理器可以让您完全了解交换的填充方式,因为您可以设置属性、标头等等。表达式方法只能用于修改 In 消息正文。
例如,使用 处理器 方法修改原始交换的副本:
from("direct:start") .wireTap("direct:foo", new Processor() { public void process(Exchange exchange) throws Exception { exchange.getIn().setHeader("foo", "bar"); } }).to("mock:result"); from("direct:foo").to("mock:foo");
使用 表达式 方法修改原始交换的副本:
from("direct:start") .wireTap("direct:foo", constant("Bye World")) .to("mock:result"); from("direct:foo").to("mock:foo");
使用 Spring XML 扩展,您可以使用 处理器 方法修改原始交换的副本,其中 processorRef
属性引用带有 myProcessor
ID 的 spring bean:
<route> <from uri="direct:start2"/> <wireTap uri="direct:foo" processorRef="myProcessor"/> <to uri="mock:result"/> </route>
使用 表达式 方法修改原始交换的副本:
<route> <from uri="direct:start"/> <wireTap uri="direct:foo"> <body><constant>Bye World</constant></body> </wireTap> <to uri="mock:result"/> </route>
TAP 新交换实例
您可以通过将 copy 标记设置为 false
(默认为 true
),使用新的交换实例定义 wiretap。在本例中,会为 wiretap 创建一个初始空交换。
例如,使用 处理器 方法创建新交换实例:
from("direct:start") .wireTap("direct:foo", false, new Processor() { public void process(Exchange exchange) throws Exception { exchange.getIn().setBody("Bye World"); exchange.getIn().setHeader("foo", "bar"); } }).to("mock:result"); from("direct:foo").to("mock:foo");
如果第二个 wireTap
参数将 copy 标记设置为 false
,这表示 不会 复制原始交换,而是创建一个空交换。
使用 表达式 方法创建新交换实例:
from("direct:start") .wireTap("direct:foo", false, constant("Bye World")) .to("mock:result"); from("direct:foo").to("mock:foo");
使用 Spring XML 扩展,您可以通过将 wireTap
元素的 copy
属性设置为 false
来指示要创建新的交换。
要使用 处理器 方法创建新交换实例,其中 processorRef
属性引用带有 myProcessor
ID 的 spring bean,如下所示:
<route> <from uri="direct:start2"/> <wireTap uri="direct:foo" processorRef="myProcessor" copy="false"/> <to uri="mock:result"/> </route>
使用 表达式 方法创建新交换实例:
<route> <from uri="direct:start"/> <wireTap uri="direct:foo" copy="false"> <body><constant>Bye World</constant></body> </wireTap> <to uri="mock:result"/> </route>
在 DSL 中发送一个新的 Exchange 并设置标头
可作为 Camel 2.8 提供。
如果您使用 第 12.3 节 “wire Tap” 发送新信息,那么您只能使用 DSL 中的 第 II 部分 “路由表达式和指定语言” 来设置消息正文。如果您需要设置新标头,则必须将该标头使用 第 1.5 节 “处理器”。因此,在 Camel 2.8 中,我们提高了这种情况,因此您可以在 DSL 中设置标头和 DSL。
以下示例发送一个新信息,其中包含
- "通过 World"作为邮件正文
- 带有键 "id" 的标头,值为 123
- 带有键"date"的标题,其当前日期为值
Java DSL
from("direct:start") // tap a new message and send it to direct:tap // the new message should be Bye World with 2 headers .wireTap("direct:tap") // create the new tap message body and headers .newExchangeBody(constant("Bye World")) .newExchangeHeader("id", constant(123)) .newExchangeHeader("date", simple("${date:now:yyyyMMdd}")) .end() // here we continue routing the original messages .to("mock:result"); // this is the tapped route from("direct:tap") .to("mock:tap");
XML DSL
XML DSL 与 Java DSL 稍有不同,因为您如何配置消息正文和标头。在 XML 中,您可以使用 <body> 和 <setHeader>,如下所示:
<route> <from uri="direct:start"/> <!-- tap a new message and send it to direct:tap --> <!-- the new message should be Bye World with 2 headers --> <wireTap uri="direct:tap"> <!-- create the new tap message body and headers --> <body><constant>Bye World</constant></body> <setHeader headerName="id"><constant>123</constant></setHeader> <setHeader headerName="date"><simple>${date:now:yyyyMMdd}</simple></setHeader> </wireTap> <!-- here we continue routing the original message --> <to uri="mock:result"/> </route>
使用 URI
线 Tap 支持静态和动态端点 URI。静态端点 URI 可从 Camel 2.20 开始使用。
以下示例演示了如何将 tap 与标头 ID 是队列名称一部分的 JMS 队列连接。
from("direct:start") .wireTap("jms:queue:backup-${header.id}") .to("bean:doSomething");
有关动态端点 URI 的更多信息,请参阅 “动态到”一节。
在准备消息时使用 onPrepare 执行自定义逻辑
可作为 Camel 2.8 提供。
详情请查看 第 8.13 节 “多播”。
选项
wireTap
DSL 命令支持以下选项:
名称 | 默认值 | 描述 |
|
用于发送有线条消息的 endpoint uri。您应该使用 | |
|
代表发送有线消息的端点。您应该使用 | |
| 指的是处理线 tapped 消息时要使用的自定义 第 2.8 节 “线程模型”。如果没有设置,则 Camel 将使用默认线程池。 | |
| 请参考自定义 第 1.5 节 “处理器”以创建新消息(例如发送新消息模式)。请参见以下内容。 | |
|
| Camel 2.3: 应该是 “交换”一节 的一个副本,以便在有线利用消息时使用。 |
| Camel 2.8: 请参阅自定义 第 1.5 节 “处理器”,以准备将 “交换”一节 的副本进行线路。这可让您进行任何自定义逻辑,如 deep-cloning(如果需要)信息有效负载。 |