This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-16757b in repository https://gitbox.apache.org/repos/asf/camel.git
commit 8ee3b0644d5686feb198ecf9a8b50fedaba1a15b Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Tue Aug 3 14:32:25 2021 +0200 CAMEL-16757: Added route configuration docs --- docs/user-manual/modules/ROOT/nav.adoc | 1 + docs/user-manual/modules/ROOT/pages/index.adoc | 1 + .../modules/ROOT/pages/route-configuration.adoc | 282 +++++++++++++++++++++ 3 files changed, 284 insertions(+) diff --git a/docs/user-manual/modules/ROOT/nav.adoc b/docs/user-manual/modules/ROOT/nav.adoc index 4facacc..e877c00 100644 --- a/docs/user-manual/modules/ROOT/nav.adoc +++ b/docs/user-manual/modules/ROOT/nav.adoc @@ -82,6 +82,7 @@ ** xref:lambda-route-builder.adoc[LambdaRouteBuilder] ** xref:route-controller.adoc[RouteController] ** xref:route-policy.adoc[RoutePolicy] +** xref:route-configuration.adoc[RouteConfiguration] ** xref:route-template.adoc[RouteTemplate] ** xref:routes.adoc[Routes] ** xref:stream-caching.adoc[Stream caching] diff --git a/docs/user-manual/modules/ROOT/pages/index.adoc b/docs/user-manual/modules/ROOT/pages/index.adoc index 86bce1c..36a57b0 100644 --- a/docs/user-manual/modules/ROOT/pages/index.adoc +++ b/docs/user-manual/modules/ROOT/pages/index.adoc @@ -117,6 +117,7 @@ camel routes without them knowing * xref:lambda-route-builder.adoc[LambdaRouteBuilder] * xref:route-controller.adoc[RouteController] * xref:route-policy.adoc[RoutePolicy] +* xref:route-configuration.adoc[RouteConfiguration] * xref:route-template.adoc[RouteTemplate] * xref:routes.adoc[Routes] * xref:stream-caching.adoc[Stream caching] diff --git a/docs/user-manual/modules/ROOT/pages/route-configuration.adoc b/docs/user-manual/modules/ROOT/pages/route-configuration.adoc new file mode 100644 index 0000000..c506540 --- /dev/null +++ b/docs/user-manual/modules/ROOT/pages/route-configuration.adoc @@ -0,0 +1,282 @@ +[[RouteConfiguration]] += Route Configuration + +Camel 3.12 introduces route configuration which is used for separating configurations +from the routes. This can be used in situations such as configuring different error handling across a set of routes. +In previous versions of Camel this was more cumbersome to do, as you would either have +to copy the same configuration to a set of routes or rely on global error handling configuration. + +Now you can configure a number of route configurations, and then specify on each route +which configuration to use (you can use match by ids, wildcards, and regular expression). + +The route configuration is supported by all DSL's, so useable by: Java, XML, Groovy, XML, Kotlin and so forth. + +In the route configuration you can setup common strategies for: + +- error handling via `onException` +- interceptors via `intercept`, `interceptFrom`, `interceptSendTo` +- on completions via `onCompletion` + + +== Route Configuration Builder in Java DSL + +With Java DSL you can use `RouteConfigurationBuilder` to specify the configuration as shown below. +The builder is similar to `RouteBuilder` so its familiar how to use. + +[source,java] +---- +public class MyJavaErrorHandler extends RouteConfigurationBuilder { + + @Override + public void configuration() throws Exception { + routeConfiguration("javaError") + .onException(Exception.class).handled(true) + .log("Java WARN: ${exception.message}"); + } +} +---- + +NOTE: The `RouteConfigurationBuilder` uses `configuration` as the method where the configuration is coded. +This is on purpose to not use the `configure` method which the regular Java DSL `RouteBuilder` +uses for coding Camel routes. + +In the example above, then there is only one route configuration which has been assigned the ID _javaError_. +This ID allows us to refer to this configuration later when you want to assign which routes are using the configuration. + +This configuration is a basic configuration that just catches and handles all exceptions and logs a WARN message. + +=== Assigning route configurations to routes + +To use this configuration in your routes, then you can assign it with `routeConfigurationId` as shown: + +[source,java] +---- +public class MyJavaRouteBuilder extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("timer:java?period=2s") + // refer to the route configuration by the id to use for this route + .routeConfigurationId("javaError") + .setBody(method(MyJavaRouteBuilder.class, "randomNumber")) + .log("Random number ${body}") + .filter(simple("${body} < 30")) + .throwException(new IllegalArgumentException("The number is too low")); + } + + public static int randomNumber() { + return new Random().nextInt(100); + } +} +---- + +In the `routeConfigurationId` the configuration to use is specified by the ID, eg _javaError_. + +Multiple configurations can be assigned (separated by comma), such as: + +[source,java] +---- +.routeConfigurationId("javaError,myAudit") +---- + +The route configurations supports matching by: + +- match by exact ID name. This is the sample we have seen above. +- match by wildcard +- match by regular expression. + +Wildcards is match that the text before the * is matched against the given configuration and if it also starts with the same characters its a match. For instance you can do: + +[source,java] +---- +.routeConfigurationId("java*,myAudit") +---- + +Here we use wildcard in _java*_ which means any configuration that starts with java is a match. + +Match by regular expression is just like match by wildcard but using regex instead. + +[source,java] +---- +.routeConfigurationId(".*error.*") +---- + +Here we want to match any routes that has _error_ in the name. + +=== Adding route configurations to CamelContext + +Because a `RouteConfigurationBuilder` is also a `RouteBuilder` then you add route configurations +the same way for `RouteBuilder` such as using the API on `CamelContext` + +[source,java] +---- +CamelContext context = ... +// add the route configuration +context.addRoutes(new MyJavaErrorHandler()); +// add the regular route +context.addRoutes(new MyJavaRouteBuilder()); +---- + +If you use Spring Boot, then your Camel routes and route configurations can be auto-discovered +by the spring boot component scanning. This requires to add `@Component` annotation to the class. + +See the example https://github.com/apache/camel-spring-boot-examples/tree/main/routes-configuration[camel-example-spring-boot-routes-configuration]. + + +=== Route configuration with Endpoint DSL + +The xref:Endpoint-dsl.adoc[Endpoint DSL] can also be used for route configurations. +This requires to add `camel-endpointdsl` to the classpath, and then use +`org.apache.camel.builder.endpoint.EndpointRouteConfigurationBuilder`, +which offers the _type safe_ DSL for Camel endpoints. + + +== Default route configurations + +Route configurations are either given an explicit unique ID, or the configuration is _nameless_. +A _nameless_ configuration is used as default/fallback configuration, for routes which has *NOT* +been explicit assigned route configurations. + +Suppose you have one _nameless_ configuration and another named _javaError_: + +[source,java] +---- +public class MyJavaErrorHandler extends RouteConfigurationBuilder { + + @Override + public void configuration() throws Exception { + routeConfiguration() + .onException(Exception.class).handled(true) + .log("WARN: ${exception.message}"); + + routeConfiguration("retryError") + .onException(Exception.class).maximumRedeliveries(5); + } +} +---- + +And the follow two routes: + +[source,java] +---- + from("file:cheese").routeId("cheese") + .to("kafka:cheese"); + + from("file:beer").routeId("beer") + .routeConfigurationId("retryError") + .to("jms:beer"); +---- + +In the example above, then the _cheese_ route has no route configurations assigned, so the route +will use the default configuration, which in case of an exception will log a warning. + +The _beer_ route on the other hand have route configuration _retryError_ assigned, and this +configuration will in case of an exception retry again up till 5 times and then if still an error +then fail and rollback. + +If you add more routes, then those routes can also be assigned the _retryError_ configuration +if they should also retry in case of error. + + +== Route Configuration in XML + +When using XML DSL then you can code your route configurations in XML files as shown below: + +[source,xml] +---- +<routeConfiguration id="xmlError"> + <onException> + <exception>java.lang.Exception</exception> + <handled><constant>true</constant></handled> + <log message="XML WARN: ${exception.message}"/> + </onException> +</routeConfiguration> +---- + +And in the XML routes you can assign which configurations to use: + +[source,xml] +---- +<route routeConfigurationId="xmlError"> + <from uri="timer:xml?period=5s"/> + <log message="I am XML"/> + <throwException exceptionType="java.lang.Exception" message="Some kind of XML error"/> +</route> +---- + +In this example the route is assigned the _xmlError_ route configuration by the exact ID. + + +== Route Configuration in YAML + +When using YAML DSL then you can code your route configurations in YAML files as shown below: + +[source,yaml] +---- +- route-configuration: + - id: "yamlError" + - on-exception: + handled: + constant: "true" + exception: + - "java.lang.Exception" + steps: + - log: + message: "YAML WARN ${exception.message}" +---- + +And in the YAML routes you can assign which configurations to use: + +[source,yaml] +---- +- route: + # refer to the route configuration by the id to use for this route + route-configuration-id: "yamlError" + from: "timer:yaml?period=3s" + steps: + - set-body: + simple: "Timer fired ${header.CamelTimerCounter} times" + - to: + uri: "log:yaml" + parameters: + show-body-type: false + show-exchange-pattern: false + - throw-exception: + exception-type: "java.lang.IllegalArgumentException" + message: "Error from yaml" +---- + +In this example the route is assigned the _yamlError_ route configuration by the exact ID. + +== Logging Summary + +If you set `startup-summary-level=verbose` then Camel will log on for each route which route configurations they have been assigned. + +This option can be configured via Java API and also in `application.properties` for Camel on Spring Boot, Quarkus, and Camel standalone via `camel-main` + +[source,java] +---- +camelContext.setStartupSummaryLevel(StartupSummaryLevel.Verbose); +---- + +And with Spring Boot: + +[source,properties] +---- +camel.spring-boot.startup-summary-level = verbose +---- + +And in Camel Main / Quarkus: + +[source,properties] +---- +camel.main.startup-summary-level = verbose +---- + +== See Also + +See the examples: + +- https://github.com/apache/camel-examples/tree/main/examples/routes-configuration[camel-example-routes-configuration] +- https://github.com/apache/camel-spring-boot-examples/tree/main/routes-configuration[camel-example-spring-boot-routes-configuration] +