Wire Tap
Wire Tap (from the EIP patterns) allows you to route messages to a separate location while they are being forwarded to the ultimate destination.
| Streams If you Wire Tap a stream message body then you should consider enabling Stream caching to ensure the message body can be read at each endpoint. See more details at Stream caching. |
Options
Name |
Default Value |
Description |
uri |
|
The URI of the endpoint to which the wire-tapped message will be sent. You should use either uri or ref. |
ref |
|
Reference identifier of the endpoint to which the wire-tapped message will be sent. You should use either uri or ref. |
executorServiceRef |
|
Reference identifier of a custom Thread Pool to use when processing the wire-tapped messages. If not set, Camel will use a default thread pool. |
processorRef |
|
Reference identifier of a custom Processor to use for creating a new message (e.g., the "send a new message" mode). See below. |
copy |
true |
Camel 2.3: Whether to copy the Exchange before wire-tapping the message. |
onPrepareRef |
|
Camel 2.8: Reference identifier of a custom Processor to prepare the copy of the Exchange to be wire-tapped. This allows you to do any custom logic, such as deep-cloning the message payload. |
WireTap thread pool
The Wire Tap uses a thread pool to process the tapped messages. This thread pool will by default use the settings detailed at Threading Model. In particular, when the pool is exhausted (with all threads utilized), further wiretaps will be executed synchronously by the calling thread. To remedy this, you can configure an explicit thread pool on the Wire Tap having either a different rejection policy, a larger worker queue, or more worker threads.
WireTap node
You can also use a wireTap node to facilitate wiretaps. Camel will copy the original Exchange and set its Exchange Pattern to InOnly, as we want the tapped Exchange to be sent in a fire and forget style. The tapped Exchange is then sent in a separate thread so it can run in parallel with the original.
We have extended wireTap to support two flavors when tapping an Exchange:
- send a copy of the original Exchange (the traditional wiretap)
- send a new Exchange, allowing you to populate it beforehand
Sending a copy (traditional wiretap)
Using the Fluent Builders
from("direct:start")
.to("log:foo")
.wireTap("direct:tap")
.to("mock:result");
Using the Spring XML Extensions
<route>
<from uri="direct:start"/>
<to uri="log:foo"/>
<wireTap uri="direct:tap"/>
<to uri="mock:result"/>
</route>
Using the Fluent Builders
Camel supports either a processor or an _expression_ to populate the new Exchange. Using a processor gives you full power over how the Exchange is populated as you can set properties, headers, et cetera. An _expression_ can only be used to set the IN body.
From Camel 2.3 onwards the _expression_ or Processor is pre-populated with a copy of the original Exchange, which allows you to access the original message when you prepare a new Exchange to be sent. You can use the copy option (enabled by default) to indicate whether you want this. If you set copy=false, then it works as in Camel 2.2 or older where the Exchange will be empty.
Below is the processor variation. This example is from Camel 2.3, where we disable copy by passing in false to create a new, empty Exchange.
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");
Here is the _expression_ variation. This example is from Camel 2.3, where we disable copy by passing in false to create a new, empty Exchange.
from("direct:start")
.wireTap("direct:foo", false, constant("Bye World"))
.to("mock:result");
from("direct:foo").to("mock:foo");
Using the Spring XML Extensions
The processor variation, which uses a processorRef attribute to refer to a Spring bean by ID:
<route>
<from uri="direct:start2"/>
<wireTap uri="direct:foo" processorRef="myProcessor"/>
<to uri="mock:result"/>
</route>
Here is the _expression_ variation, where the _expression_ is defined in the body tag:
<route>
<from uri="direct:start"/>
<wireTap uri="direct:foo">
<body><constant>Bye World</constant></body>
</wireTap>
<to uri="mock:result"/>
</route>
This variation accesses the body of the original message and creates a new Exchange based on the _expression_. It will create a new Exchange and have the body contain "Bye ORIGINAL BODY MESSAGE HERE"
<route>
<from uri="direct:start"/>
<wireTap uri="direct:foo">
<body><simple>Bye ${body}</simple></body>
</wireTap>
<to uri="mock:result"/>
</route>
Further Example
For another example of this pattern, refer to the wire tap test case.
Sending a new Exchange and set headers in DSL
Available as of Camel 2.8
If you send a new message using Wire Tap, then you could only set the message body using an _expression_ from the DSL. If you also need to set headers, you would have to use a Processor. In Camel 2.8 onwards, you can now set headers as well in the DSL.
The following example sends a new message which has
- "Bye World" as message body
- a header with key "id" with the value 123
- a header with key "date" which has current date as value
Java DSL
from("direct:start")
.wireTap("direct:tap")
.newExchangeBody(constant("Bye World"))
.newExchangeHeader("id", constant(123))
.newExchangeHeader("date", simple("${date:now:yyyyMMdd}"))
.end()
.to("mock:result");
from("direct:tap")
.to("mock:tap");
XML DSL
The XML DSL is slightly different than Java DSL in how you configure the message body and headers using <body> and <setHeader>:
<route>
<from uri="direct:start"/>
<wireTap uri="direct:tap">
<body><constant>Bye World</constant></body>
<setHeader headerName="id"><constant>123</constant></setHeader>
<setHeader headerName="date"><simple>${date:now:yyyyMMdd}</simple></setHeader>
</wireTap>
<to uri="mock:result"/>
</route>
Using onPrepare to execute custom logic when preparing messages
Available as of Camel 2.8
See details at Multicast
Using This Pattern
If you would like to use this EIP Pattern then please read the Getting Started, you may also find the Architecture useful particularly the description of Endpoint and URIs. Then you could try out some of the Examples first before trying this pattern out.