CAMEL-11756: camel-spring-boot2 - Work in progress

Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/cb70f538
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/cb70f538
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/cb70f538

Branch: refs/heads/boot2
Commit: cb70f5387f220852b06064fe2c8ea90b924d4cb4
Parents: 3a478cb
Author: Claus Ibsen <davscl...@apache.org>
Authored: Sat Sep 9 13:43:35 2017 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Sat Sep 9 13:43:35 2017 +0200

----------------------------------------------------------------------
 components/camel-spring-boot2/pom.xml           | 180 ++++
 .../src/main/docs/spring-boot.adoc              | 456 +++++++++
 .../spring/boot/CamelAutoConfiguration.java     | 524 ++++++++++
 .../boot/CamelConfigurationProperties.java      | 951 +++++++++++++++++++
 .../spring/boot/CamelContextConfiguration.java  |  27 +
 .../spring/boot/CamelMainRunController.java     |  56 ++
 .../CamelSpringBootApplicationController.java   | 103 ++
 .../CamelSpringBootInitializationException.java |  25 +
 .../boot/ComponentConfigurationProperties.java  |  23 +
 .../ComponentConfigurationPropertiesCommon.java |  60 ++
 .../boot/DataFormatConfigurationProperties.java |  23 +
 ...DataFormatConfigurationPropertiesCommon.java |  60 ++
 .../boot/FatJarPackageScanClassResolver.java    | 100 ++
 .../camel/spring/boot/FilePropertySource.java   |  81 ++
 .../boot/LanguageConfigurationProperties.java   |  23 +
 .../LanguageConfigurationPropertiesCommon.java  |  60 ++
 .../camel/spring/boot/RoutesCollector.java      | 317 +++++++
 .../SpringBootXmlCamelContextConfigurer.java    |  47 +
 .../spring/boot/SpringPropertiesParser.java     |  39 +
 .../camel/spring/boot/SpringTypeConverter.java  |  85 ++
 ...rvisingRouteControllerAutoConfiguration.java |  93 ++
 ...SupervisingRouteControllerConfiguration.java | 179 ++++
 .../boot/TypeConversionConfiguration.java       |  64 ++
 .../endpoint/CamelRouteControllerEndpoint.java  |  60 ++
 ...outeControllerEndpointAutoConfiguration.java |  49 +
 .../CamelRouteControllerMvcEndpoint.java        |  79 ++
 .../actuate/endpoint/CamelRoutesEndpoint.java   | 377 ++++++++
 .../CamelRoutesEndpointAutoConfiguration.java   |  49 +
 .../endpoint/CamelRoutesMvcEndpoint.java        | 247 +++++
 .../health/CamelHealthAutoConfiguration.java    |  46 +
 .../actuate/health/CamelHealthIndicator.java    |  52 +
 .../boot/cloud/CamelCloudAutoConfiguration.java |  30 +
 .../CamelCloudConfigurationProperties.java      | 274 ++++++
 ...rviceCallConfigurationAutoConfiguration.java |  83 ++
 ...melCloudServiceChooserAutoConfiguration.java |  43 +
 .../boot/cloud/CamelCloudServiceDiscovery.java  |  47 +
 ...lCloudServiceDiscoveryAutoConfiguration.java | 128 +++
 .../boot/cloud/CamelCloudServiceFilter.java     |  36 +
 ...amelCloudServiceFilterAutoConfiguration.java | 124 +++
 ...usteredRouteControllerAutoConfiguration.java | 101 ++
 .../ClusteredRouteControllerConfiguration.java  | 147 +++
 .../security/CamelSSLAutoConfiguration.java     |  63 ++
 .../CamelSSLConfigurationProperties.java        |  42 +
 .../spring/boot/util/CamelPropertiesHelper.java |  95 ++
 ...OnCamelContextAndAutoConfigurationBeans.java |  36 +
 .../camel/spring/boot/util/GroupCondition.java  |  44 +
 .../util/HierarchicalPropertiesEvaluator.java   |  58 ++
 .../src/main/resources/META-INF/LICENSE.txt     | 203 ++++
 .../src/main/resources/META-INF/NOTICE.txt      |  11 +
 ...dditional-spring-configuration-metadata.json |  16 +
 .../main/resources/META-INF/spring.factories    |  30 +
 .../camel/spring/boot/CamelAnnotationsTest.java |  71 ++
 .../CamelAutoConfigurationPropertiesTest.java   |  88 ++
 .../spring/boot/CamelAutoConfigurationTest.java | 194 ++++
 .../boot/CamelConfigurationLocationsTest.java   |  67 ++
 .../spring/boot/CamelEventNotifierTest.java     | 105 ++
 .../boot/CamelNonInvasiveCamelContextTest.java  |  85 ++
 .../boot/CamelSpringBootShutdownTest.java       | 127 +++
 .../CamelSpringBootTemplateShutdownTest.java    |  84 ++
 .../spring/boot/CustomShutdownStrategyTest.java |  93 ++
 .../boot/ExistingConversionServiceTest.java     |  58 ++
 .../boot/MixedBootAndXmlConfigurationTest.java  |  55 ++
 .../spring/boot/MixedJavaDslAndXmlTest.java     |  78 ++
 .../camel/spring/boot/NoConvertersTest.java     |  46 +
 .../org/apache/camel/spring/boot/PlainTest.java |  54 ++
 .../RouteConfigWithCamelContextInjected.java    |  44 +
 .../boot/SpringConverterDelegationTest.java     |  65 ++
 .../spring/boot/SpringTypeConverterTest.java    | 126 +++
 .../spring/boot/StartupShutdownOrderTest.java   | 238 +++++
 .../SupervisingRouteControllerRestartTest.java  | 140 +++
 .../boot/SupervisingRouteControllerTest.java    | 126 +++
 .../actuate/endpoint/ActuatorTestRoute.java     |  30 +
 .../endpoint/CamelRoutesEndpointTest.java       |  59 ++
 .../endpoint/CamelRoutesMvcEndpointTest.java    |  68 ++
 .../boot/actuate/health/CamelHealthTest.java    |  55 ++
 .../boot/actuate/health/MyCamelRoute.java       |  29 +
 .../CamelCloudServiceCallConfigurationTest.java |  76 ++
 ...CloudServiceCallGlobalConfigurationTest.java | 127 +++
 .../CamelCloudServiceCallRefExpressionTest.java | 133 +++
 ...melCloudServiceCallSimpleExpressionTest.java | 125 +++
 .../boot/cloud/CamelCloudServiceCallTest.java   | 126 +++
 .../boot/cloud/SpringBootPropertyUtil.java      |  57 ++
 .../boot/componentroute/ComponentRoute.java     |  36 +
 .../boot/componentroute/ComponentRouteTest.java |  55 ++
 .../camel/spring/boot/dummy/DummyComponent.java |  38 +
 .../camel/spring/boot/dummy/DummyConsumer.java  |  54 ++
 .../camel/spring/boot/dummy/DummyEndpoint.java  |  63 ++
 .../camel/spring/boot/issues/CountryPojo.java   |  78 ++
 .../spring/boot/issues/RestDslPostTest.java     | 102 ++
 .../spring/boot/issues/SimpleOgnlTest.java      |  69 ++
 .../spring/boot/issues/StreamCachingTest.java   |  96 ++
 .../camel/spring/boot/issues/UserPojo.java      |  74 ++
 .../boot/mockendpoints/AdviceWithTest.java      |  68 ++
 .../boot/mockendpoints/MockEndpointsTest.java   |  57 ++
 .../spring/boot/mockendpoints/MyRoute.java      |  30 +
 .../parent/SpringBootRefreshContextTest.java    |  57 ++
 .../camel/spring/boot/routefilter/BarRoute.java |  30 +
 .../camel/spring/boot/routefilter/BarTest.java  |  54 ++
 .../spring/boot/routefilter/DrinkRoute.java     |  30 +
 .../camel/spring/boot/routefilter/FooRoute.java |  30 +
 .../camel/spring/boot/routefilter/FooTest.java  |  54 ++
 .../security/CamelSSLAutoConfigurationTest.java |  68 ++
 .../boot/security/CamelSSLNoConfigTest.java     |  53 ++
 .../boot/util/CamelPropertiesHelperTest.java    | 170 ++++
 .../spring/boot/util/GroupConditionTest1.java   |  49 +
 .../spring/boot/util/GroupConditionTest2.java   |  49 +
 .../spring/boot/util/GroupConditionTest3.java   |  49 +
 .../spring/boot/util/GroupConditionTest4.java   |  49 +
 .../boot/util/GroupConditionTestBase.java       |  41 +
 .../HierarchicalPropertiesEvaluatorTest.java    |  63 ++
 .../src/test/resources/application.properties   |  23 +
 .../src/test/resources/camel/camelContext.xml   |  25 +
 .../src/test/resources/externalCamelContext.xml |  37 +
 .../src/test/resources/logback.xml              |  42 +
 .../src/test/resources/mixed-camel-context.xml  |  30 +
 .../src/test/resources/test-camel-context.xml   |  35 +
 .../src/test/secret/do-not-tell.properties      |  18 +
 parent/pom.xml                                  |   1 +
 118 files changed, 10852 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/cb70f538/components/camel-spring-boot2/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring-boot2/pom.xml 
b/components/camel-spring-boot2/pom.xml
new file mode 100644
index 0000000..b8c0898
--- /dev/null
+++ b/components/camel-spring-boot2/pom.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>components</artifactId>
+    <version>2.20.0-SNAPSHOT</version>
+  </parent>
+
+  <name>Camel :: Spring Boot 2</name>
+  <artifactId>camel-spring-boot2</artifactId>
+  <description>Using Camel with Spring Boot 2</description>
+
+  <properties>
+    <!-- use by camel-catalog -->
+    <firstVersion>2.20.0</firstVersion>
+    <label>spring,microservice</label>
+
+    <camel.osgi.export.pkg/>
+
+    <spring-version>5.0.0.RC3</spring-version>
+    <jackson2-version>2.9.1</jackson2-version>
+
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter</artifactId>
+      <optional>true</optional>
+      <version>${spring-boot2-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-configuration-processor</artifactId>
+      <optional>true</optional>
+      <version>${spring-boot2-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-actuator</artifactId>
+      <optional>true</optional>
+      <version>${spring-boot2-version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-spring</artifactId>
+    </dependency>
+
+    <!-- Optional Spring web support -->
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-web</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+      <version>${spring-boot2-version}</version>
+      <optional>true</optional>
+    </dependency>
+
+    <!-- Testing dependencies -->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-test-spring</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-core-xml</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.awaitility</groupId>
+      <artifactId>awaitility</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>${commons-logging-version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <version>${spring-boot2-version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-jetty</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-jackson</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <!-- TODO: using milestone of spring-boot 2 -->
+  <repositories>
+    <repository>
+      <id>spring-milestones</id>
+      <name>Spring Milestones</name>
+      <url>https://repo.spring.io/libs-milestone</url>
+      <snapshots>
+        <enabled>false</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <forkCount>1</forkCount>
+          <reuseForks>false</reuseForks>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>jdk9-build</id>
+      <activation>
+        <jdk>9</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              
<forkedProcessTimeoutInSeconds>3000</forkedProcessTimeoutInSeconds>
+              <argLine>--add-modules java.xml.bind --add-opens 
java.base/java.lang=ALL-UNNAMED</argLine>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/camel/blob/cb70f538/components/camel-spring-boot2/src/main/docs/spring-boot.adoc
----------------------------------------------------------------------
diff --git a/components/camel-spring-boot2/src/main/docs/spring-boot.adoc 
b/components/camel-spring-boot2/src/main/docs/spring-boot.adoc
new file mode 100644
index 0000000..9f148a6
--- /dev/null
+++ b/components/camel-spring-boot2/src/main/docs/spring-boot.adoc
@@ -0,0 +1,456 @@
+[[SpringBoot-SpringBoot]]
+Spring Boot
+~~~~~~~~~~~
+
+*Available as of Camel 2.15*
+
+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</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 `spring.factories` file, so as
+soon as you add that dependency into your classpath, Spring Boot will
+automatically auto-configure Camel for you.
+
+[[SpringBoot-CamelSpringBootStarter]]
+Camel Spring Boot Starter
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+*Available as of Camel 2.17*
+
+Apache Camel ships
+a 
https://github.com/spring-projects/spring-boot/tree/master/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/tree/master/examples/camel-example-spring-boot-starter[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</groupId>
+    <artifactId>camel-spring-boot-starter</artifactId>
+    <version>2.17.0</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. 
+
+[[SpringBoot-Auto-configuredCamelcontext]]
+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);
+  }
+
+}
+----------------------------------------------
+
+[[SpringBoot-Auto-detectingCamelroutes]]
+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 route 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");
+      }
+
+    };
+  }
+ 
+}
+--------------------------------------------------
+
+[[SpringBoot-Camelproperties]]
+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 link:properties.html[Camel properties support]. It basically means
+that any property defined in `application.properties` file:  
+
+[source,xml]
+-------------------------
+route.from = jms:invoices
+-------------------------
+
+...or set via system property...
+
+[source,xml]
+-----------------------------------------------------------
+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}}");
+  }
+
+}
+----------------------------------------------
+
+[[SpringBoot-CustomCamelcontextconfiguration]]
+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
+C`amelContextConfiguration#``beforeApplicationStart(CamelContext)` 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
+C`amelContextConfiguration` into your Spring context - all of them will
+be executed.
+
+[[SpringBoot-DisablingJMX]]
+Disabling JMX
+^^^^^^^^^^^^^
+
+To disable JMX of the auto-configured `CamelContext` use
+`camel.springboot.jmxEnabled` property (JMX is enabled by default). For
+example you could add the following property to your
+`application.properties` file:
+
+[source,xml]
+-----------------------------------
+camel.springboot.jmxEnabled = false
+-----------------------------------
+
+[[SpringBoot-Auto-configuredconsumerandproducertemplates]]
+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,xml]
+------------------------------------------------
+camel.springboot.consumerTemplateCacheSize = 100
+camel.springboot.producerTemplateCacheSize = 200
+------------------------------------------------
+
+[[SpringBoot-Auto-configuredTypeConverter]]
+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);
+  }
+
+}
+-------------------------------------------------------------
+
+[[SpringBoot-SpringtypeconversionAPIbridge]]
+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
+link:type-converter.html[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.
+
+[[SpringBoot-Disablingtypeconversionsfeatures]]
+Disabling type conversions features
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you don't want Camel Spring Boot to register type-conversions related
+features (like `TypeConverter` instance or Spring bridge) set the
+`camel.springboot.typeConversion` property to `false`.
+
+[source,xml]
+---------------------------------------
+camel.springboot.typeConversion = false
+---------------------------------------
+
+
+[[SpringBoot-Blockingmainthread]]
+Blocking main thread
+^^^^^^^^^^^^^^^^^^^^
+
+This feature is available starting from Camel *2.15.2*. Camel
+applications extending FatJarRouter by default block the main thread of
+the application. It means that after you start your fat jar, your
+application waits for Ctrl+C signal and does not exit immediately. If
+you would like to achieve similar behavior for non-`FatJarRouter`
+applications, retrieve `CamelSpringBootApplicationController `bean from
+your `ApplicationContext` and use the former to block the main thread of
+your application using
+`CamelSpringBootApplicationController#blockMainThread()` method.
+
+[source,java]
+------------------------------------------------------------------------------------------------------
+public static void main(String... args) {
+    ApplicationContext applicationContext = new 
SpringApplication(MyCamelApplication.class).run(args);
+    CamelSpringBootApplicationController applicationController =
+            
applicationContext.getBean(CamelSpringBootApplicationController.class);
+    applicationController.blockMainThread();
+}
+------------------------------------------------------------------------------------------------------
+
+[[SpringBoot-AddingXMLroutes]]
+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.
+From *Camel 2.17* onwards you can configure the directory name or turn
+this off using the configuration option
+
+[source,java]
+-----------------------------------------------------------
+// turn off
+camel.springboot.xmlRoutes = false
+// scan in the com/foo/routes classpath
+camel.springboot.xmlRoutes = 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>
+---------------------------------------------------------
+
+[[SpringBoot-AddingREST]]
+Adding XML Rest-DSL
+^^^^^^^^^^^^^^^^^^^
+
+By default you can put Camel Rest-DSL XML routes in the classpath under the
+directory camel-rest, which camel-spring-boot will auto detect and include.
+You can configure the directory name or turn this off using the configuration 
option
+
+[source,java]
+-----------------------------------------------------------
+// turn off
+camel.springboot.xmlRests = false
+// scan in the com/foo/routes classpath
+camel.springboot.xmlRests = classpath:com/foo/rests/*.xml
+-----------------------------------------------------------
+
+The Rest-DSL XML files should be Camel XML rests (not CamelContext) such as
+
+[source,xml]
+---------------------------------------------------------
+   <rests xmlns="http://camel.apache.org/schema/spring";>
+      <rest>
+         <post uri="/persons">
+            <to uri="direct:postPersons"/>
+         </post>
+         <get uri="/persons">
+            <to uri="direct:getPersons"/>
+         </get>
+         <get uri="/persons/{personId}">
+             <to uri="direct:getPersionId"/>
+         </get>
+         <put uri="/persons/{personId}">
+             <to uri="direct:putPersionId"/>
+         </put>
+         <delete uri="/persons/{personId}">
+             <to uri="direct:deletePersionId"/>
+         </delete>
+      </rest>
+    </rests>
+---------------------------------------------------------
+
+[[SpringBoot-SeeAlso]]
+See Also
+^^^^^^^^
+
+* link:configuring-camel.html[Configuring Camel]
+* link:component.html[Component]
+* link:endpoint.html[Endpoint]
+* link:getting-started.html[Getting Started]
+

http://git-wip-us.apache.org/repos/asf/camel/blob/cb70f538/components/camel-spring-boot2/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
----------------------------------------------------------------------
diff --git 
a/components/camel-spring-boot2/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
 
b/components/camel-spring-boot2/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
new file mode 100644
index 0000000..2f99fca
--- /dev/null
+++ 
b/components/camel-spring-boot2/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
@@ -0,0 +1,524 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.boot;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ConsumerTemplate;
+import org.apache.camel.Exchange;
+import org.apache.camel.FluentProducerTemplate;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.TypeConverters;
+import org.apache.camel.component.properties.PropertiesComponent;
+import org.apache.camel.component.properties.PropertiesParser;
+import org.apache.camel.ha.CamelClusterService;
+import org.apache.camel.impl.FileWatcherReloadStrategy;
+import org.apache.camel.processor.interceptor.BacklogTracer;
+import org.apache.camel.processor.interceptor.DefaultTraceFormatter;
+import org.apache.camel.processor.interceptor.HandleFault;
+import org.apache.camel.processor.interceptor.TraceFormatter;
+import org.apache.camel.processor.interceptor.Tracer;
+import org.apache.camel.spi.AsyncProcessorAwaitManager;
+import org.apache.camel.spi.EndpointStrategy;
+import org.apache.camel.spi.EventFactory;
+import org.apache.camel.spi.EventNotifier;
+import org.apache.camel.spi.InflightRepository;
+import org.apache.camel.spi.InterceptStrategy;
+import org.apache.camel.spi.LifecycleStrategy;
+import org.apache.camel.spi.ManagementNamingStrategy;
+import org.apache.camel.spi.ManagementStrategy;
+import org.apache.camel.spi.ReloadStrategy;
+import org.apache.camel.spi.RouteController;
+import org.apache.camel.spi.RoutePolicyFactory;
+import org.apache.camel.spi.RuntimeEndpointRegistry;
+import org.apache.camel.spi.ShutdownStrategy;
+import org.apache.camel.spi.StreamCachingStrategy;
+import org.apache.camel.spi.ThreadPoolProfile;
+import org.apache.camel.spi.UnitOfWorkFactory;
+import org.apache.camel.spring.CamelBeanPostProcessor;
+import org.apache.camel.spring.SpringCamelContext;
+import org.apache.camel.spring.spi.XmlCamelContextConfigurer;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.jsse.GlobalSSLContextParametersSupplier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.MutablePropertySources;
+
+@Configuration
+@EnableConfigurationProperties(CamelConfigurationProperties.class)
+@Import(TypeConversionConfiguration.class)
+public class CamelAutoConfiguration {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(CamelAutoConfiguration.class);
+
+    /**
+     * Allows to do custom configuration when running XML based Camel in 
Spring Boot
+     */
+    // must be named xmlCamelContextConfigurer
+    @Bean(name = "xmlCamelContextConfigurer")
+    XmlCamelContextConfigurer springBootCamelContextConfigurer() {
+        return new SpringBootXmlCamelContextConfigurer();
+    }
+
+    /**
+     * Spring-aware Camel context for the application. Auto-detects and loads 
all routes available in the Spring context.
+     */
+    // We explicitly declare the destroyMethod to be "" as the Spring @Bean
+    // annotation defaults to AbstractBeanDefinition.INFER_METHOD otherwise
+    // and in that case CamelContext::shutdown or CamelContext::stop would
+    // be used for bean destruction. As SpringCamelContext is a lifecycle
+    // bean (implements Lifecycle) additional invocations of shutdown or
+    // close would be superfluous.
+    @Bean(destroyMethod = "")
+    @ConditionalOnMissingBean(CamelContext.class)
+    CamelContext camelContext(ApplicationContext applicationContext,
+                              CamelConfigurationProperties config) throws 
Exception {
+        CamelContext camelContext = new SpringCamelContext(applicationContext);
+        return doConfigureCamelContext(applicationContext, camelContext, 
config);
+    }
+
+    static CamelContext doConfigureCamelContext(ApplicationContext 
applicationContext,
+                                         CamelContext camelContext,
+                                         CamelConfigurationProperties config) 
throws Exception {
+
+        if (ObjectHelper.isNotEmpty(config.getFileConfigurations())) {
+            Environment env = applicationContext.getEnvironment();
+            if (env instanceof ConfigurableEnvironment) {
+                MutablePropertySources sources = ((ConfigurableEnvironment) 
env).getPropertySources();
+                if (sources != null) {
+                    if (!sources.contains("camel-file-configuration")) {
+                        sources.addFirst(new 
FilePropertySource("camel-file-configuration", applicationContext, 
config.getFileConfigurations()));
+                    }
+                }
+            }
+        }
+
+        if (!config.isJmxEnabled()) {
+            camelContext.disableJMX();
+        }
+
+        if (config.getName() != null) {
+            ((SpringCamelContext) camelContext).setName(config.getName());
+        }
+
+        if (config.getShutdownTimeout() > 0) {
+            
camelContext.getShutdownStrategy().setTimeout(config.getShutdownTimeout());
+        }
+        
camelContext.getShutdownStrategy().setSuppressLoggingOnTimeout(config.isShutdownSuppressLoggingOnTimeout());
+        
camelContext.getShutdownStrategy().setShutdownNowOnTimeout(config.isShutdownNowOnTimeout());
+        
camelContext.getShutdownStrategy().setShutdownRoutesInReverseOrder(config.isShutdownRoutesInReverseOrder());
+        
camelContext.getShutdownStrategy().setLogInflightExchangesOnTimeout(config.isShutdownLogInflightExchangesOnTimeout());
+
+        if (config.getLogDebugMaxChars() > 0) {
+            
camelContext.getGlobalOptions().put(Exchange.LOG_DEBUG_BODY_MAX_CHARS, "" + 
config.getLogDebugMaxChars());
+        }
+
+        // stream caching
+        camelContext.setStreamCaching(config.isStreamCachingEnabled());
+        
camelContext.getStreamCachingStrategy().setAnySpoolRules(config.isStreamCachingAnySpoolRules());
+        
camelContext.getStreamCachingStrategy().setBufferSize(config.getStreamCachingBufferSize());
+        
camelContext.getStreamCachingStrategy().setRemoveSpoolDirectoryWhenStopping(config.isStreamCachingRemoveSpoolDirectoryWhenStopping());
+        
camelContext.getStreamCachingStrategy().setSpoolChiper(config.getStreamCachingSpoolChiper());
+        if (config.getStreamCachingSpoolDirectory() != null) {
+            
camelContext.getStreamCachingStrategy().setSpoolDirectory(config.getStreamCachingSpoolDirectory());
+        }
+        if (config.getStreamCachingSpoolThreshold() != 0) {
+            
camelContext.getStreamCachingStrategy().setSpoolThreshold(config.getStreamCachingSpoolThreshold());
+        }
+        if (config.getStreamCachingSpoolUsedHeapMemoryLimit() != null) {
+            StreamCachingStrategy.SpoolUsedHeapMemoryLimit limit;
+            if 
("Committed".equalsIgnoreCase(config.getStreamCachingSpoolUsedHeapMemoryLimit()))
 {
+                limit = 
StreamCachingStrategy.SpoolUsedHeapMemoryLimit.Committed;
+            } else if 
("Max".equalsIgnoreCase(config.getStreamCachingSpoolUsedHeapMemoryLimit())) {
+                limit = StreamCachingStrategy.SpoolUsedHeapMemoryLimit.Max;
+            } else {
+                throw new IllegalArgumentException("Invalid option " + 
config.getStreamCachingSpoolUsedHeapMemoryLimit() + " must either be Committed 
or Max");
+            }
+            
camelContext.getStreamCachingStrategy().setSpoolUsedHeapMemoryLimit(limit);
+        }
+        if (config.getStreamCachingSpoolUsedHeapMemoryThreshold() != 0) {
+            
camelContext.getStreamCachingStrategy().setSpoolUsedHeapMemoryThreshold(config.getStreamCachingSpoolUsedHeapMemoryThreshold());
+        }
+
+        camelContext.setMessageHistory(config.isMessageHistory());
+        camelContext.setLogMask(config.isLogMask());
+        
camelContext.setLogExhaustedMessageBody(config.isLogExhaustedMessageBody());
+        camelContext.setHandleFault(config.isHandleFault());
+        camelContext.setAutoStartup(config.isAutoStartup());
+        
camelContext.setAllowUseOriginalMessage(config.isAllowUseOriginalMessage());
+        camelContext.setUseBreadcrumb(config.isUseBreadcrumb());
+        camelContext.setUseDataType(config.isUseDataType());
+        camelContext.setUseMDCLogging(config.isUseMDCLogging());
+        camelContext.setLoadTypeConverters(config.isLoadTypeConverters());
+
+        if (camelContext.getManagementStrategy().getManagementAgent() != null) 
{
+            
camelContext.getManagementStrategy().getManagementAgent().setEndpointRuntimeStatisticsEnabled(config.isEndpointRuntimeStatisticsEnabled());
+            
camelContext.getManagementStrategy().getManagementAgent().setStatisticsLevel(config.getJmxManagementStatisticsLevel());
+            
camelContext.getManagementStrategy().getManagementAgent().setManagementNamePattern(config.getJmxManagementNamePattern());
+            
camelContext.getManagementStrategy().getManagementAgent().setCreateConnector(config.isJmxCreateConnector());
+        }
+
+        camelContext.setPackageScanClassResolver(new 
FatJarPackageScanClassResolver());
+
+        // tracing
+        camelContext.setTracing(config.isTracing());
+        if (camelContext.getDefaultTracer() instanceof Tracer) {
+            Tracer tracer = (Tracer) camelContext.getDefaultTracer();
+            if (tracer.getDefaultTraceFormatter() != null) {
+                DefaultTraceFormatter formatter = 
tracer.getDefaultTraceFormatter();
+                if (config.getTracerFormatterBreadCrumbLength() != null) {
+                    
formatter.setBreadCrumbLength(config.getTracerFormatterBreadCrumbLength());
+                }
+                if (config.getTracerFormatterMaxChars() != null) {
+                    formatter.setMaxChars(config.getTracerFormatterMaxChars());
+                }
+                if (config.getTracerFormatterNodeLength() != null) {
+                    
formatter.setNodeLength(config.getTracerFormatterNodeLength());
+                }
+                formatter.setShowBody(config.isTraceFormatterShowBody());
+                
formatter.setShowBodyType(config.isTracerFormatterShowBodyType());
+                
formatter.setShowBreadCrumb(config.isTraceFormatterShowBreadCrumb());
+                
formatter.setShowException(config.isTraceFormatterShowException());
+                
formatter.setShowExchangeId(config.isTraceFormatterShowExchangeId());
+                
formatter.setShowExchangePattern(config.isTraceFormatterShowExchangePattern());
+                formatter.setShowHeaders(config.isTraceFormatterShowHeaders());
+                formatter.setShowNode(config.isTraceFormatterShowNode());
+                
formatter.setShowProperties(config.isTraceFormatterShowProperties());
+                formatter.setShowRouteId(config.isTraceFormatterShowRouteId());
+                
formatter.setShowShortExchangeId(config.isTraceFormatterShowShortExchangeId());
+            }
+        }
+
+        if (config.getXmlRoutesReloadDirectory() != null) {
+            ReloadStrategy reload = new 
FileWatcherReloadStrategy(config.getXmlRoutesReloadDirectory());
+            camelContext.setReloadStrategy(reload);
+        }
+
+        // additional advanced configuration which is not configured using 
CamelConfigurationProperties
+        afterPropertiesSet(applicationContext, camelContext);
+
+        return camelContext;
+    }
+
+    @Bean
+    CamelSpringBootApplicationController 
applicationController(ApplicationContext applicationContext, CamelContext 
camelContext) {
+        return new CamelSpringBootApplicationController(applicationContext, 
camelContext);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(RoutesCollector.class)
+    RoutesCollector routesCollector(ApplicationContext applicationContext, 
CamelConfigurationProperties config) {
+        Collection<CamelContextConfiguration> configurations = 
applicationContext.getBeansOfType(CamelContextConfiguration.class).values();
+        return new RoutesCollector(applicationContext, new 
ArrayList<CamelContextConfiguration>(configurations), config);
+    }
+
+    /**
+     * Default fluent producer template for the bootstrapped Camel context.
+     * Create the bean lazy as it should only be created if its in-use.
+     */
+    // We explicitly declare the destroyMethod to be "" as the Spring @Bean
+    // annotation defaults to AbstractBeanDefinition.INFER_METHOD otherwise
+    // and in that case Service::close (FluentProducerTemplate implements 
Service)
+    // would be used for bean destruction. And we want Camel to handle the
+    // lifecycle.
+    @Bean(destroyMethod = "")
+    @ConditionalOnMissingBean(FluentProducerTemplate.class)
+    @Lazy
+    FluentProducerTemplate fluentProducerTemplate(CamelContext camelContext,
+                                                 CamelConfigurationProperties 
config) throws Exception {
+        final FluentProducerTemplate fluentProducerTemplate = 
camelContext.createFluentProducerTemplate(config.getProducerTemplateCacheSize());
+        // we add this fluentProducerTemplate as a Service to CamelContext so 
that it performs proper lifecycle (start and stop)
+        camelContext.addService(fluentProducerTemplate);
+        return fluentProducerTemplate;
+    }
+
+    /**
+     * Default producer template for the bootstrapped Camel context.
+     * Create the bean lazy as it should only be created if its in-use.
+     */
+    // We explicitly declare the destroyMethod to be "" as the Spring @Bean
+    // annotation defaults to AbstractBeanDefinition.INFER_METHOD otherwise
+    // and in that case Service::close (ProducerTemplate implements Service)
+    // would be used for bean destruction. And we want Camel to handle the
+    // lifecycle.
+    @Bean(destroyMethod = "")
+    @ConditionalOnMissingBean(ProducerTemplate.class)
+    @Lazy
+    ProducerTemplate producerTemplate(CamelContext camelContext,
+                                      CamelConfigurationProperties config) 
throws Exception {
+        final ProducerTemplate producerTemplate = 
camelContext.createProducerTemplate(config.getProducerTemplateCacheSize());
+        // we add this producerTemplate as a Service to CamelContext so that 
it performs proper lifecycle (start and stop)
+        camelContext.addService(producerTemplate);
+        return producerTemplate;
+    }
+
+    /**
+     * Default consumer template for the bootstrapped Camel context.
+     * Create the bean lazy as it should only be created if its in-use.
+     */
+    // We explicitly declare the destroyMethod to be "" as the Spring @Bean
+    // annotation defaults to AbstractBeanDefinition.INFER_METHOD otherwise
+    // and in that case Service::close (ConsumerTemplate implements Service)
+    // would be used for bean destruction. And we want Camel to handle the
+    // lifecycle.
+    @Bean(destroyMethod = "")
+    @ConditionalOnMissingBean(ConsumerTemplate.class)
+    @Lazy
+    ConsumerTemplate consumerTemplate(CamelContext camelContext,
+                                      CamelConfigurationProperties config) 
throws Exception {
+        final ConsumerTemplate consumerTemplate = 
camelContext.createConsumerTemplate(config.getConsumerTemplateCacheSize());
+        // we add this consumerTemplate as a Service to CamelContext so that 
it performs proper lifecycle (start and stop)
+        camelContext.addService(consumerTemplate);
+        return consumerTemplate;
+    }
+
+    // SpringCamelContext integration
+
+    @Bean
+    PropertiesParser propertiesParser() {
+        return new SpringPropertiesParser();
+    }
+
+    // We explicitly declare the destroyMethod to be "" as the Spring @Bean
+    // annotation defaults to AbstractBeanDefinition.INFER_METHOD otherwise
+    // and in that case ShutdownableService::shutdown/Service::close
+    // (PropertiesComponent extends ServiceSupport) would be used for bean
+    // destruction. And we want Camel to handle the lifecycle.
+    @Bean(destroyMethod = "")
+    PropertiesComponent properties(CamelContext camelContext, PropertiesParser 
parser) {
+        if (camelContext.hasComponent("properties") != null) {
+            return camelContext.getComponent("properties", 
PropertiesComponent.class);
+        } else {
+            PropertiesComponent pc = new PropertiesComponent();
+            pc.setPropertiesParser(parser);
+            return pc;
+        }
+    }
+
+    /**
+     * Camel post processor - required to support Camel annotations.
+     */
+    @Bean
+    CamelBeanPostProcessor camelBeanPostProcessor(ApplicationContext 
applicationContext) {
+        CamelBeanPostProcessor processor = new CamelBeanPostProcessor();
+        processor.setApplicationContext(applicationContext);
+        return processor;
+    }
+
+    /**
+     * Performs additional configuration to lookup beans of Camel types to 
configure
+     * advanced configurations.
+     * <p/>
+     * Similar code in camel-core-xml module in class 
org.apache.camel.core.xml.AbstractCamelContextFactoryBean.
+     */
+    static void afterPropertiesSet(ApplicationContext applicationContext, 
CamelContext camelContext) throws Exception {
+        Tracer tracer = getSingleBeanOfType(applicationContext, Tracer.class);
+        if (tracer != null) {
+            // use formatter if there is a TraceFormatter bean defined
+            TraceFormatter formatter = getSingleBeanOfType(applicationContext, 
TraceFormatter.class);
+            if (formatter != null) {
+                tracer.setFormatter(formatter);
+            }
+            LOG.info("Using custom Tracer: {}", tracer);
+            camelContext.addInterceptStrategy(tracer);
+        }
+        BacklogTracer backlogTracer = getSingleBeanOfType(applicationContext, 
BacklogTracer.class);
+        if (backlogTracer != null) {
+            LOG.info("Using custom BacklogTracer: {}", backlogTracer);
+            camelContext.addInterceptStrategy(backlogTracer);
+        }
+        HandleFault handleFault = getSingleBeanOfType(applicationContext, 
HandleFault.class);
+        if (handleFault != null) {
+            LOG.info("Using custom HandleFault: {}", handleFault);
+            camelContext.addInterceptStrategy(handleFault);
+        }
+        InflightRepository inflightRepository = 
getSingleBeanOfType(applicationContext, InflightRepository.class);
+        if (inflightRepository != null) {
+            LOG.info("Using custom InflightRepository: {}", 
inflightRepository);
+            camelContext.setInflightRepository(inflightRepository);
+        }
+        AsyncProcessorAwaitManager asyncProcessorAwaitManager = 
getSingleBeanOfType(applicationContext, AsyncProcessorAwaitManager.class);
+        if (asyncProcessorAwaitManager != null) {
+            LOG.info("Using custom AsyncProcessorAwaitManager: {}", 
asyncProcessorAwaitManager);
+            
camelContext.setAsyncProcessorAwaitManager(asyncProcessorAwaitManager);
+        }
+        ManagementStrategy managementStrategy = 
getSingleBeanOfType(applicationContext, ManagementStrategy.class);
+        if (managementStrategy != null) {
+            LOG.info("Using custom ManagementStrategy: {}", 
managementStrategy);
+            camelContext.setManagementStrategy(managementStrategy);
+        }
+        ManagementNamingStrategy managementNamingStrategy = 
getSingleBeanOfType(applicationContext, ManagementNamingStrategy.class);
+        if (managementNamingStrategy != null) {
+            LOG.info("Using custom ManagementNamingStrategy: {}", 
managementNamingStrategy);
+            
camelContext.getManagementStrategy().setManagementNamingStrategy(managementNamingStrategy);
+        }
+        EventFactory eventFactory = getSingleBeanOfType(applicationContext, 
EventFactory.class);
+        if (eventFactory != null) {
+            LOG.info("Using custom EventFactory: {}", eventFactory);
+            camelContext.getManagementStrategy().setEventFactory(eventFactory);
+        }
+        UnitOfWorkFactory unitOfWorkFactory = 
getSingleBeanOfType(applicationContext, UnitOfWorkFactory.class);
+        if (unitOfWorkFactory != null) {
+            LOG.info("Using custom UnitOfWorkFactory: {}", unitOfWorkFactory);
+            camelContext.setUnitOfWorkFactory(unitOfWorkFactory);
+        }
+        RuntimeEndpointRegistry runtimeEndpointRegistry = 
getSingleBeanOfType(applicationContext, RuntimeEndpointRegistry.class);
+        if (runtimeEndpointRegistry != null) {
+            LOG.info("Using custom RuntimeEndpointRegistry: {}", 
runtimeEndpointRegistry);
+            camelContext.setRuntimeEndpointRegistry(runtimeEndpointRegistry);
+        }
+        // custom type converters defined as <bean>s
+        Map<String, TypeConverters> typeConverters = 
applicationContext.getBeansOfType(TypeConverters.class);
+        if (typeConverters != null && !typeConverters.isEmpty()) {
+            for (Map.Entry<String, TypeConverters> entry : 
typeConverters.entrySet()) {
+                TypeConverters converter = entry.getValue();
+                LOG.info("Adding custom TypeConverters with id: {} and 
implementation: {}", entry.getKey(), converter);
+                
camelContext.getTypeConverterRegistry().addTypeConverters(converter);
+            }
+        }
+        // set the event notifier strategies if defined
+        Map<String, EventNotifier> eventNotifiers = 
applicationContext.getBeansOfType(EventNotifier.class);
+        if (eventNotifiers != null && !eventNotifiers.isEmpty()) {
+            for (Map.Entry<String, EventNotifier> entry : 
eventNotifiers.entrySet()) {
+                EventNotifier notifier = entry.getValue();
+                // do not add if already added, for instance a tracer that is 
also an InterceptStrategy class
+                if 
(!camelContext.getManagementStrategy().getEventNotifiers().contains(notifier)) {
+                    LOG.info("Using custom EventNotifier with id: {} and 
implementation: {}", entry.getKey(), notifier);
+                    
camelContext.getManagementStrategy().addEventNotifier(notifier);
+                }
+            }
+        }
+        // set endpoint strategies if defined
+        Map<String, EndpointStrategy> endpointStrategies = 
applicationContext.getBeansOfType(EndpointStrategy.class);
+        if (endpointStrategies != null && !endpointStrategies.isEmpty()) {
+            for (Map.Entry<String, EndpointStrategy> entry : 
endpointStrategies.entrySet()) {
+                EndpointStrategy strategy = entry.getValue();
+                LOG.info("Using custom EndpointStrategy with id: {} and 
implementation: {}", entry.getKey(), strategy);
+                camelContext.addRegisterEndpointCallback(strategy);
+            }
+        }
+        // shutdown
+        ShutdownStrategy shutdownStrategy = 
getSingleBeanOfType(applicationContext, ShutdownStrategy.class);
+        if (shutdownStrategy != null) {
+            LOG.info("Using custom ShutdownStrategy: " + shutdownStrategy);
+            camelContext.setShutdownStrategy(shutdownStrategy);
+        }
+        // add global interceptors
+        Map<String, InterceptStrategy> interceptStrategies = 
applicationContext.getBeansOfType(InterceptStrategy.class);
+        if (interceptStrategies != null && !interceptStrategies.isEmpty()) {
+            for (Map.Entry<String, InterceptStrategy> entry : 
interceptStrategies.entrySet()) {
+                InterceptStrategy strategy = entry.getValue();
+                // do not add if already added, for instance a tracer that is 
also an InterceptStrategy class
+                if (!camelContext.getInterceptStrategies().contains(strategy)) 
{
+                    LOG.info("Using custom InterceptStrategy with id: {} and 
implementation: {}", entry.getKey(), strategy);
+                    camelContext.addInterceptStrategy(strategy);
+                }
+            }
+        }
+        // set the lifecycle strategy if defined
+        Map<String, LifecycleStrategy> lifecycleStrategies = 
applicationContext.getBeansOfType(LifecycleStrategy.class);
+        if (lifecycleStrategies != null && !lifecycleStrategies.isEmpty()) {
+            for (Map.Entry<String, LifecycleStrategy> entry : 
lifecycleStrategies.entrySet()) {
+                LifecycleStrategy strategy = entry.getValue();
+                // do not add if already added, for instance a tracer that is 
also an InterceptStrategy class
+                if (!camelContext.getLifecycleStrategies().contains(strategy)) 
{
+                    LOG.info("Using custom LifecycleStrategy with id: {} and 
implementation: {}", entry.getKey(), strategy);
+                    camelContext.addLifecycleStrategy(strategy);
+                }
+            }
+        }
+        // cluster service
+        CamelClusterService clusterService = 
getSingleBeanOfType(applicationContext, CamelClusterService.class);
+        if (clusterService != null) {
+            LOG.info("Using CamelClusterService: " + clusterService);
+            camelContext.addService(clusterService);
+        }
+        // add route policy factories
+        Map<String, RoutePolicyFactory> routePolicyFactories = 
applicationContext.getBeansOfType(RoutePolicyFactory.class);
+        if (routePolicyFactories != null && !routePolicyFactories.isEmpty()) {
+            for (Map.Entry<String, RoutePolicyFactory> entry : 
routePolicyFactories.entrySet()) {
+                RoutePolicyFactory factory = entry.getValue();
+                LOG.info("Using custom RoutePolicyFactory with id: {} and 
implementation: {}", entry.getKey(), factory);
+                camelContext.addRoutePolicyFactory(factory);
+            }
+        }
+        // add SSL context parameters
+        GlobalSSLContextParametersSupplier sslContextParametersSupplier = 
getSingleBeanOfType(applicationContext, 
GlobalSSLContextParametersSupplier.class);
+        if (sslContextParametersSupplier != null) {
+            
camelContext.setSSLContextParameters(sslContextParametersSupplier.get());
+        }
+
+        // Route controller
+        RouteController routeController = 
getSingleBeanOfType(applicationContext, RouteController.class);
+        if (routeController != null) {
+            LOG.info("Using RouteController: " + routeController);
+            camelContext.setRouteController(routeController);
+        }
+
+        // set the default thread pool profile if defined
+        initThreadPoolProfiles(applicationContext, camelContext);
+    }
+
+    private static void initThreadPoolProfiles(ApplicationContext 
applicationContext, CamelContext camelContext) {
+        Set<String> defaultIds = new HashSet<String>();
+
+        // lookup and use custom profiles from the registry
+        Map<String, ThreadPoolProfile> profiles = 
applicationContext.getBeansOfType(ThreadPoolProfile.class);
+        if (profiles != null && !profiles.isEmpty()) {
+            for (Map.Entry<String, ThreadPoolProfile> entry : 
profiles.entrySet()) {
+                ThreadPoolProfile profile = entry.getValue();
+                // do not add if already added, for instance a tracer that is 
also an InterceptStrategy class
+                if (profile.isDefaultProfile()) {
+                    LOG.info("Using custom default ThreadPoolProfile with id: 
{} and implementation: {}", entry.getKey(), profile);
+                    
camelContext.getExecutorServiceManager().setDefaultThreadPoolProfile(profile);
+                    defaultIds.add(entry.getKey());
+                } else {
+                    
camelContext.getExecutorServiceManager().registerThreadPoolProfile(profile);
+                }
+            }
+        }
+
+        // validate at most one is defined
+        if (defaultIds.size() > 1) {
+            throw new IllegalArgumentException("Only exactly one default 
ThreadPoolProfile is allowed, was " + defaultIds.size() + " ids: " + 
defaultIds);
+        }
+    }
+
+    private static <T> T getSingleBeanOfType(ApplicationContext 
applicationContext, Class<T> type) {
+        Map<String, T> beans = applicationContext.getBeansOfType(type);
+        if (beans.size() == 1) {
+            return beans.values().iterator().next();
+        } else {
+            return null;
+        }
+    }
+
+}

Reply via email to