Intercept
The intercept feature in Camel supports intercepting Exchanges while they are on route.
Camel supports three kinds of interceptors:
-
intercept
that intercepts each and every processing step while routing an Exchange in the route. -
interceptFrom
that intercepts incoming Exchange in the route. -
interceptSendToEndpoint
that intercepts when an Exchange is about to be sent to the given Endpoint.
These interceptors supports the following features:
-
Predicate using
when
to only trigger the interceptor in certain conditions -
stop
forces to stop continue routing the Exchange and mark it as completed successful. Camel will by default not stop. -
skip
when used withinterceptSendToEndpoint
will skip sending the Exchange to the original intended endpoint. Camel will by default not skip. -
afterUrl
when using withinterceptSendToEndpoint
allows to send the Exchange to an endpoint url after the detour and sending to the original endpoint. -
interceptFrom
andinterceptSendToEndpoint
supports endpoint URI matching by: exact uri, wildcard, regular expression. See advanced section. -
The intercepted endpoint uri is stored as message header
Exchange.INTERCEPTED_ENDPOINT
.
stop
can be used in general, it does not have to be used with an
Intercept you can use it in regular routing as
well.
You can also instruct Camel to stop
continue routing your message if
you set the Exchange.ROUTE_STOP
property to "true"
or Boolean.TRUE
on the Exchange. You can for instance do this from
regular Java code in a POJO or
Processor.
Intercept
Intercept
is like a regular interceptor that is applied on each
processing step the Exchange undergo while its being
routed. You can think of it as a AOP before that is applied at each
DSL keyword you have defined in your route.
The classic Hello World example would be:
intercept().to("log:hello");
from("jms:queue:order").to("bean:validateOrder").to("bean:processOrder");
What happens is that the Exchange is intercepted before each processing step, that means that it will be intercepted before
-
.to("bean:validateOrder")
-
.to("bean:processOrder")
So in this sample we intercept the Exchange twice.
The when
predicate is also support on the intercept
so we can attach
a Predicate to only trigger the interception under
certain conditions.
For instance in the sample below we only intercept if the message body
contains the string word Hello:
And in the route below we want to stop in certain conditions, when the message contains the word 'Hello':
Using from Spring DSL
The same hello world sample in Spring DSL would be:
<camelContext ...>
<intercept>
<to uri="log:hello"/>
</intercept>
<route>
<from uri="jms:queue:order"/>
<to uri="bean:validateOrder"/>
<to uri="bean:handleOrder"/>
</route>
</camelContext>
And the sample for using the when predicate would be:
And the sample for using the when and stop would be:
InterceptFrom
InterceptFrom
is for intercepting any incoming
Exchange, in any route (it intercepts all the from
DSLs). This allows you to do some custom behavior for received
Exchanges. You can provide a specific uri for a
given Endpoint then it only applies for that
particular route.
So lets start with the logging example. We want to log all the
incoming requests so we use interceptFrom
to route to the
Log component. As proceed
is default then the
Exchange will continue its route, and thus it will
continue to mock:first
.
You can also attach a Predicate to only trigger if certain conditions is meet. For instance in the route below we intercept when a test message is send to us, so we can do some custom processing before we continue routing:
And if we want to filter out certain messages we can use the stop()
to
instruct Camel to stop continue routing the
Exchange:
And if want to only apply a specific endpoint, as the seda:bar endpoint in the sample below, we can do it like this:
InterceptSendToEndpoint
Intercept send to endpoint is triggered when an
Exchange is being sent to the intercepted endpoint.
This allows you to route the Exchange to a
detour or do some custom processing before the
Exchange is sent to the original intended
destination. You can also skip sending to the intended destination. By
default Camel will send to the original intended destination after the
intercepted route completes. And as the regular intercept you can also
define an when
Predicate so we only intercept if
the Predicate evaluates to true. This allows you
do do a bit of filtering, to only intercept when certain criteria is
meet. And finally you can send the Exchange to an endpoint with the afterUrl
option. You can use this to process the response from the original endpoint.
Let start with a simple example, where we want to intercept when an
Exchange is being sent to mock:foo
:
And this time we add the Predicate so its only when
the message body is Hello World
we intercept.
And to skip sending to the mock:foo
endpoint we use the *skip()
DSL
in the route at the end to instruct Camel to skip sending to the
original intended endpoint.
Conditional skipping
The combination of skipSendToEndpoint
with a when
predicate only occurs if the when
predicate is matched, leading to more natural logic altogether.
interceptSendToEndpoint("mock:foo").skipSendToOriginalEndpoint()
.when(simple("${body} == 'Hello World'")
.to("log:intercepted");
Using from Spring DSL
Intercept endpoint is of course also available using Spring DSL.
We start with the first example from above in Spring DSL:
And the 2nd. Notice how we can leverage the Simple language for the Predicate:
And the 3rd with the skip
, notice skip is set with the
skipSendToOriginalEndpoint
attribute on the interceptSendToEndpoint
tag:
<camelContext ...>
<interceptSendToEndpoint uri="mock:foo" skipSendToOriginalEndpoint="true">
<when><simple>${body} == 'Hello World'</simple></when>
<to uri="log:intercepted"/>
</intercept>
<route>
<from uri="jms:queue:order"/>
<to uri="bean:validateOrder"/>
<to uri="bean:handleOrder"/>
</route>
</camelContext>
[[Intercept-InterceptSendToEndpoint with afterUrl]] == InterceptSendToEndpoint with afterUrl
The interceptor allows to call an endpoint after the intercepted message has been sent to the original endpoint, which allows you to process the response from the original endpoint. For example to log the request/response from sending to all JMS endpoints you can do:
interceptSendToEndpoint("jms*").afterUrl("log:jms-reply")
.to("log:jms-request");
And in XML DSL:
<camelContext ...>
<interceptSendToEndpoint uri="jms*" afterUrl="log:jms-reply">
<to uri="log:jms-request"/>
</intercept>
</camelContext>
Advanced usage of Intercpt
The interceptFrom
and interceptSendToEndpoint
supports endpoint URI
matching by the following rules in the given order:
-
match by exact URI name. This is the sample we have seen above.
-
match by wildcard
-
match by regular expression.
The real endpoint that was intercepted is stored as uri in the message
IN header with the key Exchange.INTERCEPTED_ENDPOINT
.
This allows you to get hold of this information, when you for instance
match by wildcard. Then you know the real endpoint that was intercepted
and can react accordingly.
Match by wildcard
Match by wildcard allows you to match a range of endpoint or all of a
given type. For instance use uri="file:*"
will match all
File based endpoints.
intercept("jms:*").to("log:fromjms");
Wildcards is match that the text before the * is matched against the given endpoint and if it also starts with the same characters its a match. For instance you can do:
intercept("file://order/inbox/*").to("log:newfileorders");
To intercept any files received from the order/inbox
folder.
Match by regular expression
Match by regular expression is just like match by wildcard but using regex instead. So if we want to intercept incoming messages from gold and silver JMS queues we can do:
intercept("jms:queue:(gold|silver)").to("seda:handleFast");
About dynamic and static behavior of interceptFrom and interceptSendToEndpoint
The interceptSendToEndpoint
is dynamic hence it will also trigger if a
dynamic URI is constructed that Camel was not aware of at startup
time.
The interceptFrom
is not dynamic as it only intercepts input to
routes registered as routes in CamelContext
. So if you dynamic
construct a Consumer
using the Camel API and consumes an
Endpoint then the interceptFrom
is not triggered.