| [[SpringBoot-SpringBoot]] |
| = Spring Boot |
| //Manually maintained attributes |
| :artifactid: camel-spring-boot |
| :shortname: spring-boot |
| :camel-spring-boot-name: spring-boot |
| |
| Spring Boot component provides auto-configuration for Apache Camel. Our |
| opinionated auto-configuration of the Camel context auto-detects Camel |
| routes available in the Spring context and registers the key Camel |
| utilities (like producer template, consumer template and the type |
| converter) as beans. |
| |
| Maven users will need to add the following dependency to their `pom.xml` |
| in order to use this component: |
| |
| [source,xml] |
| ---- |
| <dependency> |
| <groupId>org.apache.camel.springboot</groupId> |
| <artifactId>camel-spring-boot</artifactId> |
| <version>${camel.version}</version> <!-- use the same version as your Camel core version --> |
| </dependency> |
| ---- |
| |
| `camel-spring-boot` jar comes with the `org.springframework.boot.autoconfigure.AutoConfiguration.imports` file, so as |
| soon as you add that dependency into your classpath, Spring Boot will |
| automatically auto-configure Camel for you. |
| |
| == Camel Spring Boot Starter |
| |
| Apache Camel ships |
| a https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-starters[Spring |
| Boot Starter] module that allows you to develop Spring Boot applications |
| using starters. There is a |
| https://github.com/apache/camel-spring-boot-examples/tree/main/spring-boot[sample |
| application] in the source code also. |
| |
| To use the starter, add the following to your spring boot pom.xml file: |
| |
| [source,xml] |
| ---- |
| <dependency> |
| <groupId>org.apache.camel.springboot</groupId> |
| <artifactId>camel-spring-boot-starter</artifactId> |
| <version>${camel.version}</version> <!-- use the same version as your Camel core version --> |
| </dependency> |
| ---- |
| |
| Then you can just add classes with your Camel routes such as: |
| |
| [source,java] |
| ---- |
| package com.example; |
| |
| import org.apache.camel.builder.RouteBuilder; |
| import org.springframework.stereotype.Component; |
| |
| @Component |
| public class MyRoute extends RouteBuilder { |
| |
| @Override |
| public void configure() throws Exception { |
| from("timer:foo").to("log:bar"); |
| } |
| } |
| ---- |
| |
| Then these routes will be started automatically. |
| |
| You can customize the Camel application in the `application.properties` |
| or `application.yml` file. |
| |
| |
| // spring-boot-auto-configure options: START |
| include::{page-component-version}@components:spring-boot:partial$starter.adoc[] |
| // spring-boot-auto-configure options: END |
| |
| == Auto-configured Camel context |
| |
| The most important piece of functionality provided by the Camel |
| auto-configuration is `CamelContext` instance. |
| Camel auto-configuration creates a `SpringCamelContext` for you and |
| takes care of the proper initialization and shutdown of that context. |
| The created Camel context is also registered in the Spring application |
| context (under `camelContext` bean name), so you can access it just as |
| any other Spring bean. |
| |
| [source,java] |
| ---- |
| @Configuration |
| public class MyAppConfig { |
| |
| @Autowired |
| CamelContext camelContext; |
| |
| @Bean |
| MyService myService() { |
| return new DefaultMyService(camelContext); |
| } |
| |
| } |
| ---- |
| |
| == Auto-detecting Camel routes |
| |
| Camel auto-configuration collects all the `RouteBuilder` instances from |
| the Spring context and automatically injects them into the provided |
| `CamelContext`. That means that creating new Camel routes with the Spring |
| Boot starter is as simple as adding the `@Component` annotated class to |
| your classpath: |
| |
| [source,java] |
| ---- |
| @Component |
| public class MyRouter extends RouteBuilder { |
| |
| @Override |
| public void configure() throws Exception { |
| from("jms:invoices").to("file:/invoices"); |
| } |
| |
| } |
| ---- |
| |
| Or creating a new route `RouteBuilder` bean in your `@Configuration` class: |
| |
| [source,java] |
| ---- |
| @Configuration |
| public class MyRouterConfiguration { |
| |
| @Bean |
| RoutesBuilder myRouter() { |
| return new RouteBuilder() { |
| |
| @Override |
| public void configure() throws Exception { |
| from("jms:invoices").to("file:/invoices"); |
| } |
| |
| }; |
| } |
| |
| } |
| ---- |
| |
| == Camel properties |
| |
| Spring Boot auto-configuration automatically connects |
| to http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config[Spring |
| Boot external configuration] (like properties placeholders, OS |
| environment variables or system properties) with |
| the Camel properties support. It basically means |
| that any property defined in `application.properties` file: |
| |
| [source,properties] |
| ---- |
| route.from = jms:invoices |
| ---- |
| |
| Or set via system property: |
| |
| [source,properties] |
| ---- |
| java -Droute.to=jms:processed.invoices -jar mySpringApp.jar |
| ---- |
| |
| ...can be used as placeholders in Camel route: |
| |
| [source,java] |
| ---- |
| @Component |
| public class MyRouter extends RouteBuilder { |
| |
| @Override |
| public void configure() throws Exception { |
| from("{{route.from}}").to("{{route.to}}"); |
| } |
| |
| } |
| ---- |
| |
| == Custom Camel context configuration |
| |
| If you would like to perform some operations on `CamelContext` bean |
| created by Camel auto-configuration, |
| register `CamelContextConfiguration` instance in your Spring context: |
| |
| [source,java] |
| ---- |
| @Configuration |
| public class MyAppConfig { |
| |
| @Bean |
| CamelContextConfiguration contextConfiguration() { |
| return new CamelContextConfiguration() { |
| @Override |
| void beforeApplicationStart(CamelContext context) { |
| // your custom configuration goes here |
| } |
| }; |
| } |
| |
| } |
| ---- |
| |
| Method beforeApplicationStart` will |
| be called just before the Spring context is started, so the |
| `CamelContext` instance passed to this callback is |
| fully auto-configured. You can add many instances of |
| `CamelContextConfiguration` into your Spring context - all of them will |
| be executed. |
| |
| |
| == Auto-configured consumer and producer templates |
| |
| Camel auto-configuration provides pre-configured `ConsumerTemplate` and |
| `ProducerTemplate` instances. You can simply inject them into your |
| Spring-managed beans: |
| |
| [source,java] |
| ---- |
| @Component |
| public class InvoiceProcessor { |
| |
| @Autowired |
| private ProducerTemplate producerTemplate; |
| |
| @Autowired |
| private ConsumerTemplate consumerTemplate; |
| |
| public void processNextInvoice() { |
| Invoice invoice = consumerTemplate.receiveBody("jms:invoices", Invoice.class); |
| ... |
| producerTemplate.sendBody("netty-http:http://invoicing.com/received/" + invoice.id()); |
| } |
| |
| } |
| ---- |
| |
| By default, consumer templates and producer templates come with the |
| endpoint cache sizes set to 1000. You can change those values via the |
| following Spring properties: |
| |
| [source,properties] |
| ---- |
| camel.springboot.consumer-template-cache-size = 100 |
| camel.springboot.producer-template-cache-size = 200 |
| ---- |
| [[typeconverter]] |
| == Auto-configured TypeConverter |
| |
| Camel auto-configuration registers a `TypeConverter` instance named |
| `typeConverter` in the Spring context. |
| |
| [source,java] |
| ---- |
| @Component |
| public class InvoiceProcessor { |
| |
| @Autowired |
| private TypeConverter typeConverter; |
| |
| public long parseInvoiceValue(Invoice invoice) { |
| String invoiceValue = invoice.grossValue(); |
| return typeConverter.convertTo(Long.class, invoiceValue); |
| } |
| |
| } |
| ---- |
| |
| === Spring type conversion API bridge |
| |
| Spring comes with |
| the powerful http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html#core-convert[type |
| conversion API]. Spring API happens to be very similar to the Camel |
| type converter API. As those APIs are so |
| similar, Camel Spring Boot automatically registers a bridge converter |
| (`SpringTypeConverter`) that delegates to the Spring conversion API.That |
| means that out-of-the-box Camel will treat Spring Converters like Camel |
| ones. With this approach you can enjoy both Camel and Spring converters |
| accessed via Camel `TypeConverter` API: |
| |
| [source,java] |
| ---- |
| @Component |
| public class InvoiceProcessor { |
| |
| @Autowired |
| private TypeConverter typeConverter; |
| |
| public UUID parseInvoiceId(Invoice invoice) { |
| // Using Spring's StringToUUIDConverter |
| UUID id = invoice.typeConverter.convertTo(UUID.class, invoice.getId()); |
| } |
| |
| } |
| ---- |
| |
| Under the hood Camel Spring Boot delegates conversion to the Spring's |
| `ConversionService` instances available in the application context. If |
| no `ConversionService` instance is available, Camel Spring Boot |
| auto-configuration will create one for you. |
| |
| |
| == Keeping the application alive |
| |
| Camel applications having this feature enabled launch a new thread on startup for the sole purpose of |
| keeping the application alive by preventing JVM termination. |
| It means that after you start a Camel application with Spring Boot, your |
| application waits for a `Ctrl+C` signal and does not exit immediately. |
| |
| The controller thread can be activated using the `camel.springboot.main-run-controller` to `true`. |
| |
| [source,properties] |
| ---- |
| camel.springboot.main-run-controller = true |
| ---- |
| |
| Applications using web modules (e.g. importing the `org.springframework.boot:spring-boot-web-starter` module), |
| usually don't need to use this feature because the application is kept alive by the presence of other non-daemon threads. |
| |
| == Adding XML routes |
| |
| By default, you can put Camel XML routes in the classpath under the |
| directory camel, which camel-spring-boot will auto-detect and include. |
| You can configure the directory name or turn |
| this off using the configuration option |
| |
| [source,properties] |
| ---- |
| # turn off |
| camel.springboot.routes-include-pattern = false |
| # scan only in the com/foo/routes classpath |
| camel.springboot.routes-include-pattern = classpath:com/foo/routes/*.xml |
| ---- |
| |
| The XML files should be Camel XML routes (*not* `<CamelContext>`) such as |
| |
| [source,xml] |
| ---- |
| <routes xmlns="http://camel.apache.org/schema/spring"> |
| <route id="test"> |
| <from uri="timer://trigger"/> |
| <transform> |
| <simple>ref:myBean</simple> |
| </transform> |
| <to uri="log:out"/> |
| </route> |
| </routes> |
| ---- |
| |
| == Testing the JUnit 5 way |
| |
| For testing, Maven users will need to add the following dependencies to their `pom.xml`: |
| |
| [source,xml] |
| ---- |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-test</artifactId> |
| <version>${spring-boot.version}</version> <!-- Use the same version as your Spring Boot version --> |
| <scope>test</scope> |
| </dependency> |
| <dependency> |
| <groupId>org.apache.camel</groupId> |
| <artifactId>camel-test-spring-junit5</artifactId> |
| <version>${camel.version}</version> <!-- use the same version as your Camel core version --> |
| <scope>test</scope> |
| </dependency> |
| ---- |
| |
| To test a Camel Spring Boot application, annotate your test class(es) with |
| `@CamelSpringBootTest`. This brings Camel's Spring Test |
| support to your application, so that you can write tests using |
| https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html[Spring Boot test conventions]. |
| |
| To get the `CamelContext` or `ProducerTemplate`, you can inject them into the class in the normal Spring manner, using `@Autowired`. |
| |
| You can also use xref:components:others:test-spring-junit5.adoc[camel-test-spring-junit5] to configure tests declaratively. This example uses the `@MockEndpoints` annotation to auto-mock an endpoint: |
| |
| [source,java] |
| ---- |
| @CamelSpringBootTest |
| @SpringBootApplication |
| @MockEndpoints("direct:end") |
| public class MyApplicationTest { |
| |
| @Autowired |
| private ProducerTemplate template; |
| |
| @EndpointInject("mock:direct:end") |
| private MockEndpoint mock; |
| |
| @Test |
| public void testReceive() throws Exception { |
| mock.expectedBodiesReceived("Hello"); |
| template.sendBody("direct:start", "Hello"); |
| mock.assertIsSatisfied(); |
| } |
| |
| } |
| ---- |
| |
| == Camel Spring Boot Native |
| |
| One of the most interesting features added to Spring Boot 3 is the support of GraalVM Native Image which allows you to reduce |
| significantly the memory footprint and the startup time of your application. Those improvements are only possible thanks |
| to the Ahead-Of-Time (AOT) compilation that relies on a closed-world assumption which means that everything needs to be |
| known at build type, all dynamic aspects included such as reflection, JNI, Proxy, and resources loading from a ClassLoader. |
| |
| For now, only Camel routes written using the Java, XML, and/or YAML DSL with basic components that don't rely on dynamic aspects to work are covered out of the box. For other components, |
| you will need to provide GraalVM some hints to let it know all the dynamic aspects needed by your application either by |
| implementing your custom https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.advanced.custom-hints[`RuntimeHintsRegistrar`] |
| or by providing GraalVM JSON hint files that can be generated by the https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html#native-image.advanced.using-the-tracing-agent[Tracing Agent]. |
| |
| For more details about `GraalVM Native Image Support` in Spring Boot please refer to https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html |
| |
| == Camel Asynchronous Health Checks |
| |
| Camel health checks can be executed asynchronously via a Task Scheduler so that the result can be cached and the actual health check is executed in background every few seconds. Asynchronous Camel health checks are disabled by default but can be enabled with the following property: |
| |
| [source,properties] |
| ---- |
| camel.health.async-camel-health-check=true |
| ---- |
| |
| moreover the Camel health check task scheduler can be customized with the following properties: |
| |
| [source,properties] |
| ---- |
| camel.health.healthCheckPoolSize=5 |
| camel.health.healthCheckFrequency=10 |
| camel.health.healthCheckThreadNamePrefix=CamelHealthTaskScheduler |
| ---- |
| |
| == Camel Readiness and Liveness State Indicators |
| |
| Camel specific Readiness and Liveness checks can be added to a Spring Boot 3 application including respectively in the |
| readiness and livenss groups camelLivenessStateHealthIndicator and camelReadinessStateHealthIndicator. In particular: |
| |
| [source,properties] |
| ---- |
| management.endpoint.health.group.liveness.include=livenessState,camelLivenessState |
| management.endpoint.health.group.readiness.include=readinessState,camelReadinessState |
| ---- |
| |
| Using Camel specific readiness and liveness health indicators, the probes will be augmented with camel components |
| health checks that support this feature. In enable the probes locally, they need to be enabled |
| |
| [source,properties] |
| ---- |
| management.endpoint.health.probes.enabled=true |
| ---- |
| |
| Finally, http://localhost:8080/actuator/health/liveness will show the updated probe. |