This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit 7d440e8411771448e9fd1d7cb8db705029b90c8d Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Sep 23 15:49:43 2021 +0200 CAMEL-16861: Cleanup and update EIP docs --- .../main/docs/modules/eips/pages/intercept.adoc | 304 ++++++++++++++------- .../model/InterceptSendToEndpointDefinition.java | 12 + 2 files changed, 215 insertions(+), 101 deletions(-) diff --git a/core/camel-core-engine/src/main/docs/modules/eips/pages/intercept.adoc b/core/camel-core-engine/src/main/docs/modules/eips/pages/intercept.adoc index 1408637..0cf663b 100644 --- a/core/camel-core-engine/src/main/docs/modules/eips/pages/intercept.adoc +++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/intercept.adoc @@ -3,7 +3,7 @@ The intercept feature in Camel supports intercepting xref:latest@manual:ROOT:exchange.adoc[Exchange]'s' while they are being routed. -== Interceptor kinds +== Kinds of interceptors Camel supports three kinds of interceptors: @@ -12,6 +12,49 @@ Camel supports three kinds of interceptors: * `interceptSendToEndpoint` that intercepts only when an xref:latest@manual:ROOT:exchange.adoc[Exchange] is about to be sent to the given xref:message-endpoint.adoc[endpoint]. +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, and will only intercept +all the known routes when Camel is starting. +So if you construct a `Consumer` using the Camel Java API and consumes +messages from this endpoint, then the `interceptFrom` is not triggered. + +=== Interceptor scopes + +All the interceptors can be configured on global, route scope, or with +xref:latest@manual:ROOT:route-configuration.adoc[Route Configuration]. + +This means multiple interceptors can be _triggered_. + +Most of the examples in this page are on global scope. +To use route scope, then its similar but is done on the route. + +For example the first example further below can be done as shown on route scope: + +[source,java] +------------------------------------------------------------------------- +from("jms:queue:order") + .intercept().to("log:hello").end() // intercepts only in this route + .to("bean:validateOrder") + .to("bean:processOrder"); +------------------------------------------------------------------------- + +And in XML: + +[source,xml] +---- + <route> + <from uri="jms:queue:order"/> + <intercept> + <to uri="log:hello"/> + </intercept> + <to uri="bean:validateOrder"/> + <to uri="bean:processOrder"/> + </route> +---- + === Common features of the interceptors All these interceptors support the following features: @@ -19,7 +62,7 @@ All these interceptors support the following features: * xref:latest@manual:ROOT:predicate.adoc[Predicate] using `when` to only trigger the interceptor in certain conditions * `stop` forces stopping continue routing the Exchange and mark it as completed successful (it's actually the xref:stop-eip.adoc[Stop] EIP). * `skip` when used with `interceptSendToEndpoint` will *skip* sending the message to the original intended endpoint. -* `afterUrl` when used with `interceptSendToEndpoint` allows to send +* `afterUri` when used with `interceptSendToEndpoint` allows to send the message to an xref:message-endpoint.adoc[endpoint] afterwards. * `interceptFrom` and `interceptSendToEndpoint` supports endpoint URI pattern matching by: exact uri, wildcard, regular expression. See further below for more details. @@ -235,139 +278,211 @@ And in XML: </camelContext> ---- - == Using intercept when sending to an endpoint -TODO: Continue HERE!!!! +You can also intercept when Camel is sending a message to an xref:message-endpoint.adoc[endpoint]. +This can be used to do some custom processing before the +message is sent to the intended destination. -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 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. +The interceptor can also be configured to not send to the destination (skip) +which means the message is detoured instead. -Let start with a simple example, where we want to intercept when an -Exchange is being sent to `mock:foo`: +A xref:latest@manual:ROOT:predicate.adoc[Predicate] can also be used +to control when to intercept, which has been previously covered. -And this time we add the Predicate so its only when -the message body is `Hello World` we intercept. +The `afterUri` option, is used when you need to process +the response message from the intended destination. This functionality +was added later to the interceptor, in a form of sending to yet another xref:message-endpoint.adoc[endpoint]. -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. +Let start with a basic example, where we want to intercept when a +message is being sent to xref:components::kafka-component.adoc[kafka]: -*Conditional skipping* +[source,java] +---- +interceptSendToEndpoint("kafka*") + .to("bean:beforeKafka"); -The combination of `skipSendToEndpoint` with a `when` predicate only occurs if the `when` predicate is matched, leading to more natural logic altogether. +from("jms:queue:order") + .to("bean:validateOrder") + .to("bean:processOrder") + .to("kafka:order"); +---- + +And in XML: + +[source,xml] +---- +<camelContext> + + <interceptSendToEndpoint uri="kafka*"> + <to uri="bean:beforeKafka"/> + </intercept> + + <route> + <from uri="jms:queue:order"/> + <to uri="bean:validateOrder"/> + <to uri="bean:processOrder"/> + <to uri="kafka:order"/> + </route> + +</camelContext> +---- + +When you also want to process the message after it has been sent to the intended destination, +then the example is slightly _odd_ because you have to use the `afterUri` as shown: [source,java] -------------------------------------- -interceptSendToEndpoint("mock:foo").skipSendToOriginalEndpoint() - .when(simple("${body} == 'Hello World'") - .to("log:intercepted"); -------------------------------------- +---- +interceptSendToEndpoint("kafka*") + .to("bean:beforeKafka") + .afterUri("bean:afterKafka"); + +from("jms:queue:order") + .to("bean:validateOrder") + .to("bean:processOrder") + .to("kafka:order"); +---- + +And in XML: + +[source,xml] +---- +<camelContext> + + <interceptSendToEndpoint uri="kafka*" afterUri="bean:afterKafka"> + <to uri="bean:beforeKafka"/> + </intercept> + + <route> + <from uri="jms:queue:order"/> + <to uri="bean:validateOrder"/> + <to uri="bean:processOrder"/> + <to uri="kafka:order"/> + </route> + +</camelContext> +---- +=== Skip sending to original endpoint -[[Intercept-UsingfromSpringDSL.2]] -=== Using from Spring DSL +Sometimes you want to *intercept and skip* sending messages to a specific endpoint. -Intercept endpoint is of course also available using Spring DSL. +For example to avoid sending any message to kafka, but detour them to a +xref:components::mock-component.adoc[mock] endpoint, can be done as follows: -We start with the first example from above in Spring DSL: +[source,java] +---- +interceptSendToEndpoint("kafka*").skipSendToOriginalEndpoint() + .to("mock:kafka"); -And the 2nd. Notice how we can leverage the xref:components:languages:simple-language.adoc[Simple] -language for the Predicate: +from("jms:queue:order") + .to("bean:validateOrder") + .to("bean:processOrder") + .to("kafka:order"); +---- -And the 3rd with the `skip`, notice skip is set with the -`skipSendToOriginalEndpoint` attribute on the *interceptSendToEndpoint* -tag: +And in XML: [source,xml] --------------------------------------- +---- <camelContext> - <interceptSendToEndpoint uri="mock:foo" skipSendToOriginalEndpoint="true"> - <when><simple>${body} == 'Hello World'</simple></when> - <to uri="log:intercepted"/> - </interceptSendToEndpoint> - - <route> - <from uri="jms:queue:order"/> - <to uri="bean:validateOrder"/> - <to uri="bean:handleOrder"/> - </route> + + <interceptSendToEndpoint uri="kafka*" skipSendToOriginalEndpoint="true"> + <to uri="mock:kafka"/> + </intercept> + + <route> + <from uri="jms:queue:order"/> + <to uri="bean:validateOrder"/> + <to uri="bean:processOrder"/> + <to uri="kafka:order"/> + </route> + </camelContext> --------------------------------------- +---- -[[Intercept-InterceptSendToEndpoint-with-afterUrl]] -== InterceptSendToEndpoint with afterUrl +=== Conditional skipping sending to endpoint -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: +You can combine both a xref:latest@manual:ROOT:predicate.adoc[predicate] and skip sending to the original endpoint. +For example suppose you have some "test" messages that sometimes occur, and that you +want to avoid sending these message to a downstream kafka system, then this can be done as shown: [source,java] -------------------------------------- -interceptSendToEndpoint("jms*").afterUrl("log:jms-reply") - .to("log:jms-request"); -------------------------------------- +---- +interceptSendToEndpoint("kafka*").skipSendToOriginalEndpoint() + .when(simple("${header.biztype} == 'TEST'") + .log("TEST message detected - is NOT send to kafka"); -And in XML DSL: +from("jms:queue:order") + .to("bean:validateOrder") + .to("bean:processOrder") + .to("kafka:order"); +---- + +And in XML: [source,xml] --------------------------------------- -<interceptSendToEndpoint uri="jms*" afterUrl="log:jms-reply"> - <to uri="log:jms-request"/> -</inteinterceptSendToEndpointcept> --------------------------------------- +---- +<camelContext> + + <interceptSendToEndpoint uri="kafka*" skipSendToOriginalEndpoint="true"> + <when><simple>${header.biztype} == 'TEST'</simple></when> + <log message="TEST message detected - is NOT send to kafka"/> + </intercept> + <route> + <from uri="jms:queue:order"/> + <to uri="bean:validateOrder"/> + <to uri="bean:processOrder"/> + <to uri="kafka:order"/> + </route> -[[Intercept-AdvancedusageofIntercept]] -== Advanced usage of Intercept +</camelContext> +---- -The `interceptFrom` and `interceptSendToEndpoint` supports endpoint URI +== Intercepting endpoints using pattern matching + +The `interceptFrom` and `interceptSendToEndpoint` supports endpoint pattern matching by the following rules in the given order: -* match by exact URI name. This is the sample we have seen above. +* match by exact URI name * match by wildcard -* match by regular expression. +* match by regular expression + +=== Intercepting when matching by exact URI + +This matches only a specific endpoint with exactly the same URI. + +For example to intercept messages being send to a specific JMS queue you can do: -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. +[source,java] +------------------------------------- +interceptSendToEndpoint("jms:queue:cheese").to("log:smelly"); +------------------------------------- -[[Intercept-Matchbywildcard]] -=== Match by wildcard +=== Intercepting when matching endpoints 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. +given type. For instance use `file:*` will match all xref:components::file-component.adoc[file] based endpoints. [source,java] ------------------------------------- -intercept("jms:*").to("log:fromjms"); +interceptFrom("file:*").to("log:from-file"); ------------------------------------- -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: +Match by wildcard works so that the pattern ends with a `\*` and that +the uri matches if it starts with the same pattern. + +For example, you can be more specific, to only match for files +from specific folders like: [source,java] ---------------------------------------------------------- -intercept("file://order/inbox/*").to("log:newfileorders"); +interceptFrom("file:order/inbox/*").to("log:new-file-orders"); ---------------------------------------------------------- -To intercept any files received from the `order/inbox` folder. - -[[Intercept-Matchbyregularexpression]] -=== Match by regular expression +=== Intercepting when matching endpoints 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 @@ -375,18 +490,5 @@ and silver JMS queues we can do: [source,java] ----------------------------------------------------------- -intercept("jms:queue:(gold|silver)").to("seda:handleFast"); +interceptFrom("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. - - diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java index e6a66c0..21934a1 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/InterceptSendToEndpointDefinition.java @@ -112,13 +112,25 @@ public class InterceptSendToEndpointDefinition extends OutputDefinition<Intercep * After sending to the endpoint then send the message to this url which allows to process its result. * * @return the builder + * @deprecated use {@link #afterUri(String)} */ + @Deprecated public InterceptSendToEndpointDefinition afterUrl(String url) { setAfterUri(url); return this; } /** + * After sending to the endpoint then send the message to this url which allows to process its result. + * + * @return the builder + */ + public InterceptSendToEndpointDefinition afterUri(String uri) { + setAfterUri(uri); + return this; + } + + /** * This method is <b>only</b> for handling some post configuration that is needed since this is an interceptor, and * we have to do a bit of magic logic to fixup to handle predicates with or without proceed/stop set as well. */