12.3. wire Tap


wire Tap

wire tap 模式(如 图 12.1 “wire Tap Pattern” 所示)可让您将消息的副本路由到单独的 tap 位置,而原始消息会转发到最终目的地。

图 12.1. wire Tap Pattern

wire tap

如果您的流消息正文,您应该考虑启用 流缓存,以确保消息正文可以被重新读取。参阅流缓存的详情,请参阅 流缓存

Wiretap 节点

Apache Camel 2.0 引进了 wireTap 节点,用于进行线路 TAP。wireTap 节点将原始交换复制到被利用的交换中,后者的交换模式被设置为 InOnly,因为被利用的交换应以 单方式 传播。已利用的交换在单独的线程中处理,以便它可以与主路由同时运行。

wireTap 支持两种不同的方法来利用交换:

  • TAP 原始交换的副本。
  • TAP 新交换实例,允许您自定义被利用的交换。
注意

从 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 message body。

例如,使用 处理器 方法修改原始交换的副本:

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 创建了一个空的交换。

例如,使用 processor 方法创建新交换实例:

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 和 set 标头

可从 Camel 2.8 开始

如果您使用 第 12.3 节 “wire Tap” 发送新信息,则只能使用 DSL 中的 第 II 部分 “路由表达式和专用语言” 设置消息正文。如果您需要设置新的标头,则必须为此使用 第 1.5 节 “处理器”。因此,在 Camel 2.8 起,我们提高了这种情况,因此您现在可以在 DSL 中设置标头。

以下示例发送一条新消息,其具有

  • "通过世界"作为邮件正文
  • 带有键 "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

wire Tap 支持静态和动态端点 URI。静态端点 URI 可从 Camel 2.20 开始。

以下示例演示了如何将 tap 连接至 JMS 队列,其中标头 ID 是队列名称的一部分。

from("direct:start")
   .wireTap("jms:queue:backup-${header.id}")
   .to("bean:doSomething");

有关动态端点 URI 的更多信息,请参阅 “动态到”一节

使用 onPrepare 在准备消息时执行自定义逻辑

可从 Camel 2.8 开始

详情请查看 第 8.13 节 “多播”

选项

wireTap DSL 命令支持以下选项:

Name

默认值

描述

uri

 

发送 wire tapped 消息的 endpoint uri。您应该使用 uriref

ref

 

指的是发送有线 tapped 消息的端点。您应该使用 uriref

executorServiceRef

 

指的是处理有线设备的消息时要使用的自定义 第 2.8 节 “线程模型”。如果没有设置,Camel 将使用默认线程池。

processorRef

 

指的是用于创建新消息的自定义 第 1.5 节 “处理器”(例如,发送新消息模式)。请参见下文。

复制

true

Camel 2.3 :是否应该将 “Exchanges”一节 副本用于处理消息。

onPrepareRef

 

Camel 2.8: 请参阅自定义 第 1.5 节 “处理器”,以准备连接 “Exchanges”一节 的副本。这可让您执行任何自定义逻辑,如深度克隆消息有效负载(如果需要)。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.