You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2020/03/24 10:24:06 UTC
[camel-karaf] 01/02: Added Camel-Blueprint to camel-karaf
This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-karaf.git
commit 2e993abd008fba813dcdc17842f13870b18954d2
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Tue Mar 24 11:14:58 2020 +0100
Added Camel-Blueprint to camel-karaf
---
components/camel-blueprint/pom.xml | 561 +++++++++
.../services/org/apache/camel/other.properties | 7 +
.../src/generated/resources/blueprint.json | 14 +
.../org/apache/camel/blueprint/jaxb.index | 13 +
.../org/apache/camel/util/blueprint/jaxb.index | 6 +
.../camel-blueprint/src/main/docs/blueprint.adoc | 45 +
.../camel/blueprint/BlueprintCamelContext.java | 290 +++++
.../BlueprintCamelContextLookupHelper.java | 57 +
.../blueprint/BlueprintCamelStateService.java | 164 +++
.../blueprint/BlueprintComponentResolver.java | 72 ++
.../BlueprintContainerBeanRepository.java | 123 ++
.../blueprint/BlueprintDataFormatResolver.java | 62 +
.../camel/blueprint/BlueprintLanguageResolver.java | 49 +
.../BlueprintModelJAXBContextFactory.java | 66 ++
.../camel/blueprint/BlueprintPropertiesSource.java | 156 +++
.../CamelConsumerTemplateFactoryBean.java | 65 +
.../camel/blueprint/CamelContextFactoryBean.java | 979 +++++++++++++++
.../camel/blueprint/CamelEndpointFactoryBean.java | 65 +
.../blueprint/CamelErrorHandlerFactoryBean.java | 144 +++
.../CamelFluentProducerTemplateFactoryBean.java | 65 +
.../CamelProducerTemplateFactoryBean.java | 65 +
.../camel/blueprint/CamelProxyFactoryBean.java | 190 +++
.../CamelRedeliveryPolicyFactoryBean.java | 65 +
.../blueprint/CamelRestContextFactoryBean.java | 41 +
.../blueprint/CamelRouteContextFactoryBean.java | 41 +
.../blueprint/CamelThreadPoolFactoryBean.java | 64 +
.../blueprint/ContextScanRouteBuilderFinder.java | 89 ++
.../apache/camel/blueprint/ErrorHandlerType.java | 54 +
.../camel/blueprint/KarafBundleStateService.java | 95 ++
.../blueprint/PackageScanRouteBuilderFinder.java | 110 ++
.../blueprint/handler/CamelNamespaceHandler.java | 1243 ++++++++++++++++++++
.../org/apache/camel/blueprint/package-info.java | 18 +
.../KeyManagersParametersFactoryBean.java | 68 ++
.../blueprint/KeyStoreParametersFactoryBean.java | 59 +
.../SSLContextClientParametersFactoryBean.java | 59 +
.../blueprint/SSLContextParametersFactoryBean.java | 110 ++
.../SSLContextServerParametersFactoryBean.java | 59 +
.../SecureRandomParametersFactoryBean.java | 59 +
.../TrustManagersParametersFactoryBean.java | 68 ++
.../apache/camel/util/blueprint/package-info.java | 19 +
.../OSGI-INF/blueprint/camel-blueprint.xml | 34 +
.../blueprint/BlueprintComponentResolverTest.java | 113 ++
.../camel/blueprint/BlueprintJaxbRestTest.java | 75 ++
.../apache/camel/blueprint/BlueprintJaxbTest.java | 65 +
.../src/test/resources/log4j2.properties | 28 +
.../src/test/resources/test-rest.xml | 42 +
.../camel-blueprint/src/test/resources/test.xml | 30 +
components/pom.xml | 1 +
48 files changed, 5967 insertions(+)
diff --git a/components/camel-blueprint/pom.xml b/components/camel-blueprint/pom.xml
new file mode 100644
index 0000000..bd42028
--- /dev/null
+++ b/components/camel-blueprint/pom.xml
@@ -0,0 +1,561 @@
+<?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.karaf</groupId>
+ <artifactId>components</artifactId>
+ <version>3.2.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-blueprint</artifactId>
+ <packaging>jar</packaging>
+
+ <name>Camel :: Blueprint</name>
+ <description>Using Camel with OSGi Blueprint</description>
+
+ <properties>
+ <firstVersion>2.4.0</firstVersion>
+ <label>java,osgi</label>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-engine</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-xml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-osgi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-xml-jaxp</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-xml-jaxb</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-bean</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.cmpn</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries</groupId>
+ <artifactId>org.apache.aries.util</artifactId>
+ <version>${aries-util-version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.karaf.bundle</groupId>
+ <artifactId>org.apache.karaf.bundle.core</artifactId>
+ <version>${karaf4-version}</version>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+
+ <!-- for testing -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>target/schema</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ <excludes>
+ <exclude>**/*.class</exclude>
+ </excludes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ </resources>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-blueprint</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ <overWrite>false</overWrite>
+ <outputDirectory>${project.build.directory}/schema</outputDirectory>
+ <includes>camel-blueprint.xsd</includes>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </plugin>
+ <!-- Eclipse m2e Lifecycle Management -->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>${lifecycle-mapping-version}</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <versionRange>${maven-antrun-plugin-version}</versionRange>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore/>
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-package-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>jaxb-list</id>
+ <goals>
+ <goal>generate-jaxb-list</goal>
+ </goals>
+ <phase>process-classes</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-generated-resources-jaxb</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>process-classes</phase>
+ <configuration>
+ <resources>
+ <resource>
+ <directory>${basedir}/target/generated/camel/jaxb</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- enrich the schemas with documentation -->
+ <plugin>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-eip-documentation-enricher-maven-plugin</artifactId>
+ <version>${project.version}</version>
+ <executions>
+ <execution>
+ <id>eip-documentation-enricher</id>
+ <!-- need to run earlier so we use the process-test-resources phase -->
+ <phase>process-test-resources</phase>
+ <goals>
+ <goal>eip-documentation-enricher</goal>
+ </goals>
+ <configuration>
+ <inputCamelSchemaFile>${project.build.directory}/schema/schema1.xsd</inputCamelSchemaFile>
+ <outputCamelSchemaFile>${project.build.directory}/schema/camel-blueprint.xsd
+ </outputCamelSchemaFile>
+ <deleteFilesAfterRun>
+ ${project.build.directory}/schema/schema1.xsd,${project.build.directory}/schema/schema2.xsd
+ </deleteFilesAfterRun>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Push the execution order of the maven-bundle-plugin further to the end. That's why we add it here again. -->
+ <plugin>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-bundle-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>bundle-manifest</id>
+ <phase>prepare-package</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>jaxb2-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-schema</id>
+ <phase>generate-test-sources</phase>
+ <goals>
+ <goal>schemagen</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <outputDirectory>${project.build.directory}/schema</outputDirectory>
+ <sources>
+ <source>${project.build.directory}/schema-src</source>
+ </sources>
+ <createJavaDocAnnotations>false</createJavaDocAnnotations>
+ <schemaSourceExcludeFilters>
+ <filter implementation="org.codehaus.mojo.jaxb2.shared.filters.pattern.PatternFileFilter">
+ <patterns>
+ <pattern>Helper.java</pattern>
+ <pattern>Adapter.java</pattern>
+ </patterns>
+ </filter>
+ </schemaSourceExcludeFilters>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <links>
+ <link>http://download.oracle.com/javase/7/docs/api/</link>
+ <link>http://download.oracle.com/javaee/7/api/</link>
+ <link>http://static.springsource.org/spring/docs/${spring-version}/javadoc-api/</link>
+ </links>
+ <stylesheetfile>${basedir}/../../etc/css/stylesheet.css</stylesheetfile>
+ <linksource>true</linksource>
+ <maxmemory>256m</maxmemory>
+ <source>${jdk.version}</source>
+ <groups>
+ <group>
+ <title>Camel Blueprint Classes</title>
+ <packages>org.apache.camel.blueprint</packages>
+ </group>
+ </groups>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+
+ <profiles>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>package</id>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <links>
+ <link>http://download.oracle.com/javase/6/docs/api/</link>
+ <link>http://download.oracle.com/javaee/6/api/</link>
+ </links>
+ <stylesheetfile>${basedir}/../../etc/css/stylesheet.css</stylesheetfile>
+ <linksource>true</linksource>
+ <source>${jdk.version}</source>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <!-- XML XSD schema generator -->
+ <profile>
+ <id>enable-schemagen</id>
+ <activation>
+ <property>
+ <name>!disable-schemagen</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <!-- unpack sources which are needed for the scheme generator -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>3.1.2</version>
+ <executions>
+ <execution>
+ <id>process-sources</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-api</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ <classifier>sources</classifier>
+ <overWrite>true</overWrite>
+ <outputDirectory>target/sources/camel-api</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-engine</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ <classifier>sources</classifier>
+ <overWrite>true</overWrite>
+ <outputDirectory>target/sources/camel-core-engine</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-xml</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ <classifier>sources</classifier>
+ <overWrite>true</overWrite>
+ <outputDirectory>target/sources/camel-core-xml</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-util</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ <classifier>sources</classifier>
+ <overWrite>true</overWrite>
+ <outputDirectory>target/sources/camel-util</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ <classifier>sources</classifier>
+ <overWrite>true</overWrite>
+ <outputDirectory>target/sources/camel-spring</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.8</version>
+ <inherited>true</inherited>
+ <executions>
+ <execution>
+ <id>process-sources</id>
+ <phase>process-classes</phase>
+ <configuration>
+ <target>
+ <taskdef resource="net/sf/antcontrib/antcontrib.properties"
+ classpathref="maven.plugin.classpath"/>
+ <echo>Copying to code together for the XSD generation</echo>
+ <mkdir dir="${project.build.directory}/schema-src"/>
+ <mkdir dir="${project.build.directory}/schema"/>
+ <mkdir dir="${project.build.directory}/schema/META-INF/JAXB"/>
+ <copy todir="${project.build.directory}/schema-src">
+ <fileset dir="${basedir}/src/main/java">
+ <include name="org/apache/camel/blueprint/Camel*.java"/>
+ <include name="org/apache/camel/blueprint/ErrorHandler*.java"/>
+ <include name="org/apache/camel/blueprint/package-info.java"/>
+ <include name="org/apache/camel/util/blueprint/**/*.java"/>
+ </fileset>
+ <fileset dir="${project.build.directory}/sources/camel-core-xml">
+ <include name="org/apache/camel/core/xml/*.java"/>
+ <include name="org/apache/camel/core/xml/util/**/*.java"/>
+ <exclude name="org/apache/camel/core/xml/CamelProxyFactoryDefinition.java"/>
+ </fileset>
+ <fileset dir="${project.build.directory}/sources/camel-api">
+ <include name="org/apache/camel/ExchangePattern.java"/>
+ <include name="org/apache/camel/LoggingLevel.java"/>
+ <include name="org/apache/camel/ManagementStatisticsLevel.java"/>
+ <include name="org/apache/camel/ShutdownRoute.java"/>
+ <include name="org/apache/camel/ShutdownRunningTask.java"/>
+ <include name="org/apache/camel/WaitForTaskToComplete.java"/>
+ </fileset>
+ <fileset dir="${project.build.directory}/sources/camel-core-engine">
+ <include name="org/apache/camel/model/**/*.java"/>
+ <include name="org/apache/camel/package-info.java"/>
+ </fileset>
+ <fileset dir="${project.build.directory}/sources/camel-util">
+ <include name="org/apache/camel/util/concurrent/ThreadPoolRejectedPolicy.java"/>
+ </fileset>
+ </copy>
+ </target>
+ <exportAntProperties>true</exportAntProperties>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <!-- after the eip-documentation-enricher we need to copy some schema files -->
+ <execution>
+ <id>include-schemas</id>
+ <phase>prepare-package</phase>
+ <configuration>
+ <target>
+ <echo>Copying XSD schema to be included in JAR</echo>
+ <replace file="${project.build.directory}/schema/camel-blueprint.xsd"
+ token="xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema""
+ value="xs:schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema""/>
+ <replace file="${project.build.directory}/schema/camel-blueprint.xsd"
+ token="http://camel.apache.org/schema/spring"
+ value="http://camel.apache.org/schema/blueprint"/>
+ <copy todir="${project.build.directory}/classes">
+ <fileset dir="${project.build.directory}/schema">
+ <exclude name="**/*.class"/>
+ </fileset>
+ </copy>
+ <!-- copy modified schemas back again in classes so they are included in the JAR -->
+ <fileset dir="${project.build.directory}/schema">
+ <exclude name="**/*.class"/>
+ </fileset>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <!-- Bypass the schemagen plugin on HP and IBM JDKs. -->
+ <id>on-ibmjdk</id>
+ <activation>
+ <property>
+ <name>java.vendor</name>
+ <value>IBM Corporation</value>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <!-- Bypass the schemagen plugin on HP and IBM JDKs. -->
+ <id>on-hpjdk</id>
+ <activation>
+ <property>
+ <name>java.vendor</name>
+ <value>Hewlett-Packard Co.</value>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/components/camel-blueprint/src/generated/resources/META-INF/services/org/apache/camel/other.properties b/components/camel-blueprint/src/generated/resources/META-INF/services/org/apache/camel/other.properties
new file mode 100644
index 0000000..fe9ebfd
--- /dev/null
+++ b/components/camel-blueprint/src/generated/resources/META-INF/services/org/apache/camel/other.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+name=blueprint
+groupId=org.apache.camel.karaf
+artifactId=camel-blueprint
+version=3.2.0-SNAPSHOT
+projectName=Camel :: Blueprint
+projectDescription=Using Camel with OSGi Blueprint
diff --git a/components/camel-blueprint/src/generated/resources/blueprint.json b/components/camel-blueprint/src/generated/resources/blueprint.json
new file mode 100644
index 0000000..32d13e4
--- /dev/null
+++ b/components/camel-blueprint/src/generated/resources/blueprint.json
@@ -0,0 +1,14 @@
+{
+ "other": {
+ "kind": "other",
+ "name": "blueprint",
+ "title": "Blueprint",
+ "description": "Using Camel with OSGi Blueprint",
+ "deprecated": false,
+ "firstVersion": "2.4.0",
+ "label": "java,osgi",
+ "groupId": "org.apache.camel.karaf",
+ "artifactId": "camel-blueprint",
+ "version": "3.2.0-SNAPSHOT"
+ }
+}
diff --git a/components/camel-blueprint/src/generated/resources/org/apache/camel/blueprint/jaxb.index b/components/camel-blueprint/src/generated/resources/org/apache/camel/blueprint/jaxb.index
new file mode 100644
index 0000000..3ab0ca9
--- /dev/null
+++ b/components/camel-blueprint/src/generated/resources/org/apache/camel/blueprint/jaxb.index
@@ -0,0 +1,13 @@
+# Generated by camel build tools - do NOT edit this file!
+CamelConsumerTemplateFactoryBean
+CamelContextFactoryBean
+CamelEndpointFactoryBean
+CamelErrorHandlerFactoryBean
+CamelFluentProducerTemplateFactoryBean
+CamelProducerTemplateFactoryBean
+CamelProxyFactoryBean
+CamelRedeliveryPolicyFactoryBean
+CamelRestContextFactoryBean
+CamelRouteContextFactoryBean
+CamelThreadPoolFactoryBean
+ErrorHandlerType
diff --git a/components/camel-blueprint/src/generated/resources/org/apache/camel/util/blueprint/jaxb.index b/components/camel-blueprint/src/generated/resources/org/apache/camel/util/blueprint/jaxb.index
new file mode 100644
index 0000000..b0d65ff
--- /dev/null
+++ b/components/camel-blueprint/src/generated/resources/org/apache/camel/util/blueprint/jaxb.index
@@ -0,0 +1,6 @@
+# Generated by camel build tools - do NOT edit this file!
+KeyStoreParametersFactoryBean
+SSLContextClientParametersFactoryBean
+SSLContextParametersFactoryBean
+SSLContextServerParametersFactoryBean
+SecureRandomParametersFactoryBean
diff --git a/components/camel-blueprint/src/main/docs/blueprint.adoc b/components/camel-blueprint/src/main/docs/blueprint.adoc
new file mode 100644
index 0000000..c17b0e0
--- /dev/null
+++ b/components/camel-blueprint/src/main/docs/blueprint.adoc
@@ -0,0 +1,45 @@
+= Using OSGi blueprint with Camel
+
+A custom XML namespace for Blueprint has been created to let you leverage the nice XML dialect.
+Given Blueprint custom namespaces are not standardized yet, this namespace can only be used on the Apache Aries Blueprint
+implementation, which is the one used by Apache Karaf.
+
+== Overview
+
+The XML schema is mostly the same as the one for Spring, so all the XML snippets throughout the documentation
+referring to Spring XML also apply to Blueprint routes.
+
+Here is a very simple route definition using Blueprint:
+
+[source,xml]
+----
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+ <camelContext xmlns="http://camel.apache.org/schema/blueprint">
+ <route>
+ <from uri="timer:test" />
+ <to uri="log:test" />
+ </route>
+ </camelContext>
+
+</blueprint>
+----
+
+There are a few limitations at this point about the supported xml elements (compared to the Spring XML syntax):
+
+- `beanPostProcessor` and `<export>` are specific to Spring and are not in use
+
+However, using Blueprint when you deploy your applications in an OSGi environment has several advantages:
+
+- when upgrading to a new Camel version, you don't have to change the namespace, as the correct version will be
+ selected based on the Camel packages that are imported by your bundle
+- no startup ordering issue with respect to the custom namespaces and your bundles
+- you can use Blueprint property placeholders
+
+
+== Using camel-blueprint
+
+To leverage camel-blueprint in OSGi, you only need the Aries Blueprint bundle and the camel-blueprint bundle,
+in addition to camel-core-xml and its dependencies.
+
+If you use Karaf, you can use the feature named camel-blueprint which will install all the required bundles.
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContext.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContext.java
new file mode 100644
index 0000000..e9fcf46
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContext.java
@@ -0,0 +1,290 @@
+/*
+ * 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.blueprint;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.camel.TypeConverter;
+import org.apache.camel.blueprint.handler.CamelNamespaceHandler;
+import org.apache.camel.core.osgi.OsgiBeanRepository;
+import org.apache.camel.core.osgi.OsgiCamelContextHelper;
+import org.apache.camel.core.osgi.OsgiCamelContextPublisher;
+import org.apache.camel.core.osgi.OsgiFactoryFinderResolver;
+import org.apache.camel.core.osgi.OsgiTypeConverter;
+import org.apache.camel.core.osgi.utils.BundleContextUtils;
+import org.apache.camel.core.osgi.utils.BundleDelegatingClassLoader;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.BeanRepository;
+import org.apache.camel.spi.EventNotifier;
+import org.apache.camel.spi.FactoryFinder;
+import org.apache.camel.spi.ModelJAXBContextFactory;
+import org.apache.camel.support.DefaultRegistry;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.container.BlueprintEvent;
+import org.osgi.service.blueprint.container.BlueprintListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OSGi Blueprint based {@link org.apache.camel.CamelContext}.
+ */
+public class BlueprintCamelContext extends DefaultCamelContext implements ServiceListener, BlueprintListener {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BlueprintCamelContext.class);
+
+ protected final AtomicBoolean routeDefinitionValid = new AtomicBoolean(true);
+
+ private BundleContext bundleContext;
+ private BlueprintContainer blueprintContainer;
+ private ServiceRegistration<?> registration;
+ private BlueprintCamelStateService bundleStateService;
+
+ public BlueprintCamelContext(BundleContext bundleContext, BlueprintContainer blueprintContainer) {
+ super(false);
+ this.bundleContext = bundleContext;
+ this.blueprintContainer = blueprintContainer;
+
+ // inject common osgi
+ OsgiCamelContextHelper.osgiUpdate(this, bundleContext);
+
+ // and these are blueprint specific
+ BeanRepository repo1 = new BlueprintContainerBeanRepository(getBlueprintContainer());
+ OsgiBeanRepository repo2 = new OsgiBeanRepository(bundleContext);
+ setRegistry(new DefaultRegistry(repo1, repo2));
+ // Need to clean up the OSGi service when camel context is closed.
+ addLifecycleStrategy(repo2);
+
+ setComponentResolver(new BlueprintComponentResolver(bundleContext));
+ setLanguageResolver(new BlueprintLanguageResolver(bundleContext));
+ setDataFormatResolver(new BlueprintDataFormatResolver(bundleContext));
+ setApplicationContextClassLoader(new BundleDelegatingClassLoader(bundleContext.getBundle()));
+ init();
+ }
+
+ @Override
+ protected ModelJAXBContextFactory createModelJAXBContextFactory() {
+ // must use classloader of the namespace handler
+ return new BlueprintModelJAXBContextFactory(CamelNamespaceHandler.class.getClassLoader());
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public BlueprintContainer getBlueprintContainer() {
+ return blueprintContainer;
+ }
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ public BlueprintCamelStateService getBundleStateService() {
+ return bundleStateService;
+ }
+
+ public void setBundleStateService(BlueprintCamelStateService bundleStateService) {
+ this.bundleStateService = bundleStateService;
+ }
+
+ @Override
+ public void doInit() throws Exception {
+ LOG.trace("init {}", this);
+ // add service listener so we can be notified when blueprint container is done
+ // and we would be ready to start CamelContext
+ bundleContext.addServiceListener(this);
+ // add blueprint listener as service, as we need this for the blueprint container
+ // to support change events when it changes states
+ registration = bundleContext.registerService(BlueprintListener.class, this, null);
+ // call super
+ super.doInit();
+ }
+
+ public void destroy() throws Exception {
+ LOG.trace("destroy {}", this);
+
+ // remove listener and stop this CamelContext
+ try {
+ bundleContext.removeServiceListener(this);
+ } catch (Exception e) {
+ LOG.warn("Error removing ServiceListener: " + this + ". This exception is ignored.", e);
+ }
+ if (registration != null) {
+ try {
+ registration.unregister();
+ } catch (Exception e) {
+ LOG.warn("Error unregistering service registration: " + registration + ". This exception is ignored.", e);
+ }
+ registration = null;
+ }
+ bundleStateService.setBundleState(bundleContext.getBundle(), this.getName(), null);
+
+ // must stop Camel
+ stop();
+ }
+
+ @Override
+ public void blueprintEvent(BlueprintEvent event) {
+ if (LOG.isDebugEnabled()) {
+ String eventTypeString;
+
+ switch (event.getType()) {
+ case BlueprintEvent.CREATING:
+ eventTypeString = "CREATING";
+ break;
+ case BlueprintEvent.CREATED:
+ eventTypeString = "CREATED";
+ break;
+ case BlueprintEvent.DESTROYING:
+ eventTypeString = "DESTROYING";
+ break;
+ case BlueprintEvent.DESTROYED:
+ eventTypeString = "DESTROYED";
+ break;
+ case BlueprintEvent.GRACE_PERIOD:
+ eventTypeString = "GRACE_PERIOD";
+ break;
+ case BlueprintEvent.WAITING:
+ eventTypeString = "WAITING";
+ break;
+ case BlueprintEvent.FAILURE:
+ eventTypeString = "FAILURE";
+ break;
+ default:
+ eventTypeString = "UNKNOWN";
+ break;
+ }
+
+ LOG.debug("Received BlueprintEvent[replay={} type={} bundle={}] {}", event.isReplay(), eventTypeString, event.getBundle().getSymbolicName(), event);
+ }
+
+ if (!event.isReplay() && this.getBundleContext().getBundle().getBundleId() == event.getBundle().getBundleId()) {
+ if (event.getType() == BlueprintEvent.CREATED) {
+ try {
+ LOG.info("Attempting to start CamelContext: {}", this.getName());
+ this.maybeStart();
+ } catch (Exception startEx) {
+ LOG.error("Error occurred during starting CamelContext: {}", this.getName(), startEx);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void serviceChanged(ServiceEvent event) {
+ if (LOG.isTraceEnabled()) {
+ String eventTypeString;
+
+ switch (event.getType()) {
+ case ServiceEvent.REGISTERED:
+ eventTypeString = "REGISTERED";
+ break;
+ case ServiceEvent.MODIFIED:
+ eventTypeString = "MODIFIED";
+ break;
+ case ServiceEvent.UNREGISTERING:
+ eventTypeString = "UNREGISTERING";
+ break;
+ case ServiceEvent.MODIFIED_ENDMATCH:
+ eventTypeString = "MODIFIED_ENDMATCH";
+ break;
+ default:
+ eventTypeString = "UNKNOWN";
+ break;
+ }
+
+ // use trace logging as this is very noisy
+ LOG.trace("Service: {} changed to: {}", event, eventTypeString);
+ }
+ }
+
+ @Override
+ protected TypeConverter createTypeConverter() {
+ // CAMEL-3614: make sure we use a bundle context which imports org.apache.camel.impl.converter package
+ BundleContext ctx = BundleContextUtils.getBundleContext(getClass());
+ if (ctx == null) {
+ ctx = bundleContext;
+ }
+ FactoryFinder finder = new OsgiFactoryFinderResolver(bundleContext).resolveDefaultFactoryFinder(getClassResolver());
+ return new OsgiTypeConverter(ctx, this, getInjector(), finder);
+ }
+
+ @Override
+ public void start() {
+ final ClassLoader original = Thread.currentThread().getContextClassLoader();
+ try {
+ // let's set a more suitable TCCL while starting the context
+ Thread.currentThread().setContextClassLoader(getApplicationContextClassLoader());
+ bundleStateService.setBundleState(bundleContext.getBundle(), this.getName(), BlueprintCamelStateService.State.Starting);
+ super.start();
+ bundleStateService.setBundleState(bundleContext.getBundle(), this.getName(), BlueprintCamelStateService.State.Active);
+ } catch (Exception e) {
+ bundleStateService.setBundleState(bundleContext.getBundle(), this.getName(), BlueprintCamelStateService.State.Failure, e);
+ routeDefinitionValid.set(false);
+ throw e;
+ } finally {
+ Thread.currentThread().setContextClassLoader(original);
+ }
+ }
+
+ private void maybeStart() throws Exception {
+ LOG.trace("maybeStart: {}", this);
+
+ if (!routeDefinitionValid.get()) {
+ LOG.trace("maybeStart: {} is skipping since CamelRoute definition is not correct.", this);
+ return;
+ }
+
+ // allow to register the BluerintCamelContext eager in the OSGi Service Registry, which ex is needed
+ // for unit testing with camel-test-blueprint
+ boolean eager = "true".equalsIgnoreCase(System.getProperty("registerBlueprintCamelContextEager"));
+ if (eager) {
+ for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) {
+ if (notifier instanceof OsgiCamelContextPublisher) {
+ OsgiCamelContextPublisher publisher = (OsgiCamelContextPublisher) notifier;
+ publisher.registerCamelContext(this);
+ break;
+ }
+ }
+ }
+
+ // for example from unit testing we want to start Camel later and not
+ // when blueprint loading the bundle
+ boolean skip = "true".equalsIgnoreCase(System.getProperty("skipStartingCamelContext"));
+ if (skip) {
+ LOG.trace("maybeStart: {} is skipping as System property skipStartingCamelContext is set", this);
+ return;
+ }
+
+ if (!isStarted() && !isStarting()) {
+ LOG.debug("Starting {}", this);
+ start();
+ } else {
+ // ignore as Camel is already started
+ LOG.trace("Ignoring maybeStart() as {} is already started", this);
+ }
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContextLookupHelper.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContextLookupHelper.java
new file mode 100644
index 0000000..29c932d
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContextLookupHelper.java
@@ -0,0 +1,57 @@
+/*
+ * 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.blueprint;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+
+/**
+ * A helper class to find the ids of the {@link BlueprintCamelContext} defined
+ * in the {@link org.osgi.service.blueprint.container.BlueprintContainer}
+ */
+public final class BlueprintCamelContextLookupHelper {
+
+ private BlueprintCamelContextLookupHelper() {
+ }
+
+ /**
+ * Lookup all the {@link BlueprintCamelContext} in the {@link BlueprintContainer}.
+ *
+ * @param container the blueprint container, must be provided
+ * @return a set with the ids of the {@link BlueprintCamelContext}, never <tt>null</tt>, but can be empty set.
+ */
+ public static Set<String> lookupBlueprintCamelContext(BlueprintContainer container) {
+ Set<String> ids = new LinkedHashSet<>();
+ for (Object id : container.getComponentIds()) {
+ ComponentMetadata meta = container.getComponentMetadata(id.toString());
+
+ // must be extended meta, to see if its the blueprint camel context
+ if (meta instanceof ExtendedBeanMetadata) {
+ Class<?> clazz = ((ExtendedBeanMetadata) meta).getRuntimeClass();
+ if (clazz != null && BlueprintCamelContext.class.isAssignableFrom(clazz)) {
+ // okay we found a BlueprintCamelContext
+ ids.add(meta.getId());
+ }
+ }
+ }
+ return ids;
+ }
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelStateService.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelStateService.java
new file mode 100644
index 0000000..8569f76
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelStateService.java
@@ -0,0 +1,164 @@
+/*
+ * 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.blueprint;
+
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Used by {@link BlueprintCamelContext} to inform about state of Camel context. If running inside Karaf
+ * and Karaf's BundleStateService is accessible, Camel context state will propagate as <em>extended
+ * bundle state</em>.
+ */
+public class BlueprintCamelStateService {
+
+ public static final Logger LOG = LoggerFactory.getLogger(BlueprintCamelStateService.class);
+
+ public enum State {
+ Starting,
+ Active,
+ Failure
+ }
+
+ private Map<String, State> states;
+ private Map<String, Throwable> exceptions;
+
+ private BundleContext bundleContext;
+
+ private ServiceRegistration<?> registration;
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ /**
+ * One of four {@link State states} is set for given {@link org.osgi.framework.Bundle} and context Id.
+ * One (blueprint) bundle may declare one or more Camel context.
+ * @param contextId
+ * @param state
+ */
+ public void setBundleState(Bundle bundle, String contextId, State state) {
+ setBundleState(bundle, contextId, state, null);
+ }
+
+ /**
+ * One of four {@link State states} is set for given {@link org.osgi.framework.Bundle} and context Id.
+ * One (blueprint) bundle may declare one or more Camel context.
+ * @param contextId
+ * @param state
+ * @param t
+ */
+ public void setBundleState(Bundle bundle, String contextId, State state, Throwable t) {
+ if (state == State.Failure) {
+ LOG.warn("Changing Camel state for bundle {} to {}", bundle.getBundleId(), state);
+ } else if (LOG.isDebugEnabled()) {
+ LOG.debug("Changing Camel state for bundle {} to {}", bundle.getBundleId(), state);
+ }
+
+ String key = String.format("%d:%s", bundle.getBundleId(), contextId);
+ if (state != null) {
+ states.put(key, state);
+ } else {
+ states.remove(key);
+ }
+ if (t != null) {
+ exceptions.put(key, t);
+ } else {
+ exceptions.remove(key);
+ }
+ }
+
+ /**
+ * Get states for all context registered for given {@link Bundle}
+ * @param bundle
+ * @return
+ */
+ public List<State> getStates(Bundle bundle) {
+ List<State> result = new LinkedList<>();
+ for (Map.Entry<String, State> e : states.entrySet()) {
+ if (e.getKey().startsWith(bundle.getBundleId() + ":")) {
+ result.add(e.getValue());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get exceptions for all camel contexts for given bundle
+ * @param bundle
+ * @return
+ */
+ public Map<String, Throwable> getExceptions(Bundle bundle) {
+ Map<String, Throwable> result = new LinkedHashMap<>();
+ for (Map.Entry<String, Throwable> e : exceptions.entrySet()) {
+ if (e.getKey().startsWith(bundle.getBundleId() + ":")) {
+ result.put(e.getKey().substring(e.getKey().indexOf(":") + 1), e.getValue());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Attempts to register Karaf-specific BundleStateService - if possible
+ */
+ public void init() {
+ try {
+ states = new ConcurrentHashMap<>();
+ exceptions = new ConcurrentHashMap<>();
+
+ registration = new KarafBundleStateServiceCreator().create(bundleContext, this);
+ } catch (NoClassDefFoundError e) {
+ LOG.info("Karaf BundleStateService not accessible. Bundle state won't reflect Camel context state");
+ }
+ }
+
+ /**
+ * Unregisters any OSGi service registered
+ */
+ public void destroy() {
+ if (registration != null) {
+ registration.unregister();
+ }
+ states.clear();
+ states = null;
+ exceptions.clear();
+ exceptions = null;
+ }
+
+ /**
+ * Static creator to decouple from optional Karaf classes.
+ */
+ private static class KarafBundleStateServiceCreator {
+ public ServiceRegistration<?> create(BundleContext context, BlueprintCamelStateService camelStateService) {
+ KarafBundleStateService karafBundleStateService = new KarafBundleStateService(camelStateService);
+ return karafBundleStateService.register(context);
+ }
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintComponentResolver.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintComponentResolver.java
new file mode 100644
index 0000000..02b32f7
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintComponentResolver.java
@@ -0,0 +1,72 @@
+/*
+ * 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.blueprint;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.core.osgi.OsgiComponentResolver;
+import org.apache.camel.spi.ComponentResolver;
+import org.apache.camel.support.ResolverHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.container.NoSuchComponentException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.camel.util.ObjectHelper.getException;
+
+public class BlueprintComponentResolver extends OsgiComponentResolver {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BlueprintComponentResolver.class);
+
+ public BlueprintComponentResolver(BundleContext bundleContext) {
+ super(bundleContext);
+ }
+
+ @Override
+ public Component resolveComponent(String name, CamelContext context) throws Exception {
+
+ Component componentReg = ResolverHelper.lookupComponentInRegistryWithFallback(context, name, new ResolverHelper.LookupExceptionHandler() {
+ @Override
+ public void handleException(Exception e, Logger log, String name) {
+ if (getException(NoSuchComponentException.class, e) != null) {
+ // if the caused error is NoSuchComponentException then that can be expected so ignore
+ } else if (getException(ComponentDefinitionException.class, e) != null) {
+ LOG.warn("Problem looking up bean: " + name + " due: " + e.getMessage(), e);
+ } else {
+ LOG.trace("Ignored error looking up bean: " + name + " due: " + e.getMessage(), e);
+ }
+ }
+ });
+
+ if (componentReg != null) {
+ return componentReg;
+ }
+
+ try {
+ Object bean = context.getRegistry().lookupByName(".camelBlueprint.componentResolver." + name);
+ if (bean instanceof ComponentResolver) {
+ LOG.debug("Found component resolver: {} in registry: {}", name, bean);
+ return ((ComponentResolver) bean).resolveComponent(name, context);
+ }
+ } catch (Exception e) {
+ LOG.trace("Ignored error looking up bean: " + name + " due: " + e.getMessage(), e);
+ }
+ return getComponent(name, context);
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintContainerBeanRepository.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintContainerBeanRepository.java
new file mode 100644
index 0000000..8c32a62
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintContainerBeanRepository.java
@@ -0,0 +1,123 @@
+/*
+ * 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.blueprint;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.NoSuchBeanException;
+import org.apache.camel.spi.BeanRepository;
+import org.osgi.framework.Bundle;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.container.NoSuchComponentException;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+
+public class BlueprintContainerBeanRepository implements BeanRepository {
+
+ private final BlueprintContainer blueprintContainer;
+
+ public BlueprintContainerBeanRepository(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ public Object lookupByName(String name) {
+ try {
+ return blueprintContainer.getComponentInstance(name);
+ } catch (NoSuchComponentException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public <T> T lookupByNameAndType(String name, Class<T> type) {
+ Object answer;
+ try {
+ answer = blueprintContainer.getComponentInstance(name);
+ } catch (NoSuchComponentException e) {
+ return null;
+ }
+
+ // just to be safe
+ if (answer == null) {
+ return null;
+ }
+
+ try {
+ return type.cast(answer);
+ } catch (Throwable e) {
+ String msg = "Found bean: " + name + " in BlueprintContainer: " + blueprintContainer
+ + " of type: " + answer.getClass().getName() + " expected type was: " + type;
+ throw new NoSuchBeanException(name, msg, e);
+ }
+ }
+
+ @Override
+ public <T> Map<String, T> findByTypeWithName(Class<T> type) {
+ return lookupByType(blueprintContainer, type);
+ }
+
+ @Override
+ public <T> Set<T> findByType(Class<T> type) {
+ Map<String, T> map = lookupByType(blueprintContainer, type);
+ return new HashSet<>(map.values());
+ }
+
+ public static <T> Map<String, T> lookupByType(BlueprintContainer blueprintContainer, Class<T> type) {
+ return lookupByType(blueprintContainer, type, true);
+ }
+
+ public static <T> Map<String, T> lookupByType(BlueprintContainer blueprintContainer, Class<T> type, boolean includeNonSingletons) {
+ Bundle bundle = (Bundle) blueprintContainer.getComponentInstance("blueprintBundle");
+ Map<String, T> objects = new LinkedHashMap<>();
+ Set<String> ids = blueprintContainer.getComponentIds();
+ for (String id : ids) {
+ try {
+ ComponentMetadata metadata = blueprintContainer.getComponentMetadata(id);
+ Class<?> cl = null;
+ if (metadata instanceof BeanMetadata) {
+ BeanMetadata beanMetadata = (BeanMetadata)metadata;
+ // should we skip the bean if its prototype and we are only looking for singletons?
+ if (!includeNonSingletons) {
+ String scope = beanMetadata.getScope();
+ if (BeanMetadata.SCOPE_PROTOTYPE.equals(scope)) {
+ continue;
+ }
+ }
+ String clazz = beanMetadata.getClassName();
+ if (clazz != null) {
+ cl = bundle.loadClass(clazz);
+ }
+ } else if (metadata instanceof ReferenceMetadata) {
+ ReferenceMetadata referenceMetadata = (ReferenceMetadata)metadata;
+ cl = bundle.loadClass(referenceMetadata.getInterface());
+ }
+ if (cl != null && type.isAssignableFrom(cl)) {
+ Object o = blueprintContainer.getComponentInstance(metadata.getId());
+ objects.put(metadata.getId(), type.cast(o));
+ }
+ } catch (Throwable t) {
+ // ignore
+ }
+ }
+ return objects;
+ }
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintDataFormatResolver.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintDataFormatResolver.java
new file mode 100644
index 0000000..0f504d0
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintDataFormatResolver.java
@@ -0,0 +1,62 @@
+/*
+ * 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.blueprint;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.core.osgi.OsgiDataFormatResolver;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataFormatFactory;
+import org.apache.camel.spi.DataFormatResolver;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BlueprintDataFormatResolver extends OsgiDataFormatResolver {
+ private static final Logger LOG = LoggerFactory.getLogger(BlueprintDataFormatResolver.class);
+
+ public BlueprintDataFormatResolver(BundleContext bundleContext) {
+ super(bundleContext);
+ }
+
+ @Override
+ public DataFormat resolveDataFormat(String name, CamelContext context) {
+ DataFormat dataFormat = null;
+
+ DataFormatResolver resolver = context.getRegistry().lookupByNameAndType(".camelBlueprint.dataformatResolver." + name, DataFormatResolver.class);
+ if (resolver != null) {
+ LOG.debug("Found dataformat resolver: {} in registry: {}", name, resolver);
+ dataFormat = resolver.resolveDataFormat(name, context);
+ }
+
+ if (dataFormat == null) {
+ dataFormat = super.resolveDataFormat(name, context);
+ }
+
+ return dataFormat;
+ }
+
+ @Override
+ public DataFormat createDataFormat(String name, CamelContext context) {
+ DataFormatFactory factory = context.getRegistry().lookupByNameAndType(".camelBlueprint.dataformatFactory." + name, DataFormatFactory.class);
+ if (factory != null) {
+ LOG.debug("Found dataformat factory: {} in registry: {}", name, factory);
+ return factory.newInstance();
+ }
+
+ return super.createDataFormat(name, context);
+ }
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintLanguageResolver.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintLanguageResolver.java
new file mode 100644
index 0000000..a2ae987
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintLanguageResolver.java
@@ -0,0 +1,49 @@
+/*
+ * 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.blueprint;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.core.osgi.OsgiLanguageResolver;
+import org.apache.camel.spi.Language;
+import org.apache.camel.spi.LanguageResolver;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BlueprintLanguageResolver extends OsgiLanguageResolver {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BlueprintLanguageResolver.class);
+
+ public BlueprintLanguageResolver(BundleContext bundleContext) {
+ super(bundleContext);
+ }
+
+ @Override
+ public Language resolveLanguage(String name, CamelContext context) {
+ try {
+ Object bean = context.getRegistry().lookupByName(".camelBlueprint.languageResolver." + name);
+ if (bean instanceof LanguageResolver) {
+ LOG.debug("Found language resolver: {} in registry: {}", name, bean);
+ return ((LanguageResolver) bean).resolveLanguage(name, context);
+ }
+ } catch (Exception e) {
+ LOG.trace("Ignored error looking up bean: " + name + " due: " + e.getMessage(), e);
+ }
+ return super.resolveLanguage(name, context);
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintModelJAXBContextFactory.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintModelJAXBContextFactory.java
new file mode 100644
index 0000000..7a10282
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintModelJAXBContextFactory.java
@@ -0,0 +1,66 @@
+/*
+ * 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.blueprint;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.camel.core.xml.AbstractCamelContextFactoryBean;
+import org.apache.camel.util.blueprint.SSLContextParametersFactoryBean;
+import org.apache.camel.xml.jaxb.DefaultModelJAXBContextFactory;
+
+public class BlueprintModelJAXBContextFactory extends DefaultModelJAXBContextFactory {
+
+ private final ClassLoader classLoader;
+
+ public BlueprintModelJAXBContextFactory(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ @Override
+ protected ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ @Override
+ protected String getPackages() {
+ // we nedd to have a class from each different package with jaxb models
+ // and we must use the .class for the classloader to work in OSGi
+ Set<Class<?>> classes = new LinkedHashSet<>();
+ classes.add(CamelContextFactoryBean.class);
+ classes.add(AbstractCamelContextFactoryBean.class);
+ classes.add(SSLContextParametersFactoryBean.class);
+ classes.add(org.apache.camel.ExchangePattern.class);
+ classes.add(org.apache.camel.model.RouteDefinition.class);
+ classes.add(org.apache.camel.model.config.StreamResequencerConfig.class);
+ classes.add(org.apache.camel.model.dataformat.DataFormatsDefinition.class);
+ classes.add(org.apache.camel.model.language.ExpressionDefinition.class);
+ classes.add(org.apache.camel.model.loadbalancer.RoundRobinLoadBalancerDefinition.class);
+ classes.add(org.apache.camel.model.rest.RestDefinition.class);
+ classes.add(org.apache.camel.model.cloud.ServiceCallDefinition.class);
+
+ StringBuilder packages = new StringBuilder();
+ for (Class<?> cl : classes) {
+ if (packages.length() > 0) {
+ packages.append(":");
+ }
+ packages.append(cl.getName(), 0, cl.getName().lastIndexOf('.'));
+ }
+ return packages.toString();
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintPropertiesSource.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintPropertiesSource.java
new file mode 100644
index 0000000..29c85b6
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintPropertiesSource.java
@@ -0,0 +1,156 @@
+/*
+ * 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.blueprint;
+
+import java.lang.reflect.Method;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.aries.blueprint.ext.PropertyPlaceholderExt;
+import org.apache.camel.spi.PropertiesSource;
+import org.apache.camel.support.ObjectHelper;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.ReflectionHelper;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Blueprint {@link PropertiesSource} which supports looking up
+ * property placeholders from the Blueprint Property Placeholder Service.
+ */
+public class BlueprintPropertiesSource extends ServiceSupport implements PropertiesSource {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BlueprintPropertiesSource.class);
+ private final BlueprintContainer container;
+ private final List<String> ids;
+ private final Set<PropertyPlaceholderWrapper> placeholders = new LinkedHashSet<>();
+
+ public BlueprintPropertiesSource(BlueprintContainer container, List<String> ids) {
+ this.container = container;
+ this.ids = ids;
+ }
+
+ @Override
+ public String getName() {
+ return "BlueprintPropertiesSource" + ids;
+ }
+
+ @Override
+ public String getProperty(String name) {
+ String answer = null;
+
+ for (PropertyPlaceholderWrapper placeholder : placeholders) {
+ boolean isDefault = false;
+ if (placeholders.size() > 1) {
+ // okay we have multiple placeholders and we want to return the answer that
+ // is not the default placeholder if there is multiple keys
+ Map map = placeholder.getDefaultProperties();
+ isDefault = map != null && map.containsKey(name);
+ LOG.trace("Blueprint property key: {} is part of default properties: {}", name, isDefault);
+ }
+
+ try {
+ String candidate = placeholder.retrieveValue(name);
+ if (candidate != null) {
+ if (answer == null || !isDefault) {
+ LOG.trace("Blueprint candidate property key: {} as value: {}", name, answer);
+ answer = candidate;
+ }
+ }
+ } catch (Exception ex) {
+ // Here we just catch the exception and try to use other candidate
+ }
+ }
+ LOG.debug("Blueprint getProperty: {}={}", name, answer);
+
+ return answer;
+ }
+
+ /**
+ * Adds the given Blueprint property placeholder service with the given id
+ *
+ * @param id id of the Blueprint property placeholder service to add.
+ */
+ private void addPropertyPlaceholder(String id) {
+ Object component = container.getComponentInstance(id);
+
+ if (component instanceof PropertyPlaceholderExt) {
+ Class<?> clazz = component.getClass();
+ if (clazz != null) {
+ LOG.debug("Adding Blueprint PropertyPlaceholder: {}", id);
+ Method method = ReflectionHelper.findMethod(clazz, "retrieveValue", String.class);
+ Method defaultMethod = ReflectionHelper.findMethod(clazz, "getDefaultProperties");
+ if (method != null) {
+ method.setAccessible(true);
+ if (defaultMethod != null) {
+ defaultMethod.setAccessible(true);
+ }
+ placeholders.add(new PropertyPlaceholderWrapper(component, method, defaultMethod));
+ } else {
+ throw new IllegalStateException("Cannot add blueprint property placeholder: " + id
+ + " as the method retrieveValue is not found");
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void doInit() throws Exception {
+ for (String id : ids) {
+ addPropertyPlaceholder(id);
+ }
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ // noop
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ // noop
+ }
+
+ private class PropertyPlaceholderWrapper {
+
+ private final Object delegate;
+ private final Method method;
+ private final Method defaultMethod;
+
+ PropertyPlaceholderWrapper(Object delegate, Method method, Method defaultMethod) {
+ this.delegate = delegate;
+ this.method = method;
+ this.defaultMethod = defaultMethod;
+ }
+
+ String retrieveValue(String key) {
+ Object v = ObjectHelper.invokeMethod(method, delegate, key);
+ return v == null ? null : v.toString();
+ }
+
+ Map getDefaultProperties() {
+ if (defaultMethod != null) {
+ return (Map) ObjectHelper.invokeMethod(defaultMethod, delegate);
+ }
+ return null;
+ }
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelConsumerTemplateFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelConsumerTemplateFactoryBean.java
new file mode 100644
index 0000000..2f8948a
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelConsumerTemplateFactoryBean.java
@@ -0,0 +1,65 @@
+/*
+ * 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.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.core.xml.AbstractCamelConsumerTemplateFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+/**
+ * A factory for creating a new {@link org.apache.camel.ConsumerTemplate}
+ * instance with a minimum of XML
+ */
+@XmlRootElement(name = "consumerTemplate")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelConsumerTemplateFactoryBean extends AbstractCamelConsumerTemplateFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
new file mode 100644
index 0000000..d39a199
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
@@ -0,0 +1,979 @@
+/*
+ * 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.blueprint;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Properties;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
+import org.apache.aries.blueprint.ext.PropertyPlaceholderExt;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.ShutdownRoute;
+import org.apache.camel.ShutdownRunningTask;
+import org.apache.camel.TypeConverterExists;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.properties.PropertiesComponent;
+import org.apache.camel.core.osgi.OsgiCamelContextPublisher;
+import org.apache.camel.core.osgi.OsgiEventAdminNotifier;
+import org.apache.camel.core.osgi.utils.BundleDelegatingClassLoader;
+import org.apache.camel.core.xml.AbstractCamelContextFactoryBean;
+import org.apache.camel.core.xml.AbstractCamelFactoryBean;
+import org.apache.camel.core.xml.CamelJMXAgentDefinition;
+import org.apache.camel.core.xml.CamelPropertyPlaceholderDefinition;
+import org.apache.camel.core.xml.CamelServiceExporterDefinition;
+import org.apache.camel.core.xml.CamelStreamCachingStrategyDefinition;
+import org.apache.camel.model.ContextScanDefinition;
+import org.apache.camel.model.GlobalOptionsDefinition;
+import org.apache.camel.model.HystrixConfigurationDefinition;
+import org.apache.camel.model.InterceptDefinition;
+import org.apache.camel.model.InterceptFromDefinition;
+import org.apache.camel.model.InterceptSendToEndpointDefinition;
+import org.apache.camel.model.OnCompletionDefinition;
+import org.apache.camel.model.OnExceptionDefinition;
+import org.apache.camel.model.PackageScanDefinition;
+import org.apache.camel.model.Resilience4jConfigurationDefinition;
+import org.apache.camel.model.RestContextRefDefinition;
+import org.apache.camel.model.RouteBuilderDefinition;
+import org.apache.camel.model.RouteContextRefDefinition;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.ThreadPoolProfileDefinition;
+import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
+import org.apache.camel.model.dataformat.DataFormatsDefinition;
+import org.apache.camel.model.rest.RestConfigurationDefinition;
+import org.apache.camel.model.rest.RestDefinition;
+import org.apache.camel.model.transformer.TransformersDefinition;
+import org.apache.camel.model.validator.ValidatorsDefinition;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.PackageScanFilter;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.util.StringHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A bean to create and initialize a {@link BlueprintCamelContext} and install
+ * routes either explicitly configured in Blueprint XML or found by searching
+ * the classpath for Java classes which extend {@link RouteBuilder} using the
+ * nested {@link #setPackages(String[])}.
+ */
+@XmlRootElement(name = "camelContext")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<BlueprintCamelContext> {
+ private static final Logger LOG = LoggerFactory.getLogger(CamelContextFactoryBean.class);
+
+ @XmlAttribute(name = "depends-on")
+ private String dependsOn;
+ @XmlAttribute
+ private String trace;
+ @XmlAttribute
+ private String backlogTrace;
+ @XmlAttribute
+ private String tracePattern;
+ @XmlAttribute
+ private String debug;
+ @XmlAttribute
+ private String messageHistory;
+ @XmlAttribute
+ private String logMask;
+ @XmlAttribute
+ private String logExhaustedMessageBody;
+ @XmlAttribute
+ private String streamCache = "false";
+ @XmlAttribute
+ private String delayer;
+ @XmlAttribute
+ private String errorHandlerRef;
+ @XmlAttribute
+ private String autoStartup = "true";
+ @XmlAttribute
+ private String useMDCLogging;
+ @XmlAttribute
+ private String mdcLoggingKeysPattern;
+ @XmlAttribute
+ private String useDataType;
+ @XmlAttribute
+ private String useBreadcrumb;
+ @XmlAttribute
+ private String allowUseOriginalMessage;
+ @XmlAttribute
+ private String caseInsensitiveHeaders;
+ @XmlAttribute
+ private String runtimeEndpointRegistryEnabled;
+ @XmlAttribute
+ private String managementNamePattern;
+ @XmlAttribute
+ private String threadNamePattern;
+ @XmlAttribute
+ @Metadata(defaultValue = "true")
+ private Boolean useBlueprintPropertyResolver;
+ @XmlAttribute
+ private ShutdownRoute shutdownRoute;
+ @XmlAttribute
+ private ShutdownRunningTask shutdownRunningTask;
+ @XmlAttribute
+ private Boolean loadTypeConverters;
+ @XmlAttribute
+ private Boolean typeConverterStatisticsEnabled;
+ @XmlAttribute
+ private Boolean inflightRepositoryBrowseEnabled;
+ @XmlAttribute
+ private TypeConverterExists typeConverterExists;
+ @XmlAttribute
+ private LoggingLevel typeConverterExistsLoggingLevel;
+ @XmlElement(name = "globalOptions")
+ private GlobalOptionsDefinition globalOptions;
+ @XmlElement(name = "propertyPlaceholder", type = CamelPropertyPlaceholderDefinition.class)
+ private CamelPropertyPlaceholderDefinition camelPropertyPlaceholder;
+ @XmlElement(name = "package")
+ private String[] packages = {};
+ @XmlElement(name = "packageScan", type = PackageScanDefinition.class)
+ private PackageScanDefinition packageScan;
+ @XmlElement(name = "contextScan", type = ContextScanDefinition.class)
+ private ContextScanDefinition contextScan;
+ @XmlElement(name = "jmxAgent", type = CamelJMXAgentDefinition.class)
+ private CamelJMXAgentDefinition camelJMXAgent;
+ @XmlElement(name = "streamCaching", type = CamelStreamCachingStrategyDefinition.class)
+ private CamelStreamCachingStrategyDefinition camelStreamCachingStrategy;
+ @XmlElements({@XmlElement(name = "template", type = CamelProducerTemplateFactoryBean.class),
+ @XmlElement(name = "fluentTemplate", type = CamelFluentProducerTemplateFactoryBean.class),
+ @XmlElement(name = "consumerTemplate", type = CamelConsumerTemplateFactoryBean.class), @XmlElement(name = "proxy", type = CamelProxyFactoryBean.class),
+ @XmlElement(name = "errorHandler", type = CamelErrorHandlerFactoryBean.class)})
+ private List<AbstractCamelFactoryBean<?>> beansFactory;
+ @XmlElements({@XmlElement(name = "export", type = CamelServiceExporterDefinition.class)})
+ private List<?> beans;
+ @XmlElement(name = "defaultServiceCallConfiguration")
+ private ServiceCallConfigurationDefinition defaultServiceCallConfiguration;
+ @XmlElement(name = "serviceCallConfiguration", type = ServiceCallConfigurationDefinition.class)
+ private List<ServiceCallConfigurationDefinition> serviceCallConfigurations;
+ @XmlElement(name = "defaultHystrixConfiguration")
+ private HystrixConfigurationDefinition defaultHystrixConfiguration;
+ @XmlElement(name = "hystrixConfiguration", type = HystrixConfigurationDefinition.class)
+ private List<HystrixConfigurationDefinition> hystrixConfigurations;
+ @XmlElement(name = "defaultResilience4jConfiguration")
+ private Resilience4jConfigurationDefinition defaultResilience4jConfiguration;
+ @XmlElement(name = "resilience4jConfiguration", type = Resilience4jConfigurationDefinition.class)
+ private List<Resilience4jConfigurationDefinition> resilience4jConfigurations;
+ @XmlElement(name = "routeBuilder")
+ private List<RouteBuilderDefinition> builderRefs = new ArrayList<>();
+ @XmlElement(name = "routeContextRef")
+ private List<RouteContextRefDefinition> routeRefs = new ArrayList<>();
+ @XmlElement(name = "restContextRef")
+ private List<RestContextRefDefinition> restRefs = new ArrayList<>();
+ @XmlElement(name = "threadPoolProfile")
+ private List<ThreadPoolProfileDefinition> threadPoolProfiles;
+ @XmlElement(name = "threadPool")
+ private List<CamelThreadPoolFactoryBean> threadPools;
+ @XmlElement(name = "endpoint")
+ private List<CamelEndpointFactoryBean> endpoints;
+ @XmlElement(name = "dataFormats")
+ private DataFormatsDefinition dataFormats;
+ @XmlElement(name = "transformers")
+ private TransformersDefinition transformers;
+ @XmlElement(name = "validators")
+ private ValidatorsDefinition validators;
+ @XmlElement(name = "redeliveryPolicyProfile")
+ private List<CamelRedeliveryPolicyFactoryBean> redeliveryPolicies;
+ @XmlElement(name = "onException")
+ private List<OnExceptionDefinition> onExceptions = new ArrayList<>();
+ @XmlElement(name = "onCompletion")
+ private List<OnCompletionDefinition> onCompletions = new ArrayList<>();
+ @XmlElement(name = "intercept")
+ private List<InterceptDefinition> intercepts = new ArrayList<>();
+ @XmlElement(name = "interceptFrom")
+ private List<InterceptFromDefinition> interceptFroms = new ArrayList<>();
+ @XmlElement(name = "interceptSendToEndpoint")
+ private List<InterceptSendToEndpointDefinition> interceptSendToEndpoints = new ArrayList<>();
+ @XmlElement(name = "restConfiguration")
+ private RestConfigurationDefinition restConfiguration;
+ @XmlElement(name = "rest")
+ private List<RestDefinition> rests = new ArrayList<>();
+ @XmlElement(name = "route")
+ private List<RouteDefinition> routes = new ArrayList<>();
+ @XmlTransient
+ private BlueprintCamelContext context;
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+ @XmlTransient
+ private BundleContext bundleContext;
+ @XmlTransient
+ private boolean implicitId;
+ @XmlTransient
+ private OsgiCamelContextPublisher osgiCamelContextPublisher;
+
+ @Override
+ public Class<BlueprintCamelContext> getObjectType() {
+ return BlueprintCamelContext.class;
+ }
+
+ @Override
+ public BlueprintCamelContext getContext(boolean create) {
+ if (context == null && create) {
+ context = createContext();
+ if (!isImplicitId()) {
+ context.setName(getId());
+ }
+ }
+ return context;
+ }
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ protected BlueprintCamelContext createContext() {
+ return new BlueprintCamelContext(bundleContext, blueprintContainer);
+ }
+
+ @Override
+ protected void initCustomRegistry(BlueprintCamelContext context) {
+ Registry registry = getBeanForType(Registry.class);
+ if (registry != null) {
+ LOG.info("Using custom Registry: {}", registry);
+ context.setRegistry(registry);
+ }
+ }
+
+ @Override
+ protected <S> S getBeanForType(Class<S> clazz) {
+ Collection<S> objects = BlueprintContainerBeanRepository.lookupByType(blueprintContainer, clazz).values();
+ if (objects.size() == 1) {
+ return objects.iterator().next();
+ }
+ return null;
+ }
+
+ @Override
+ protected void initPropertyPlaceholder() throws Exception {
+ super.initPropertyPlaceholder();
+
+ // if blueprint property resolver is enabled on CamelContext then bridge
+ // PropertiesComponent to blueprint
+ if (isUseBlueprintPropertyResolver()) {
+ // lookup existing configured properties component
+ PropertiesComponent pc = (PropertiesComponent)getContext().getPropertiesComponent();
+
+ // any extra properties
+ ServiceReference<?> ref = bundleContext.getServiceReference(PropertiesComponent.OVERRIDE_PROPERTIES);
+ if (ref != null) {
+ Properties extra = (Properties)bundleContext.getService(ref);
+ if (extra != null) {
+ pc.setOverrideProperties(extra);
+ }
+ }
+
+ List<String> ids = new ArrayList<>();
+ for (String bp : pc.getLocations()) {
+ String resolver = StringHelper.before(bp, ":");
+ String path = StringHelper.after(bp, ":");
+ if ("blueprint".equals(resolver)) {
+ ids.add(path);
+ }
+ }
+ if (ids.isEmpty()) {
+ // no blueprint locations has been set, so auto-detect the
+ // blueprint property placeholders to use (convention over
+ // configuration)
+ ids = lookupPropertyPlaceholderIds();
+ }
+ pc.addPropertiesSource(new BlueprintPropertiesSource(blueprintContainer, ids));
+ }
+ }
+
+ /**
+ * Lookup the ids of the Blueprint property placeholder services in the
+ * Blueprint container.
+ *
+ * @return the ids, will be an empty if none found.
+ */
+ private List<String> lookupPropertyPlaceholderIds() {
+ List<String> ids = new ArrayList<>();
+
+ for (Object componentId : blueprintContainer.getComponentIds()) {
+ String id = (String)componentId;
+ ComponentMetadata meta = blueprintContainer.getComponentMetadata(id);
+ if (meta instanceof ExtendedBeanMetadata) {
+ Class<?> clazz = ((ExtendedBeanMetadata)meta).getRuntimeClass();
+ if (clazz != null && PropertyPlaceholderExt.class.isAssignableFrom(clazz)) {
+ ids.add(id);
+ }
+ }
+ }
+
+ return ids;
+ }
+
+ @Override
+ protected void initBeanPostProcessor(BlueprintCamelContext context) {
+ }
+
+ @Override
+ protected void postProcessBeforeInit(RouteBuilder builder) {
+ }
+
+ @Override
+ protected void findRouteBuildersByPackageScan(String[] packages, PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception {
+ // add filter to class resolver which then will filter
+ getContext().getPackageScanClassResolver().addFilter(filter);
+ ClassLoader classLoader = new BundleDelegatingClassLoader(bundleContext.getBundle());
+ PackageScanRouteBuilderFinder finder = new PackageScanRouteBuilderFinder(getContext(), packages, classLoader, getContext().getPackageScanClassResolver());
+ finder.appendBuilders(builders);
+
+ // and remove the filter
+ getContext().getPackageScanClassResolver().removeFilter(filter);
+ }
+
+ @Override
+ protected void findRouteBuildersByContextScan(PackageScanFilter filter, boolean includeNonSingletons, List<RoutesBuilder> builders) throws Exception {
+ ContextScanRouteBuilderFinder finder = new ContextScanRouteBuilderFinder(getContext(), filter, includeNonSingletons);
+ finder.appendBuilders(builders);
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ super.afterPropertiesSet();
+ // setup the application context classloader with the bundle delegating
+ // classloader
+ ClassLoader cl = new BundleDelegatingClassLoader(bundleContext.getBundle());
+ LOG.debug("Set the application context classloader to: {}", cl);
+ getContext().setApplicationContextClassLoader(cl);
+ osgiCamelContextPublisher = new OsgiCamelContextPublisher(bundleContext);
+ osgiCamelContextPublisher.start();
+ getContext().getManagementStrategy().addEventNotifier(osgiCamelContextPublisher);
+ try {
+ getClass().getClassLoader().loadClass("org.osgi.service.event.EventAdmin");
+ getContext().getManagementStrategy().addEventNotifier(new OsgiEventAdminNotifier(bundleContext));
+ } catch (Throwable t) {
+ // Ignore, if the EventAdmin package is not available, just don't
+ // use it
+ LOG.debug("EventAdmin package is not available, just don't use it");
+ }
+ // ensure routes is setup
+ setupRoutes();
+ }
+
+ @Override
+ public void destroy() throws Exception {
+ super.destroy();
+ if (osgiCamelContextPublisher != null) {
+ osgiCamelContextPublisher.shutdown();
+ }
+ }
+
+ @Override
+ public String getDependsOn() {
+ return dependsOn;
+ }
+
+ public void setDependsOn(String dependsOn) {
+ this.dependsOn = dependsOn;
+ }
+
+ @Override
+ public String getAutoStartup() {
+ return autoStartup;
+ }
+
+ public void setAutoStartup(String autoStartup) {
+ this.autoStartup = autoStartup;
+ }
+
+ @Override
+ public String getUseMDCLogging() {
+ return useMDCLogging;
+ }
+
+ public void setUseMDCLogging(String useMDCLogging) {
+ this.useMDCLogging = useMDCLogging;
+ }
+
+ @Override
+ public String getMDCLoggingKeysPattern() {
+ return mdcLoggingKeysPattern;
+ }
+
+ public void setMDCLoggingKeysPattern(String mdcLoggingKeysPattern) {
+ this.mdcLoggingKeysPattern = mdcLoggingKeysPattern;
+ }
+
+ @Override
+ public String getUseDataType() {
+ return useDataType;
+ }
+
+ public void setUseDataType(String useDataType) {
+ this.useDataType = useDataType;
+ }
+
+ @Override
+ public String getUseBreadcrumb() {
+ return useBreadcrumb;
+ }
+
+ public void setUseBreadcrumb(String useBreadcrumb) {
+ this.useBreadcrumb = useBreadcrumb;
+ }
+
+ @Override
+ public String getAllowUseOriginalMessage() {
+ return allowUseOriginalMessage;
+ }
+
+ public void setAllowUseOriginalMessage(String allowUseOriginalMessage) {
+ this.allowUseOriginalMessage = allowUseOriginalMessage;
+ }
+
+ @Override
+ public String getCaseInsensitiveHeaders() {
+ return caseInsensitiveHeaders;
+ }
+
+ public void setCaseInsensitiveHeaders(String caseInsensitiveHeaders) {
+ this.caseInsensitiveHeaders = caseInsensitiveHeaders;
+ }
+
+ @Override
+ public String getRuntimeEndpointRegistryEnabled() {
+ return runtimeEndpointRegistryEnabled;
+ }
+
+ public void setRuntimeEndpointRegistryEnabled(String runtimeEndpointRegistryEnabled) {
+ this.runtimeEndpointRegistryEnabled = runtimeEndpointRegistryEnabled;
+ }
+
+ @Override
+ public String getManagementNamePattern() {
+ return managementNamePattern;
+ }
+
+ public void setManagementNamePattern(String managementNamePattern) {
+ this.managementNamePattern = managementNamePattern;
+ }
+
+ @Override
+ public String getThreadNamePattern() {
+ return threadNamePattern;
+ }
+
+ public void setThreadNamePattern(String threadNamePattern) {
+ this.threadNamePattern = threadNamePattern;
+ }
+
+ @Override
+ public Boolean getLoadTypeConverters() {
+ return loadTypeConverters;
+ }
+
+ public void setLoadTypeConverters(Boolean loadTypeConverters) {
+ this.loadTypeConverters = loadTypeConverters;
+ }
+
+ @Override
+ public Boolean getTypeConverterStatisticsEnabled() {
+ return typeConverterStatisticsEnabled;
+ }
+
+ public void setTypeConverterStatisticsEnabled(Boolean typeConverterStatisticsEnabled) {
+ this.typeConverterStatisticsEnabled = typeConverterStatisticsEnabled;
+ }
+
+ @Override
+ public TypeConverterExists getTypeConverterExists() {
+ return typeConverterExists;
+ }
+
+ public void setTypeConverterExists(TypeConverterExists typeConverterExists) {
+ this.typeConverterExists = typeConverterExists;
+ }
+
+ @Override
+ public LoggingLevel getTypeConverterExistsLoggingLevel() {
+ return typeConverterExistsLoggingLevel;
+ }
+
+ public void setTypeConverterExistsLoggingLevel(LoggingLevel typeConverterExistsLoggingLevel) {
+ this.typeConverterExistsLoggingLevel = typeConverterExistsLoggingLevel;
+ }
+
+ @Override
+ public ShutdownRoute getShutdownRoute() {
+ return shutdownRoute;
+ }
+
+ public void setShutdownRoute(ShutdownRoute shutdownRoute) {
+ this.shutdownRoute = shutdownRoute;
+ }
+
+ @Override
+ public ShutdownRunningTask getShutdownRunningTask() {
+ return shutdownRunningTask;
+ }
+
+ public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) {
+ this.shutdownRunningTask = shutdownRunningTask;
+ }
+
+ @Override
+ public CamelPropertyPlaceholderDefinition getCamelPropertyPlaceholder() {
+ return camelPropertyPlaceholder;
+ }
+
+ public void setCamelPropertyPlaceholder(CamelPropertyPlaceholderDefinition camelPropertyPlaceholder) {
+ this.camelPropertyPlaceholder = camelPropertyPlaceholder;
+ }
+
+ @Override
+ public List<RouteContextRefDefinition> getRouteRefs() {
+ return routeRefs;
+ }
+
+ public void setRouteRefs(List<RouteContextRefDefinition> routeRefs) {
+ this.routeRefs = routeRefs;
+ }
+
+ @Override
+ public List<RestContextRefDefinition> getRestRefs() {
+ return restRefs;
+ }
+
+ public void setRestRefs(List<RestContextRefDefinition> restRefs) {
+ this.restRefs = restRefs;
+ }
+
+ @Override
+ public List<CamelRedeliveryPolicyFactoryBean> getRedeliveryPolicies() {
+ return redeliveryPolicies;
+ }
+
+ public void setRedeliveryPolicies(List<CamelRedeliveryPolicyFactoryBean> redeliveryPolicies) {
+ this.redeliveryPolicies = redeliveryPolicies;
+ }
+
+ @Override
+ public List<ThreadPoolProfileDefinition> getThreadPoolProfiles() {
+ return threadPoolProfiles;
+ }
+
+ public void setThreadPoolProfiles(List<ThreadPoolProfileDefinition> threadPoolProfiles) {
+ this.threadPoolProfiles = threadPoolProfiles;
+ }
+
+ public List<CamelThreadPoolFactoryBean> getThreadPools() {
+ return threadPools;
+ }
+
+ public void setThreadPools(List<CamelThreadPoolFactoryBean> threadPools) {
+ this.threadPools = threadPools;
+ }
+
+ @Override
+ public String getTrace() {
+ return trace;
+ }
+
+ public void setTrace(String trace) {
+ this.trace = trace;
+ }
+
+ @Override
+ public String getBacklogTrace() {
+ return backlogTrace;
+ }
+
+ /**
+ * Sets whether backlog tracing is enabled or not.
+ */
+ public void setBacklogTrace(String backlogTrace) {
+ this.backlogTrace = backlogTrace;
+ }
+
+ @Override
+ public String getTracePattern() {
+ return tracePattern;
+ }
+
+ public void setTracePattern(String tracePattern) {
+ this.tracePattern = tracePattern;
+ }
+
+ @Override
+ public String getDebug() {
+ return debug;
+ }
+
+ /**
+ * Sets whether debugging is enabled or not.
+ */
+ public void setDebug(String debug) {
+ this.debug = debug;
+ }
+
+ @Override
+ public String getMessageHistory() {
+ return messageHistory;
+ }
+
+ public void setMessageHistory(String messageHistory) {
+ this.messageHistory = messageHistory;
+ }
+
+ @Override
+ public String getLogMask() {
+ return logMask;
+ }
+
+ public void setLogMask(String logMask) {
+ this.logMask = logMask;
+ }
+
+ @Override
+ public String getLogExhaustedMessageBody() {
+ return logExhaustedMessageBody;
+ }
+
+ public void setLogExhaustedMessageBody(String logExhaustedMessageBody) {
+ this.logExhaustedMessageBody = logExhaustedMessageBody;
+ }
+
+ @Override
+ public String getStreamCache() {
+ return streamCache;
+ }
+
+ public void setStreamCache(String streamCache) {
+ this.streamCache = streamCache;
+ }
+
+ @Override
+ public String getDelayer() {
+ return delayer;
+ }
+
+ public void setDelayer(String delayer) {
+ this.delayer = delayer;
+ }
+
+ @Override
+ public String getErrorHandlerRef() {
+ return errorHandlerRef;
+ }
+
+ public void setErrorHandlerRef(String errorHandlerRef) {
+ this.errorHandlerRef = errorHandlerRef;
+ }
+
+ @Override
+ public GlobalOptionsDefinition getGlobalOptions() {
+ return globalOptions;
+ }
+
+ public void setGlobalOptions(GlobalOptionsDefinition globalOptions) {
+ this.globalOptions = globalOptions;
+ }
+
+ @Override
+ public String[] getPackages() {
+ return packages;
+ }
+
+ public void setPackages(String[] packages) {
+ this.packages = packages;
+ }
+
+ @Override
+ public PackageScanDefinition getPackageScan() {
+ return packageScan;
+ }
+
+ @Override
+ public void setPackageScan(PackageScanDefinition packageScan) {
+ this.packageScan = packageScan;
+ }
+
+ @Override
+ public ContextScanDefinition getContextScan() {
+ return contextScan;
+ }
+
+ @Override
+ public void setContextScan(ContextScanDefinition contextScan) {
+ this.contextScan = contextScan;
+ }
+
+ @Override
+ public CamelJMXAgentDefinition getCamelJMXAgent() {
+ return camelJMXAgent;
+ }
+
+ public void setCamelJMXAgent(CamelJMXAgentDefinition camelJMXAgent) {
+ this.camelJMXAgent = camelJMXAgent;
+ }
+
+ @Override
+ public CamelStreamCachingStrategyDefinition getCamelStreamCachingStrategy() {
+ return camelStreamCachingStrategy;
+ }
+
+ public void setCamelStreamCachingStrategy(CamelStreamCachingStrategyDefinition camelStreamCachingStrategy) {
+ this.camelStreamCachingStrategy = camelStreamCachingStrategy;
+ }
+
+ @Override
+ public List<AbstractCamelFactoryBean<?>> getBeansFactory() {
+ return beansFactory;
+ }
+
+ public void setBeansFactory(List<AbstractCamelFactoryBean<?>> beansFactory) {
+ this.beansFactory = beansFactory;
+ }
+
+ @Override
+ public List<?> getBeans() {
+ return beans;
+ }
+
+ public void setBeans(List<?> beans) {
+ this.beans = beans;
+ }
+
+ @Override
+ public ServiceCallConfigurationDefinition getDefaultServiceCallConfiguration() {
+ return defaultServiceCallConfiguration;
+ }
+
+ public void setDefaultServiceCallConfiguration(ServiceCallConfigurationDefinition defaultServiceCallConfiguration) {
+ this.defaultServiceCallConfiguration = defaultServiceCallConfiguration;
+ }
+
+ @Override
+ public List<ServiceCallConfigurationDefinition> getServiceCallConfigurations() {
+ return serviceCallConfigurations;
+ }
+
+ public void setServiceCallConfigurations(List<ServiceCallConfigurationDefinition> serviceCallConfigurations) {
+ this.serviceCallConfigurations = serviceCallConfigurations;
+ }
+
+ @Override
+ public HystrixConfigurationDefinition getDefaultHystrixConfiguration() {
+ return defaultHystrixConfiguration;
+ }
+
+ public void setDefaultHystrixConfiguration(HystrixConfigurationDefinition defaultHystrixConfiguration) {
+ this.defaultHystrixConfiguration = defaultHystrixConfiguration;
+ }
+
+ @Override
+ public List<HystrixConfigurationDefinition> getHystrixConfigurations() {
+ return hystrixConfigurations;
+ }
+
+ public void setHystrixConfigurations(List<HystrixConfigurationDefinition> hystrixConfigurations) {
+ this.hystrixConfigurations = hystrixConfigurations;
+ }
+
+ @Override
+ public Resilience4jConfigurationDefinition getDefaultResilience4jConfiguration() {
+ return defaultResilience4jConfiguration;
+ }
+
+ public void setDefaultResilience4jConfiguration(Resilience4jConfigurationDefinition defaultResilience4jConfiguration) {
+ this.defaultResilience4jConfiguration = defaultResilience4jConfiguration;
+ }
+
+ @Override
+ public List<Resilience4jConfigurationDefinition> getResilience4jConfigurations() {
+ return resilience4jConfigurations;
+ }
+
+ public void setResilience4jConfigurations(List<Resilience4jConfigurationDefinition> resilience4jConfigurations) {
+ this.resilience4jConfigurations = resilience4jConfigurations;
+ }
+
+ @Override
+ public List<RouteBuilderDefinition> getBuilderRefs() {
+ return builderRefs;
+ }
+
+ public void setBuilderRefs(List<RouteBuilderDefinition> builderRefs) {
+ this.builderRefs = builderRefs;
+ }
+
+ @Override
+ public List<CamelEndpointFactoryBean> getEndpoints() {
+ return endpoints;
+ }
+
+ public void setEndpoints(List<CamelEndpointFactoryBean> endpoints) {
+ this.endpoints = endpoints;
+ }
+
+ @Override
+ public DataFormatsDefinition getDataFormats() {
+ return dataFormats;
+ }
+
+ public void setDataFormats(DataFormatsDefinition dataFormats) {
+ this.dataFormats = dataFormats;
+ }
+
+ public void setTransformers(TransformersDefinition transformers) {
+ this.transformers = transformers;
+ }
+
+ @Override
+ public TransformersDefinition getTransformers() {
+ return transformers;
+ }
+
+ public void setValidators(ValidatorsDefinition validators) {
+ this.validators = validators;
+ }
+
+ @Override
+ public ValidatorsDefinition getValidators() {
+ return validators;
+ }
+
+ @Override
+ public List<OnExceptionDefinition> getOnExceptions() {
+ return onExceptions;
+ }
+
+ public void setOnExceptions(List<OnExceptionDefinition> onExceptions) {
+ this.onExceptions = onExceptions;
+ }
+
+ @Override
+ public List<OnCompletionDefinition> getOnCompletions() {
+ return onCompletions;
+ }
+
+ public void setOnCompletions(List<OnCompletionDefinition> onCompletions) {
+ this.onCompletions = onCompletions;
+ }
+
+ @Override
+ public List<InterceptDefinition> getIntercepts() {
+ return intercepts;
+ }
+
+ public void setIntercepts(List<InterceptDefinition> intercepts) {
+ this.intercepts = intercepts;
+ }
+
+ @Override
+ public List<InterceptFromDefinition> getInterceptFroms() {
+ return interceptFroms;
+ }
+
+ public void setInterceptFroms(List<InterceptFromDefinition> interceptFroms) {
+ this.interceptFroms = interceptFroms;
+ }
+
+ @Override
+ public List<InterceptSendToEndpointDefinition> getInterceptSendToEndpoints() {
+ return interceptSendToEndpoints;
+ }
+
+ public void setInterceptSendToEndpoints(List<InterceptSendToEndpointDefinition> interceptSendToEndpoints) {
+ this.interceptSendToEndpoints = interceptSendToEndpoints;
+ }
+
+ @Override
+ public List<RouteDefinition> getRoutes() {
+ return routes;
+ }
+
+ @Override
+ public void setRoutes(List<RouteDefinition> routes) {
+ this.routes = routes;
+ }
+
+ @Override
+ public List<RestDefinition> getRests() {
+ return rests;
+ }
+
+ @Override
+ public void setRests(List<RestDefinition> rests) {
+ this.rests = rests;
+ }
+
+ @Override
+ public RestConfigurationDefinition getRestConfiguration() {
+ return restConfiguration;
+ }
+
+ public void setRestConfiguration(RestConfigurationDefinition restConfiguration) {
+ this.restConfiguration = restConfiguration;
+ }
+
+ public boolean isImplicitId() {
+ return implicitId;
+ }
+
+ public void setImplicitId(boolean flag) {
+ implicitId = flag;
+ }
+
+ public Boolean getUseBlueprintPropertyResolver() {
+ return useBlueprintPropertyResolver;
+ }
+
+ /**
+ * Whether to automatic detect OSGi Blueprint property placeholder service in use,
+ * and bridge with Camel property placeholder.
+ * When enabled this allows you to only setup OSGi Blueprint property placeholder
+ * and Camel can use the properties in the camelContext.
+ */
+ public void setUseBlueprintPropertyResolver(Boolean useBlueprintPropertyResolver) {
+ this.useBlueprintPropertyResolver = useBlueprintPropertyResolver;
+ }
+
+ public boolean isUseBlueprintPropertyResolver() {
+ // enable by default
+ return useBlueprintPropertyResolver == null || useBlueprintPropertyResolver.booleanValue();
+ }
+
+ @Override
+ public Boolean getInflightRepositoryBrowseEnabled() {
+ return inflightRepositoryBrowseEnabled;
+ }
+
+ public void setInflightRepositoryBrowseEnabled(Boolean inflightRepositoryBrowseEnabled) {
+ this.inflightRepositoryBrowseEnabled = inflightRepositoryBrowseEnabled;
+ }
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelEndpointFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelEndpointFactoryBean.java
new file mode 100644
index 0000000..d9710bd
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelEndpointFactoryBean.java
@@ -0,0 +1,65 @@
+/*
+ * 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.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.core.xml.AbstractCamelEndpointFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+/**
+ * A factory which instantiates {@link Endpoint} objects
+ */
+@XmlRootElement(name = "endpoint")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelEndpointFactoryBean extends AbstractCamelEndpointFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
new file mode 100644
index 0000000..fd6e7de
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
@@ -0,0 +1,144 @@
+/*
+ * 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.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.DefaultErrorHandlerBuilder;
+import org.apache.camel.builder.ErrorHandlerBuilder;
+import org.apache.camel.core.xml.AbstractCamelFactoryBean;
+import org.apache.camel.model.RedeliveryPolicyDefinition;
+import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+@XmlRootElement(name = "errorHandler")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelErrorHandlerFactoryBean extends AbstractCamelFactoryBean<ErrorHandlerBuilder> {
+
+ @XmlAttribute
+ private ErrorHandlerType type = ErrorHandlerType.DefaultErrorHandler;
+ @XmlAttribute
+ private String deadLetterUri;
+ @XmlAttribute
+ private Boolean deadLetterHandleNewException;
+ @XmlAttribute
+ private Boolean useOriginalMessage;
+ @XmlAttribute
+ private Boolean useOriginalBody;
+ @XmlAttribute
+ private String onRedeliveryRef;
+ @XmlAttribute
+ private String onPrepareFailureRef;
+ @XmlAttribute
+ private String onExceptionOccurredRef;
+ @XmlAttribute
+ private String retryWhileRef;
+ @XmlAttribute
+ private String executorServiceRef;
+ @XmlAttribute
+ private String redeliveryPolicyRef;
+ @XmlElement
+ private RedeliveryPolicyDefinition redeliveryPolicy;
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ @Override
+ public ErrorHandlerBuilder getObject() throws Exception {
+ ErrorHandlerBuilder errorHandler = getObjectType().newInstance();
+ if (errorHandler instanceof DefaultErrorHandlerBuilder) {
+ DefaultErrorHandlerBuilder handler = (DefaultErrorHandlerBuilder) errorHandler;
+ if (deadLetterUri != null) {
+ handler.setDeadLetterUri(deadLetterUri);
+ }
+ if (deadLetterHandleNewException != null) {
+ handler.setDeadLetterHandleNewException(deadLetterHandleNewException);
+ }
+ if (useOriginalMessage != null) {
+ handler.setUseOriginalMessage(useOriginalMessage);
+ }
+ if (useOriginalBody != null) {
+ handler.setUseOriginalBody(useOriginalBody);
+ }
+ if (redeliveryPolicy != null) {
+ handler.setRedeliveryPolicy(ErrorHandlerReifier.createRedeliveryPolicy(redeliveryPolicy, getCamelContext(), null));
+ }
+ if (redeliveryPolicyRef != null) {
+ handler.setRedeliveryPolicy(lookup(redeliveryPolicyRef, RedeliveryPolicy.class));
+ }
+ if (onRedeliveryRef != null) {
+ handler.setOnRedelivery(lookup(onRedeliveryRef, Processor.class));
+ }
+ if (onPrepareFailureRef != null) {
+ handler.setOnPrepareFailure(lookup(onPrepareFailureRef, Processor.class));
+ }
+ if (onExceptionOccurredRef != null) {
+ handler.setOnExceptionOccurred(lookup(onExceptionOccurredRef, Processor.class));
+ }
+ if (retryWhileRef != null) {
+ handler.setRetryWhileRef(retryWhileRef);
+ }
+ if (executorServiceRef != null) {
+ handler.setExecutorServiceRef(executorServiceRef);
+ }
+ }
+ return errorHandler;
+ }
+
+ @Override
+ public Class<? extends ErrorHandlerBuilder> getObjectType() {
+ return type.getTypeAsClass();
+ }
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+ protected <T> T lookup(String name, Class<T> type) {
+ return type.cast(blueprintContainer.getComponentInstance(name));
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelFluentProducerTemplateFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelFluentProducerTemplateFactoryBean.java
new file mode 100644
index 0000000..74a6f9d
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelFluentProducerTemplateFactoryBean.java
@@ -0,0 +1,65 @@
+/*
+ * 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.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.core.xml.AbstractCamelFluentProducerTemplateFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+/**
+ * A factory for creating a new {@link org.apache.camel.FluentProducerTemplate}
+ * instance with a minimum of XML
+ */
+@XmlRootElement(name = "fluentTemplate")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelFluentProducerTemplateFactoryBean extends AbstractCamelFluentProducerTemplateFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProducerTemplateFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProducerTemplateFactoryBean.java
new file mode 100644
index 0000000..0e37fc9
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProducerTemplateFactoryBean.java
@@ -0,0 +1,65 @@
+/*
+ * 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.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.core.xml.AbstractCamelProducerTemplateFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+/**
+ * A factory for creating a new {@link org.apache.camel.ProducerTemplate}
+ * instance with a minimum of XML
+ */
+@XmlRootElement(name = "template")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelProducerTemplateFactoryBean extends AbstractCamelProducerTemplateFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProxyFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProxyFactoryBean.java
new file mode 100644
index 0000000..cd42c74
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelProxyFactoryBean.java
@@ -0,0 +1,190 @@
+/*
+ * 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.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.FailedToCreateProducerException;
+import org.apache.camel.Producer;
+import org.apache.camel.component.bean.ProxyHelper;
+import org.apache.camel.core.xml.AbstractCamelFactoryBean;
+import org.apache.camel.support.service.ServiceHelper;
+
+/**
+ * A factory to create a Proxy to a a Camel Pojo Endpoint.
+ */
+@XmlRootElement(name = "proxy")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelProxyFactoryBean extends AbstractCamelFactoryBean<Object> {
+
+ @XmlAttribute
+ private String serviceUrl;
+ @XmlAttribute
+ private String serviceRef;
+ @XmlAttribute
+ private String serviceInterface;
+ @XmlAttribute
+ private Boolean binding;
+ @XmlTransient
+ private Endpoint endpoint;
+ @XmlTransient
+ private Object serviceProxy;
+ @XmlTransient
+ private Producer producer;
+ @XmlTransient
+ private ExtendedBlueprintContainer blueprintContainer;
+
+ @Override
+ public Object getObject() {
+ return serviceProxy;
+ }
+
+ @Override
+ public Class<Object> getObjectType() {
+ return Object.class;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ if (endpoint == null) {
+ getCamelContext();
+ if (getServiceUrl() == null && getServiceRef() == null) {
+ throw new IllegalArgumentException("serviceUrl or serviceRef must be specified.");
+ }
+ if (getServiceInterface() == null) {
+ throw new IllegalArgumentException("serviceInterface must be specified.");
+ }
+
+ // lookup endpoint or we have the url for it
+ if (getServiceRef() != null) {
+ endpoint = getCamelContext().getRegistry().lookupByNameAndType(getServiceRef(), Endpoint.class);
+ } else {
+ endpoint = getCamelContext().getEndpoint(getServiceUrl());
+ }
+
+ if (endpoint == null) {
+ throw new IllegalArgumentException("Could not resolve endpoint: " + getServiceUrl());
+ }
+ }
+
+ // binding is enabled by default
+ boolean bind = getBinding() != null ? getBinding() : true;
+
+ try {
+ // need to start endpoint before we create producer
+ ServiceHelper.startService(endpoint);
+ producer = endpoint.createProducer();
+ // add and start producer
+ getCamelContext().addService(producer, true, true);
+ Class<?> clazz = blueprintContainer.loadClass(getServiceInterface());
+ serviceProxy = ProxyHelper.createProxy(endpoint, bind, producer, clazz);
+ } catch (Exception e) {
+ throw new FailedToCreateProducerException(endpoint, e);
+ }
+ }
+
+ @Override
+ public void destroy() throws Exception {
+ // we let CamelContext manage the lifecycle of the producer and shut it down when Camel stops
+ }
+
+ public String getServiceUrl() {
+ return serviceUrl;
+ }
+
+ public void setServiceUrl(String serviceUrl) {
+ this.serviceUrl = serviceUrl;
+ }
+
+ public String getServiceRef() {
+ return serviceRef;
+ }
+
+ public void setServiceRef(String serviceRef) {
+ this.serviceRef = serviceRef;
+ }
+
+ public Boolean getBinding() {
+ return binding;
+ }
+
+ public void setBinding(Boolean binding) {
+ this.binding = binding;
+ }
+
+ public String getServiceInterface() {
+ return serviceInterface;
+ }
+
+ public void setServiceInterface(String serviceInterface) {
+ this.serviceInterface = serviceInterface;
+ }
+
+ public Endpoint getEndpoint() {
+ return endpoint;
+ }
+
+ public void setEndpoint(Endpoint endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public Producer getProducer() {
+ return producer;
+ }
+
+ public void setProducer(Producer producer) {
+ this.producer = producer;
+ }
+
+ public ExtendedBlueprintContainer getBlueprintContainer() {
+ return blueprintContainer;
+ }
+
+ public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRedeliveryPolicyFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRedeliveryPolicyFactoryBean.java
new file mode 100644
index 0000000..39aa341
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRedeliveryPolicyFactoryBean.java
@@ -0,0 +1,65 @@
+/*
+ * 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.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.core.xml.AbstractCamelRedeliveryPolicyFactoryBean;
+import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+/**
+ * A factory which instantiates {@link RedeliveryPolicy} objects
+ */
+@XmlRootElement(name = "redeliveryPolicyProfile")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelRedeliveryPolicyFactoryBean extends AbstractCamelRedeliveryPolicyFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRestContextFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRestContextFactoryBean.java
new file mode 100644
index 0000000..452e715
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRestContextFactoryBean.java
@@ -0,0 +1,41 @@
+/*
+ * 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.blueprint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.model.IdentifiedType;
+import org.apache.camel.model.rest.RestDefinition;
+
+@XmlRootElement(name = "restContext")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelRestContextFactoryBean extends IdentifiedType {
+
+ @XmlElement(name = "rest", required = true)
+ private List<RestDefinition> rests = new ArrayList<>();
+
+ public List<RestDefinition> getRests() throws Exception {
+ return rests;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRouteContextFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRouteContextFactoryBean.java
new file mode 100644
index 0000000..673de7b
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelRouteContextFactoryBean.java
@@ -0,0 +1,41 @@
+/*
+ * 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.blueprint;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.model.IdentifiedType;
+import org.apache.camel.model.RouteDefinition;
+
+@XmlRootElement(name = "routeContext")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelRouteContextFactoryBean extends IdentifiedType {
+
+ @XmlElement(name = "route", required = true)
+ private List<RouteDefinition> routes = new ArrayList<>();
+
+ public List<RouteDefinition> getRoutes() throws Exception {
+ return routes;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelThreadPoolFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelThreadPoolFactoryBean.java
new file mode 100644
index 0000000..f64efa2
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelThreadPoolFactoryBean.java
@@ -0,0 +1,64 @@
+/*
+ * 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.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.core.xml.AbstractCamelThreadPoolFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+/**
+ * A factory which instantiates {@link java.util.concurrent.ExecutorService} objects
+ */
+@XmlRootElement(name = "threadPool")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CamelThreadPoolFactoryBean extends AbstractCamelThreadPoolFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/ContextScanRouteBuilderFinder.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/ContextScanRouteBuilderFinder.java
new file mode 100644
index 0000000..5423358
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/ContextScanRouteBuilderFinder.java
@@ -0,0 +1,89 @@
+/*
+ * 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.blueprint;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.spi.PackageScanFilter;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A helper class which will find all {@link org.apache.camel.builder.RouteBuilder} instances in the
+ * {@link org.osgi.service.blueprint.container.BlueprintContainer}.
+ */
+public class ContextScanRouteBuilderFinder {
+ private static final Logger LOG = LoggerFactory.getLogger(ContextScanRouteBuilderFinder.class);
+ private final BlueprintContainer blueprintContainer;
+ private final PackageScanFilter filter;
+ private final boolean includeNonSingletons;
+
+ public ContextScanRouteBuilderFinder(BlueprintCamelContext camelContext, PackageScanFilter filter, boolean includeNonSingletons) {
+ this.blueprintContainer = camelContext.getBlueprintContainer();
+ this.filter = filter;
+ this.includeNonSingletons = includeNonSingletons;
+ }
+
+ /**
+ * Appends all the {@link org.apache.camel.builder.RouteBuilder} instances that can be found in the context
+ */
+ public void appendBuilders(List<RoutesBuilder> list) {
+ Map<String, RoutesBuilder> beans = BlueprintContainerBeanRepository.lookupByType(blueprintContainer, RoutesBuilder.class, includeNonSingletons);
+
+ for (Entry<String, RoutesBuilder> entry : beans.entrySet()) {
+ String key = entry.getKey();
+ Object bean = entry.getValue();
+
+ LOG.trace("Found RouteBuilder with id: {} -> {}", key, bean);
+
+ // certain beans should be ignored
+ if (shouldIgnoreBean(bean)) {
+ LOG.debug("Ignoring RouteBuilder id: {}", key);
+ continue;
+ }
+
+ if (!isFilteredClass(bean)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Ignoring filtered RouteBuilder id: {} as class: {}", key, bean.getClass());
+ }
+ continue;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Adding instantiated RouteBuilder id: {} as class: {}", key, bean.getClass());
+ }
+ list.add((RoutesBuilder) bean);
+ }
+ }
+
+ protected boolean shouldIgnoreBean(Object bean) {
+ return false;
+ }
+
+ protected boolean isFilteredClass(Object bean) {
+ if (filter != null) {
+ return filter.matches(bean.getClass());
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/ErrorHandlerType.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/ErrorHandlerType.java
new file mode 100644
index 0000000..72a0d6f
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/ErrorHandlerType.java
@@ -0,0 +1,54 @@
+/*
+ * 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.blueprint;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.builder.DeadLetterChannelBuilder;
+import org.apache.camel.builder.DefaultErrorHandlerBuilder;
+import org.apache.camel.builder.ErrorHandlerBuilder;
+import org.apache.camel.builder.NoErrorHandlerBuilder;
+
+/**
+ * Used to configure the errorHandler type
+ */
+@XmlType
+@XmlEnum(String.class)
+public enum ErrorHandlerType {
+
+ DefaultErrorHandler, DeadLetterChannel, NoErrorHandler;
+
+ /**
+ * Get the type as class.
+ *
+ * @return the class which represents the selected type.
+ */
+ public Class<? extends ErrorHandlerBuilder> getTypeAsClass() {
+ switch (this) {
+ case DefaultErrorHandler:
+ return DefaultErrorHandlerBuilder.class;
+ case DeadLetterChannel:
+ return DeadLetterChannelBuilder.class;
+ case NoErrorHandler:
+ return NoErrorHandlerBuilder.class;
+ default:
+ throw new IllegalArgumentException("Unknown error handler: " + this);
+ }
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/KarafBundleStateService.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/KarafBundleStateService.java
new file mode 100644
index 0000000..1ef5b2c
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/KarafBundleStateService.java
@@ -0,0 +1,95 @@
+/*
+ * 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.blueprint;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Map;
+
+import org.apache.karaf.bundle.core.BundleState;
+import org.apache.karaf.bundle.core.BundleStateService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * A service for Karaf to get extended Bundle information related to Camel Context(s) declared in Blueprint
+ * container.
+ */
+public class KarafBundleStateService implements BundleStateService {
+
+ BlueprintCamelStateService camelStateService;
+
+ public KarafBundleStateService(BlueprintCamelStateService camelStateService) {
+ this.camelStateService = camelStateService;
+ }
+
+ @Override
+ public String getName() {
+ return "Camel Blueprint";
+ }
+
+ @Override
+ public String getDiag(Bundle bundle) {
+ if (getState(bundle) == BundleState.Failure) {
+ // return stacktraces for failed camel contexts
+ Map<String, Throwable> exceptions = camelStateService.getExceptions(bundle);
+ StringWriter sw = new StringWriter();
+ for (String contextId : exceptions.keySet()) {
+ sw.append("Camel context \"").append(contextId).append("\"\n");
+ Throwable t = exceptions.get(contextId);
+ if (t instanceof NullPointerException) {
+ sw.append("Exception: NullPointerException\n");
+ } else if (t.getMessage() != null) {
+ sw.append("Exception: ").append(t.getMessage()).append("\n");
+ }
+ t.printStackTrace(new PrintWriter(sw));
+ sw.append("\n");
+ }
+ return sw.toString();
+ }
+ return null;
+ }
+
+ @Override
+ public BundleState getState(Bundle bundle) {
+ BundleState effective = BundleState.Unknown;
+ for (BlueprintCamelStateService.State s : camelStateService.getStates(bundle)) {
+ if (effective == BundleState.Unknown || s == BlueprintCamelStateService.State.Failure) {
+ switch (s) {
+ case Starting:
+ effective = BundleState.Starting;
+ break;
+ case Active:
+ effective = BundleState.Active;
+ break;
+ case Failure:
+ effective = BundleState.Failure;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return effective;
+ }
+
+ public ServiceRegistration<?> register(BundleContext context) {
+ return context.registerService(BundleStateService.class, this, null);
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/PackageScanRouteBuilderFinder.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/PackageScanRouteBuilderFinder.java
new file mode 100644
index 0000000..7def428
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/PackageScanRouteBuilderFinder.java
@@ -0,0 +1,110 @@
+/*
+ * 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.blueprint;
+
+import java.lang.reflect.Modifier;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.spi.PackageScanClassResolver;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A helper class which will find all {@link org.apache.camel.builder.RouteBuilder} instances on the classpath
+ */
+public class PackageScanRouteBuilderFinder {
+ private static final Logger LOG = LoggerFactory.getLogger(PackageScanRouteBuilderFinder.class);
+ private final BlueprintCamelContext camelContext;
+ private final String[] packages;
+ private final PackageScanClassResolver resolver;
+ private final BlueprintContainer blueprintContainer;
+
+ public PackageScanRouteBuilderFinder(BlueprintCamelContext camelContext, String[] packages, ClassLoader classLoader,
+ PackageScanClassResolver resolver) {
+ this.camelContext = camelContext;
+ this.blueprintContainer = camelContext.getBlueprintContainer();
+ this.packages = packages;
+ this.resolver = resolver;
+ // add our provided loader as well
+ resolver.addClassLoader(classLoader);
+ }
+
+ /**
+ * Appends all the {@link org.apache.camel.builder.RouteBuilder} instances that can be found on the classpath
+ */
+ public void appendBuilders(List<RoutesBuilder> list) throws IllegalAccessException, InstantiationException {
+ Set<Class<?>> classes = resolver.findImplementations(RoutesBuilder.class, packages);
+ for (Class<?> aClass : classes) {
+ LOG.trace("Found RouteBuilder class: {}", aClass);
+
+ // certain beans should be ignored
+ if (shouldIgnoreBean(aClass)) {
+ LOG.debug("Ignoring RouteBuilder class: {}", aClass);
+ continue;
+ }
+
+ if (!isValidClass(aClass)) {
+ LOG.debug("Ignoring invalid RouteBuilder class: {}", aClass);
+ continue;
+ }
+
+ // type is valid so create and instantiate the builder
+ RoutesBuilder builder = instantiateBuilder(aClass);
+ LOG.debug("Adding instantiated RouteBuilder: {}", builder);
+ list.add(builder);
+ }
+ }
+
+ /**
+ * Allows for ignoring beans that are explicitly configured in the Spring XML files
+ */
+ protected boolean shouldIgnoreBean(Class<?> type) {
+ for (Object metadataObject : blueprintContainer.getMetadata(BeanMetadata.class)) {
+ BeanMetadata metadata = (BeanMetadata) metadataObject;
+ if (BeanMetadata.SCOPE_SINGLETON.equals(metadata.getScope())) {
+ Object bean = blueprintContainer.getComponentInstance(metadata.getId());
+ if (type.isInstance(bean)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns <tt>true</tt>if the class is a public, non-abstract class
+ */
+ protected boolean isValidClass(Class<?> type) {
+ // should skip non public classes
+ if (!Modifier.isPublic(type.getModifiers())) {
+ return false;
+ }
+
+ if (!Modifier.isAbstract(type.getModifiers()) && !type.isInterface()) {
+ return true;
+ }
+ return false;
+ }
+
+ protected RoutesBuilder instantiateBuilder(Class<?> type) throws IllegalAccessException, InstantiationException {
+ return (RoutesBuilder) camelContext.getInjector().newInstance(type);
+ }
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java
new file mode 100644
index 0000000..f4c8173
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java
@@ -0,0 +1,1243 @@
+/*
+ * 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.blueprint.handler;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import javax.xml.bind.Binder;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.aries.blueprint.BeanProcessor;
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.ComponentDefinitionRegistryProcessor;
+import org.apache.aries.blueprint.NamespaceHandler;
+import org.apache.aries.blueprint.ParserContext;
+import org.apache.aries.blueprint.PassThroughMetadata;
+import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
+import org.apache.aries.blueprint.mutable.MutablePassThroughMetadata;
+import org.apache.aries.blueprint.mutable.MutableRefMetadata;
+import org.apache.aries.blueprint.mutable.MutableReferenceMetadata;
+import org.apache.camel.BeanInject;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Produce;
+import org.apache.camel.PropertyInject;
+import org.apache.camel.blueprint.BlueprintCamelContext;
+import org.apache.camel.blueprint.BlueprintCamelStateService;
+import org.apache.camel.blueprint.BlueprintModelJAXBContextFactory;
+import org.apache.camel.blueprint.CamelContextFactoryBean;
+import org.apache.camel.blueprint.CamelEndpointFactoryBean;
+import org.apache.camel.blueprint.CamelRestContextFactoryBean;
+import org.apache.camel.blueprint.CamelRouteContextFactoryBean;
+import org.apache.camel.core.xml.AbstractCamelFactoryBean;
+import org.apache.camel.impl.engine.CamelPostProcessorHelper;
+import org.apache.camel.impl.engine.DefaultCamelContextNameStrategy;
+import org.apache.camel.model.AggregateDefinition;
+import org.apache.camel.model.CatchDefinition;
+import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.model.ExpressionNode;
+import org.apache.camel.model.ExpressionSubElementDefinition;
+import org.apache.camel.model.FromDefinition;
+import org.apache.camel.model.MarshalDefinition;
+import org.apache.camel.model.Model;
+import org.apache.camel.model.OnExceptionDefinition;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.model.ResequenceDefinition;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.SendDefinition;
+import org.apache.camel.model.SortDefinition;
+import org.apache.camel.model.ToDefinition;
+import org.apache.camel.model.ToDynamicDefinition;
+import org.apache.camel.model.UnmarshalDefinition;
+import org.apache.camel.model.WireTapDefinition;
+import org.apache.camel.model.language.ExpressionDefinition;
+import org.apache.camel.model.rest.RestBindingMode;
+import org.apache.camel.model.rest.RestDefinition;
+import org.apache.camel.model.rest.VerbDefinition;
+import org.apache.camel.spi.CamelContextNameStrategy;
+import org.apache.camel.spi.ComponentResolver;
+import org.apache.camel.spi.DataFormatResolver;
+import org.apache.camel.spi.LanguageResolver;
+import org.apache.camel.spi.NamespaceAware;
+import org.apache.camel.spi.PropertiesComponent;
+import org.apache.camel.support.ObjectHelper;
+import org.apache.camel.support.builder.Namespaces;
+import org.apache.camel.support.builder.xml.NamespacesHelper;
+import org.apache.camel.support.jsse.KeyStoreParameters;
+import org.apache.camel.support.jsse.SSLContextParameters;
+import org.apache.camel.support.jsse.SecureRandomParameters;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.URISupport;
+import org.apache.camel.util.blueprint.KeyStoreParametersFactoryBean;
+import org.apache.camel.util.blueprint.SSLContextParametersFactoryBean;
+import org.apache.camel.util.blueprint.SecureRandomParametersFactoryBean;
+import org.osgi.framework.Bundle;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.RefMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.osgi.service.blueprint.reflect.ComponentMetadata.ACTIVATION_LAZY;
+import static org.osgi.service.blueprint.reflect.ServiceReferenceMetadata.AVAILABILITY_MANDATORY;
+import static org.osgi.service.blueprint.reflect.ServiceReferenceMetadata.AVAILABILITY_OPTIONAL;
+
+/**
+ * Camel {@link NamespaceHandler} to parse the Camel related namespaces.
+ */
+public class CamelNamespaceHandler implements NamespaceHandler {
+
+ public static final String BLUEPRINT_NS = "http://camel.apache.org/schema/blueprint";
+ public static final String SPRING_NS = "http://camel.apache.org/schema/spring";
+
+ private static final String CAMEL_CONTEXT = "camelContext";
+ private static final String ROUTE_CONTEXT = "routeContext";
+ private static final String REST_CONTEXT = "restContext";
+ private static final String ENDPOINT = "endpoint";
+ private static final String KEY_STORE_PARAMETERS = "keyStoreParameters";
+ private static final String SECURE_RANDOM_PARAMETERS = "secureRandomParameters";
+ private static final String SSL_CONTEXT_PARAMETERS = "sslContextParameters";
+
+ private static final Logger LOG = LoggerFactory.getLogger(CamelNamespaceHandler.class);
+
+ private JAXBContext jaxbContext;
+
+ /**
+ * Prepares the nodes before parsing.
+ */
+ public static void doBeforeParse(Node node, String fromNamespace, String toNamespace) {
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
+ Document doc = node.getOwnerDocument();
+ if (node.getNamespaceURI().equals(fromNamespace)) {
+ doc.renameNode(node, toNamespace, node.getLocalName());
+ }
+
+ // remove whitespace noise from uri, xxxUri attributes, eg new lines, and tabs etc, which allows end users to format
+ // their Camel routes in more human readable format, but at runtime those attributes must be trimmed
+ // the parser removes most of the noise, but keeps double spaces in the attribute values
+ NamedNodeMap map = node.getAttributes();
+ for (int i = 0; i < map.getLength(); i++) {
+ Node att = map.item(i);
+ if (att.getNodeName().equals("uri") || att.getNodeName().endsWith("Uri")) {
+ final String value = att.getNodeValue();
+ String before = StringHelper.before(value, "?");
+ String after = StringHelper.after(value, "?");
+
+ if (before != null && after != null) {
+ // remove all double spaces in the uri parameters
+ String changed = after.replaceAll("\\s{2,}", "");
+ if (!after.equals(changed)) {
+ String newAtr = before.trim() + "?" + changed.trim();
+ LOG.debug("Removed whitespace noise from attribute {} -> {}", value, newAtr);
+ att.setNodeValue(newAtr);
+ }
+ }
+ }
+ }
+ }
+ NodeList list = node.getChildNodes();
+ for (int i = 0; i < list.getLength(); ++i) {
+ doBeforeParse(list.item(i), fromNamespace, toNamespace);
+ }
+ }
+
+ @Override
+ public URL getSchemaLocation(String namespace) {
+ if (BLUEPRINT_NS.equals(namespace)) {
+ return getClass().getClassLoader().getResource("camel-blueprint.xsd");
+ }
+ return null;
+ }
+
+ @Override
+ @SuppressWarnings({"rawtypes"})
+ public Set<Class> getManagedClasses() {
+ return new HashSet<>(Arrays.asList(BlueprintCamelContext.class));
+ }
+
+ @Override
+ public Metadata parse(Element element, ParserContext context) {
+ LOG.trace("Parsing element {}", element);
+
+ try {
+ // as the camel-core model namespace is Spring we need to rename from blueprint to spring
+ doBeforeParse(element, BLUEPRINT_NS, SPRING_NS);
+
+ if (element.getLocalName().equals(CAMEL_CONTEXT)) {
+ return parseCamelContextNode(element, context);
+ }
+ if (element.getLocalName().equals(ROUTE_CONTEXT)) {
+ return parseRouteContextNode(element, context);
+ }
+ if (element.getLocalName().equals(REST_CONTEXT)) {
+ return parseRestContextNode(element, context);
+ }
+ if (element.getLocalName().equals(ENDPOINT)) {
+ return parseEndpointNode(element, context);
+ }
+ if (element.getLocalName().equals(KEY_STORE_PARAMETERS)) {
+ return parseKeyStoreParametersNode(element, context);
+ }
+ if (element.getLocalName().equals(SECURE_RANDOM_PARAMETERS)) {
+ return parseSecureRandomParametersNode(element, context);
+ }
+ if (element.getLocalName().equals(SSL_CONTEXT_PARAMETERS)) {
+ return parseSSLContextParametersNode(element, context);
+ }
+ } finally {
+ // make sure to rename back so we leave the DOM as-is
+ doBeforeParse(element, SPRING_NS, BLUEPRINT_NS);
+ }
+
+ return null;
+ }
+
+ private Metadata parseCamelContextNode(Element element, ParserContext context) {
+ LOG.trace("Parsing CamelContext {}", element);
+ // Find the id, generate one if needed
+ String contextId = element.getAttribute("id");
+ boolean implicitId = false;
+
+ // let's avoid folks having to explicitly give an ID to a camel context
+ if (org.apache.camel.util.ObjectHelper.isEmpty(contextId)) {
+ // if no explicit id was set then use a default auto generated name
+ CamelContextNameStrategy strategy = new DefaultCamelContextNameStrategy();
+ contextId = strategy.getName();
+ element.setAttributeNS(null, "id", contextId);
+ implicitId = true;
+ }
+
+ // now let's parse the routes with JAXB
+ Binder<Node> binder;
+ try {
+ binder = getJaxbContext().createBinder();
+ } catch (JAXBException e) {
+ throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e);
+ }
+ Object value = parseUsingJaxb(element, context, binder);
+ if (!(value instanceof CamelContextFactoryBean)) {
+ throw new ComponentDefinitionException("Expected an instance of " + CamelContextFactoryBean.class);
+ }
+
+ CamelContextFactoryBean ccfb = (CamelContextFactoryBean) value;
+ ccfb.setImplicitId(implicitId);
+
+ MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
+ factory.setId(".camelBlueprint.passThrough." + contextId);
+ factory.setObject(new PassThroughCallable<>(value));
+
+ MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class);
+ factory2.setId(".camelBlueprint.factory." + contextId);
+ factory2.setFactoryComponent(factory);
+ factory2.setFactoryMethod("call");
+ factory2.setInitMethod("afterPropertiesSet");
+ factory2.setDestroyMethod("destroy");
+ factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+ factory2.addProperty("bundleContext", createRef(context, "blueprintBundleContext"));
+ // We need to add other components which the camel context dependsOn
+ if (org.apache.camel.util.ObjectHelper.isNotEmpty(ccfb.getDependsOn())) {
+ factory2.setDependsOn(Arrays.asList(ccfb.getDependsOn().split(" |,")));
+ }
+ context.getComponentDefinitionRegistry().registerComponentDefinition(factory2);
+
+ MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
+ ctx.setId(contextId);
+ ctx.setRuntimeClass(BlueprintCamelContext.class);
+ ctx.setFactoryComponent(factory2);
+ ctx.setFactoryMethod("getContext");
+ ctx.addProperty("bundleStateService", createRef(context, ".camelBlueprint.bundleStateService"));
+ ctx.setInitMethod("init");
+ ctx.setDestroyMethod("destroy");
+
+ // Register factory beans
+ registerBeans(context, contextId, ccfb.getThreadPools());
+ registerBeans(context, contextId, ccfb.getEndpoints());
+ registerBeans(context, contextId, ccfb.getRedeliveryPolicies());
+ registerBeans(context, contextId, ccfb.getBeansFactory());
+
+ // Register single CamelBundleStateService - shared for all bundles and all Blueprint Camel contexts
+ registerBundleStateService(context);
+
+ // Register processors
+ MutablePassThroughMetadata beanProcessorFactory = context.createMetadata(MutablePassThroughMetadata.class);
+ beanProcessorFactory.setId(".camelBlueprint.processor.bean.passThrough." + contextId);
+ beanProcessorFactory.setObject(new PassThroughCallable<Object>(new CamelInjector(contextId)));
+
+ MutableBeanMetadata beanProcessor = context.createMetadata(MutableBeanMetadata.class);
+ beanProcessor.setId(".camelBlueprint.processor.bean." + contextId);
+ beanProcessor.setRuntimeClass(CamelInjector.class);
+ beanProcessor.setFactoryComponent(beanProcessorFactory);
+ beanProcessor.setFactoryMethod("call");
+ beanProcessor.setProcessor(true);
+ beanProcessor.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+ context.getComponentDefinitionRegistry().registerComponentDefinition(beanProcessor);
+
+ MutablePassThroughMetadata regProcessorFactory = context.createMetadata(MutablePassThroughMetadata.class);
+ regProcessorFactory.setId(".camelBlueprint.processor.registry.passThrough." + contextId);
+ regProcessorFactory.setObject(new PassThroughCallable<Object>(new CamelDependenciesFinder(contextId, context)));
+
+ MutableBeanMetadata regProcessor = context.createMetadata(MutableBeanMetadata.class);
+ regProcessor.setId(".camelBlueprint.processor.registry." + contextId);
+ regProcessor.setRuntimeClass(CamelDependenciesFinder.class);
+ regProcessor.setFactoryComponent(regProcessorFactory);
+ regProcessor.setFactoryMethod("call");
+ regProcessor.setProcessor(true);
+ regProcessor.addDependsOn(".camelBlueprint.processor.bean." + contextId);
+ regProcessor.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+ context.getComponentDefinitionRegistry().registerComponentDefinition(regProcessor);
+
+ // lets inject the namespaces into any namespace aware POJOs
+ injectNamespaces(element, binder);
+
+ LOG.trace("Parsing CamelContext done, returning {}", ctx);
+ return ctx;
+ }
+
+ protected void injectNamespaces(Element element, Binder<Node> binder) {
+ NodeList list = element.getChildNodes();
+ Namespaces namespaces = null;
+ int size = list.getLength();
+ for (int i = 0; i < size; i++) {
+ Node child = list.item(i);
+ if (child instanceof Element) {
+ Element childElement = (Element) child;
+ Object object = binder.getJAXBNode(child);
+ if (object instanceof NamespaceAware) {
+ NamespaceAware namespaceAware = (NamespaceAware) object;
+ if (namespaces == null) {
+ namespaces = NamespacesHelper.namespaces(element);
+ }
+ namespaces.configure(namespaceAware);
+ }
+ injectNamespaces(childElement, binder);
+ }
+ }
+ }
+
+ private Metadata parseRouteContextNode(Element element, ParserContext context) {
+ LOG.trace("Parsing RouteContext {}", element);
+ // now parse the routes with JAXB
+ Binder<Node> binder;
+ try {
+ binder = getJaxbContext().createBinder();
+ } catch (JAXBException e) {
+
+ throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e);
+ }
+ Object value = parseUsingJaxb(element, context, binder);
+ if (!(value instanceof CamelRouteContextFactoryBean)) {
+ throw new ComponentDefinitionException("Expected an instance of " + CamelRouteContextFactoryBean.class);
+ }
+
+ CamelRouteContextFactoryBean rcfb = (CamelRouteContextFactoryBean) value;
+ String id = rcfb.getId();
+
+ MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
+ factory.setId(".camelBlueprint.passThrough." + id);
+ factory.setObject(new PassThroughCallable<Object>(rcfb));
+
+ MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class);
+ factory2.setId(".camelBlueprint.factory." + id);
+ factory2.setFactoryComponent(factory);
+ factory2.setFactoryMethod("call");
+
+ MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
+ ctx.setId(id);
+ ctx.setRuntimeClass(List.class);
+ ctx.setFactoryComponent(factory2);
+ ctx.setFactoryMethod("getRoutes");
+ // must be lazy as we want CamelContext to be activated first
+ ctx.setActivation(ACTIVATION_LAZY);
+
+ // lets inject the namespaces into any namespace aware POJOs
+ injectNamespaces(element, binder);
+
+ LOG.trace("Parsing RouteContext {} done, returning {}", element, ctx);
+ return ctx;
+ }
+
+ private Metadata parseRestContextNode(Element element, ParserContext context) {
+ LOG.trace("Parsing RestContext {}", element);
+ // now parse the rests with JAXB
+ Binder<Node> binder;
+ try {
+ binder = getJaxbContext().createBinder();
+ } catch (JAXBException e) {
+ throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e);
+ }
+ Object value = parseUsingJaxb(element, context, binder);
+ if (!(value instanceof CamelRestContextFactoryBean)) {
+ throw new ComponentDefinitionException("Expected an instance of " + CamelRestContextFactoryBean.class);
+ }
+
+ CamelRestContextFactoryBean rcfb = (CamelRestContextFactoryBean) value;
+ String id = rcfb.getId();
+
+ MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
+ factory.setId(".camelBlueprint.passThrough." + id);
+ factory.setObject(new PassThroughCallable<Object>(rcfb));
+
+ MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class);
+ factory2.setId(".camelBlueprint.factory." + id);
+ factory2.setFactoryComponent(factory);
+ factory2.setFactoryMethod("call");
+
+ MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
+ ctx.setId(id);
+ ctx.setRuntimeClass(List.class);
+ ctx.setFactoryComponent(factory2);
+ ctx.setFactoryMethod("getRests");
+ // must be lazy as we want CamelContext to be activated first
+ ctx.setActivation(ACTIVATION_LAZY);
+
+ // lets inject the namespaces into any namespace aware POJOs
+ injectNamespaces(element, binder);
+
+ LOG.trace("Parsing RestContext {} done, returning {}", element, ctx);
+ return ctx;
+ }
+
+ private Metadata parseEndpointNode(Element element, ParserContext context) {
+ LOG.trace("Parsing Endpoint {}", element);
+ // now parse the rests with JAXB
+ Binder<Node> binder;
+ try {
+ binder = getJaxbContext().createBinder();
+ } catch (JAXBException e) {
+ throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e);
+ }
+ Object value = parseUsingJaxb(element, context, binder);
+ if (!(value instanceof CamelEndpointFactoryBean)) {
+ throw new ComponentDefinitionException("Expected an instance of " + CamelEndpointFactoryBean.class);
+ }
+
+ CamelEndpointFactoryBean rcfb = (CamelEndpointFactoryBean) value;
+ String id = rcfb.getId();
+
+ MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
+ factory.setId(".camelBlueprint.passThrough." + id);
+ factory.setObject(new PassThroughCallable<Object>(rcfb));
+
+ MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class);
+ factory2.setId(".camelBlueprint.factory." + id);
+ factory2.setFactoryComponent(factory);
+ factory2.setFactoryMethod("call");
+ factory2.setInitMethod("afterPropertiesSet");
+ factory2.setDestroyMethod("destroy");
+ factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+
+ MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
+ ctx.setId(id);
+ ctx.setRuntimeClass(Endpoint.class);
+ ctx.setFactoryComponent(factory2);
+ ctx.setFactoryMethod("getObject");
+ // must be lazy as we want CamelContext to be activated first
+ ctx.setActivation(ACTIVATION_LAZY);
+
+ LOG.trace("Parsing endpoint {} done, returning {}", element, ctx);
+ return ctx;
+ }
+
+ private Metadata parseKeyStoreParametersNode(Element element, ParserContext context) {
+ LOG.trace("Parsing KeyStoreParameters {}", element);
+ // now parse the key store parameters with JAXB
+ Binder<Node> binder;
+ try {
+ binder = getJaxbContext().createBinder();
+ } catch (JAXBException e) {
+ throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e);
+ }
+ Object value = parseUsingJaxb(element, context, binder);
+ if (!(value instanceof KeyStoreParametersFactoryBean)) {
+ throw new ComponentDefinitionException("Expected an instance of " + KeyStoreParametersFactoryBean.class);
+ }
+
+ KeyStoreParametersFactoryBean kspfb = (KeyStoreParametersFactoryBean) value;
+ String id = kspfb.getId();
+
+ MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
+ factory.setId(".camelBlueprint.passThrough." + id);
+ factory.setObject(new PassThroughCallable<Object>(kspfb));
+
+ MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class);
+ factory2.setId(".camelBlueprint.factory." + id);
+ factory2.setFactoryComponent(factory);
+ factory2.setFactoryMethod("call");
+ factory2.setInitMethod("afterPropertiesSet");
+ factory2.setDestroyMethod("destroy");
+ factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+
+ MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
+ ctx.setId(id);
+ ctx.setRuntimeClass(KeyStoreParameters.class);
+ ctx.setFactoryComponent(factory2);
+ ctx.setFactoryMethod("getObject");
+ // must be lazy as we want CamelContext to be activated first
+ ctx.setActivation(ACTIVATION_LAZY);
+
+ LOG.trace("Parsing KeyStoreParameters done, returning {}", ctx);
+ return ctx;
+ }
+
+ private Metadata parseSecureRandomParametersNode(Element element, ParserContext context) {
+ LOG.trace("Parsing SecureRandomParameters {}", element);
+ // now parse the key store parameters with JAXB
+ Binder<Node> binder;
+ try {
+ binder = getJaxbContext().createBinder();
+ } catch (JAXBException e) {
+ throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e);
+ }
+ Object value = parseUsingJaxb(element, context, binder);
+ if (!(value instanceof SecureRandomParametersFactoryBean)) {
+ throw new ComponentDefinitionException("Expected an instance of " + SecureRandomParametersFactoryBean.class);
+ }
+
+ SecureRandomParametersFactoryBean srfb = (SecureRandomParametersFactoryBean) value;
+ String id = srfb.getId();
+
+ MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
+ factory.setId(".camelBlueprint.passThrough." + id);
+ factory.setObject(new PassThroughCallable<Object>(srfb));
+
+ MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class);
+ factory2.setId(".camelBlueprint.factory." + id);
+ factory2.setFactoryComponent(factory);
+ factory2.setFactoryMethod("call");
+ factory2.setInitMethod("afterPropertiesSet");
+ factory2.setDestroyMethod("destroy");
+ factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+
+ MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
+ ctx.setId(id);
+ ctx.setRuntimeClass(SecureRandomParameters.class);
+ ctx.setFactoryComponent(factory2);
+ ctx.setFactoryMethod("getObject");
+ // must be lazy as we want CamelContext to be activated first
+ ctx.setActivation(ACTIVATION_LAZY);
+
+ LOG.trace("Parsing SecureRandomParameters done, returning {}", ctx);
+ return ctx;
+ }
+
+ private Metadata parseSSLContextParametersNode(Element element, ParserContext context) {
+ LOG.trace("Parsing SSLContextParameters {}", element);
+ // now parse the key store parameters with JAXB
+ Binder<Node> binder;
+ try {
+ binder = getJaxbContext().createBinder();
+ } catch (JAXBException e) {
+ throw new ComponentDefinitionException("Failed to create the JAXB binder : " + e, e);
+ }
+ Object value = parseUsingJaxb(element, context, binder);
+ if (!(value instanceof SSLContextParametersFactoryBean)) {
+ throw new ComponentDefinitionException("Expected an instance of " + SSLContextParametersFactoryBean.class);
+ }
+
+ SSLContextParametersFactoryBean scpfb = (SSLContextParametersFactoryBean) value;
+ String id = scpfb.getId();
+
+ MutablePassThroughMetadata factory = context.createMetadata(MutablePassThroughMetadata.class);
+ factory.setId(".camelBlueprint.passThrough." + id);
+ factory.setObject(new PassThroughCallable<Object>(scpfb));
+
+ MutableBeanMetadata factory2 = context.createMetadata(MutableBeanMetadata.class);
+ factory2.setId(".camelBlueprint.factory." + id);
+ factory2.setFactoryComponent(factory);
+ factory2.setFactoryMethod("call");
+ factory2.setInitMethod("afterPropertiesSet");
+ factory2.setDestroyMethod("destroy");
+ factory2.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+
+ MutableBeanMetadata ctx = context.createMetadata(MutableBeanMetadata.class);
+ ctx.setId(id);
+ ctx.setRuntimeClass(SSLContextParameters.class);
+ ctx.setFactoryComponent(factory2);
+ ctx.setFactoryMethod("getObject");
+ // must be lazy as we want CamelContext to be activated first
+ ctx.setActivation(ACTIVATION_LAZY);
+
+ LOG.trace("Parsing SSLContextParameters done, returning {}", ctx);
+ return ctx;
+ }
+
+ private void registerBeans(ParserContext context, String contextId, List<?> beans) {
+ if (beans != null) {
+ for (Object bean : beans) {
+ if (bean instanceof AbstractCamelFactoryBean) {
+ registerBean(context, contextId, (AbstractCamelFactoryBean<?>) bean);
+ }
+ }
+ }
+ }
+
+ protected void registerBean(ParserContext context, String contextId, AbstractCamelFactoryBean<?> fact) {
+ String id = fact.getId();
+
+ fact.setCamelContextId(contextId);
+
+ MutablePassThroughMetadata eff = context.createMetadata(MutablePassThroughMetadata.class);
+ eff.setId(".camelBlueprint.bean.passthrough." + id);
+ eff.setObject(new PassThroughCallable<Object>(fact));
+
+ MutableBeanMetadata ef = context.createMetadata(MutableBeanMetadata.class);
+ ef.setId(".camelBlueprint.bean.factory." + id);
+ ef.setFactoryComponent(eff);
+ ef.setFactoryMethod("call");
+ ef.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+ ef.setInitMethod("afterPropertiesSet");
+ ef.setDestroyMethod("destroy");
+
+ MutableBeanMetadata e = context.createMetadata(MutableBeanMetadata.class);
+ e.setId(id);
+ e.setRuntimeClass(fact.getObjectType());
+ e.setFactoryComponent(ef);
+ e.setFactoryMethod("getObject");
+ e.addDependsOn(".camelBlueprint.processor.bean." + contextId);
+
+ context.getComponentDefinitionRegistry().registerComponentDefinition(e);
+ }
+
+ /**
+ * There's single instance of {@link BlueprintCamelStateService} that's used by all Blueprint Camel contexts
+ * to inform about state of Camel contexts. If Karaf is available, this information will propagate to
+ * <em>extended bundle info</em>.
+ * See CAMEL-12980
+ */
+ private void registerBundleStateService(ParserContext context) {
+ ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry();
+ ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.bundleStateService");
+ if (cm == null) {
+ MutableBeanMetadata ssm = context.createMetadata(MutableBeanMetadata.class);
+ ssm.setId(".camelBlueprint.bundleStateService");
+ ssm.setRuntimeClass(BlueprintCamelStateService.class);
+ ssm.addProperty("bundleContext", createRef(context, "blueprintBundleContext"));
+ ssm.setInitMethod("init");
+ ssm.setDestroyMethod("destroy");
+ componentDefinitionRegistry.registerComponentDefinition(ssm);
+ }
+ }
+
+ protected BlueprintContainer getBlueprintContainer(ParserContext context) {
+ PassThroughMetadata ptm = (PassThroughMetadata) context.getComponentDefinitionRegistry().getComponentDefinition("blueprintContainer");
+ return (BlueprintContainer) ptm.getObject();
+ }
+
+ @Override
+ public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
+ return null;
+ }
+
+ protected Object parseUsingJaxb(Element element, ParserContext parserContext, Binder<Node> binder) {
+ try {
+ return binder.unmarshal(element);
+ } catch (JAXBException e) {
+ throw new ComponentDefinitionException("Failed to parse JAXB element: " + e, e);
+ }
+ }
+
+ public JAXBContext getJaxbContext() throws JAXBException {
+ if (jaxbContext == null) {
+ jaxbContext = new BlueprintModelJAXBContextFactory(getClass().getClassLoader()).newJAXBContext();
+ }
+ return jaxbContext;
+ }
+
+ private RefMetadata createRef(ParserContext context, String value) {
+ MutableRefMetadata r = context.createMetadata(MutableRefMetadata.class);
+ r.setComponentId(value);
+ return r;
+ }
+
+ private static ComponentMetadata getDataformatResolverReference(ParserContext context, String dataformat) {
+ // we cannot resolve dataformat names using property placeholders at this point in time
+ if (dataformat.startsWith(PropertiesComponent.PREFIX_TOKEN)) {
+ return null;
+ }
+ ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry();
+ ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.dataformatResolver." + dataformat);
+ if (cm == null) {
+ MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class);
+ svc.setId(".camelBlueprint.dataformatResolver." + dataformat);
+ svc.setFilter("(dataformat=" + dataformat + ")");
+ svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(dataformat) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
+ try {
+ // Try to set the runtime interface (only with aries blueprint > 0.1
+ svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, DataFormatResolver.class);
+ } catch (Throwable t) {
+ // Check if the bundle can see the class
+ try {
+ PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
+ Bundle b = (Bundle) ptm.getObject();
+ if (b.loadClass(DataFormatResolver.class.getName()) != DataFormatResolver.class) {
+ throw new UnsupportedOperationException();
+ }
+ svc.setInterface(DataFormatResolver.class.getName());
+ } catch (Throwable t2) {
+ throw new UnsupportedOperationException();
+ }
+ }
+ componentDefinitionRegistry.registerComponentDefinition(svc);
+ cm = svc;
+ }
+ return cm;
+ }
+
+ private static ComponentMetadata getLanguageResolverReference(ParserContext context, String language) {
+ // we cannot resolve language names using property placeholders at this point in time
+ if (language.startsWith(PropertiesComponent.PREFIX_TOKEN)) {
+ return null;
+ }
+ ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry();
+ ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.languageResolver." + language);
+ if (cm == null) {
+ MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class);
+ svc.setId(".camelBlueprint.languageResolver." + language);
+ svc.setFilter("(language=" + language + ")");
+ svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(language) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
+ try {
+ // Try to set the runtime interface (only with aries blueprint > 0.1
+ svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, LanguageResolver.class);
+ } catch (Throwable t) {
+ // Check if the bundle can see the class
+ try {
+ PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
+ Bundle b = (Bundle) ptm.getObject();
+ if (b.loadClass(LanguageResolver.class.getName()) != LanguageResolver.class) {
+ throw new UnsupportedOperationException();
+ }
+ svc.setInterface(LanguageResolver.class.getName());
+ } catch (Throwable t2) {
+ throw new UnsupportedOperationException();
+ }
+ }
+ componentDefinitionRegistry.registerComponentDefinition(svc);
+ cm = svc;
+ }
+ return cm;
+ }
+
+ private static ComponentMetadata getComponentResolverReference(ParserContext context, String component) {
+ // we cannot resolve component names using property placeholders at this point in time
+ if (component.startsWith(PropertiesComponent.PREFIX_TOKEN)) {
+ return null;
+ }
+ ComponentDefinitionRegistry componentDefinitionRegistry = context.getComponentDefinitionRegistry();
+ ComponentMetadata cm = componentDefinitionRegistry.getComponentDefinition(".camelBlueprint.componentResolver." + component);
+ if (cm == null) {
+ MutableReferenceMetadata svc = context.createMetadata(MutableReferenceMetadata.class);
+ svc.setId(".camelBlueprint.componentResolver." + component);
+ svc.setFilter("(component=" + component + ")");
+ svc.setAvailability(componentDefinitionRegistry.containsComponentDefinition(component) ? AVAILABILITY_OPTIONAL : AVAILABILITY_MANDATORY);
+ try {
+ // Try to set the runtime interface (only with aries blueprint > 0.1
+ svc.getClass().getMethod("setRuntimeInterface", Class.class).invoke(svc, ComponentResolver.class);
+ } catch (Throwable t) {
+ // Check if the bundle can see the class
+ try {
+ PassThroughMetadata ptm = (PassThroughMetadata) componentDefinitionRegistry.getComponentDefinition("blueprintBundle");
+ Bundle b = (Bundle) ptm.getObject();
+ if (b.loadClass(ComponentResolver.class.getName()) != ComponentResolver.class) {
+ throw new UnsupportedOperationException();
+ }
+ svc.setInterface(ComponentResolver.class.getName());
+ } catch (Throwable t2) {
+ throw new UnsupportedOperationException();
+ }
+ }
+ componentDefinitionRegistry.registerComponentDefinition(svc);
+ cm = svc;
+ }
+ return cm;
+ }
+
+ public static class PassThroughCallable<T> implements Callable<T> {
+
+ private T value;
+
+ public PassThroughCallable(T value) {
+ this.value = value;
+ }
+
+ @Override
+ public T call() throws Exception {
+ return value;
+ }
+ }
+
+ public static class CamelInjector extends CamelPostProcessorHelper implements BeanProcessor {
+
+ private final String camelContextName;
+ private BlueprintContainer blueprintContainer;
+
+ public CamelInjector(String camelContextName) {
+ this.camelContextName = camelContextName;
+ }
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ public CamelContext getCamelContext() {
+ if (blueprintContainer != null) {
+ CamelContext answer = (CamelContext) blueprintContainer.getComponentInstance(camelContextName);
+ return answer;
+ }
+ return null;
+ }
+
+ @Override
+ public Object beforeInit(Object bean, String beanName, BeanCreator beanCreator, BeanMetadata beanMetadata) {
+ LOG.trace("Before init of bean: {} -> {}", beanName, bean);
+ // prefer to inject later in afterInit
+ return bean;
+ }
+
+ /**
+ * A strategy method to allow implementations to perform some custom JBI
+ * based injection of the POJO
+ *
+ * @param bean the bean to be injected
+ */
+ protected void injectFields(final Object bean, final String beanName) {
+ Class<?> clazz = bean.getClass();
+ do {
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field field : fields) {
+ PropertyInject propertyInject = field.getAnnotation(PropertyInject.class);
+ if (propertyInject != null) {
+ injectFieldProperty(field, propertyInject.value(), propertyInject.defaultValue(), bean, beanName);
+ }
+
+ BeanInject beanInject = field.getAnnotation(BeanInject.class);
+ if (beanInject != null) {
+ injectFieldBean(field, beanInject.value(), bean, beanName);
+ }
+
+ EndpointInject endpointInject = field.getAnnotation(EndpointInject.class);
+ if (endpointInject != null) {
+ String uri = endpointInject.value().isEmpty() ? endpointInject.uri() : endpointInject.value();
+ injectField(field, uri, endpointInject.property(), bean, beanName);
+ }
+
+ Produce produce = field.getAnnotation(Produce.class);
+ if (produce != null) {
+ String uri = produce.value().isEmpty() ? produce.uri() : produce.value();
+ injectField(field, uri, produce.property(), bean, beanName);
+ }
+ }
+ clazz = clazz.getSuperclass();
+ } while (clazz != null && clazz != Object.class);
+ }
+
+ protected void injectField(Field field, String endpointUri, String endpointProperty, Object bean, String beanName) {
+ setField(field, bean, getInjectionValue(field.getType(), endpointUri, endpointProperty, field.getName(), bean, beanName));
+ }
+
+ protected void injectFieldProperty(Field field, String propertyName, String propertyDefaultValue, Object bean, String beanName) {
+ setField(field, bean, getInjectionPropertyValue(field.getType(), propertyName, propertyDefaultValue, field.getName(), bean, beanName));
+ }
+
+ public void injectFieldBean(Field field, String name, Object bean, String beanName) {
+ setField(field, bean, getInjectionBeanValue(field.getType(), name));
+ }
+
+ protected static void setField(Field field, Object instance, Object value) {
+ try {
+ boolean oldAccessible = field.isAccessible();
+ boolean shouldSetAccessible = !Modifier.isPublic(field.getModifiers()) && !oldAccessible;
+ if (shouldSetAccessible) {
+ field.setAccessible(true);
+ }
+ field.set(instance, value);
+ if (shouldSetAccessible) {
+ field.setAccessible(oldAccessible);
+ }
+ } catch (IllegalArgumentException ex) {
+ throw new UnsupportedOperationException("Cannot inject value of class: " + value.getClass() + " into: " + field);
+ } catch (IllegalAccessException ex) {
+ throw new IllegalStateException("Could not access method: " + ex.getMessage());
+ }
+ }
+
+ protected void injectMethods(final Object bean, final String beanName) {
+ Class<?> clazz = bean.getClass();
+ do {
+ Method[] methods = clazz.getDeclaredMethods();
+ for (Method method : methods) {
+ setterInjection(method, bean, beanName);
+ consumerInjection(method, bean, beanName);
+ }
+ clazz = clazz.getSuperclass();
+ } while (clazz != null && clazz != Object.class);
+ }
+
+ protected void setterInjection(Method method, Object bean, String beanName) {
+ PropertyInject propertyInject = method.getAnnotation(PropertyInject.class);
+ if (propertyInject != null) {
+ setterPropertyInjection(method, propertyInject.value(), propertyInject.defaultValue(), bean, beanName);
+ }
+
+ BeanInject beanInject = method.getAnnotation(BeanInject.class);
+ if (beanInject != null) {
+ setterBeanInjection(method, beanInject.value(), bean, beanName);
+ }
+
+ EndpointInject endpointInject = method.getAnnotation(EndpointInject.class);
+ if (endpointInject != null) {
+ String uri = endpointInject.value().isEmpty() ? endpointInject.uri() : endpointInject.value();
+ setterInjection(method, bean, beanName, uri, endpointInject.property());
+ }
+
+ Produce produce = method.getAnnotation(Produce.class);
+ if (produce != null) {
+ String uri = produce.value().isEmpty() ? produce.uri() : produce.value();
+ setterInjection(method, bean, beanName, uri, produce.property());
+ }
+ }
+
+ protected void setterPropertyInjection(Method method, String propertyValue, String propertyDefaultValue, Object bean, String beanName) {
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes.length != 1) {
+ LOG.warn("Ignoring badly annotated method for injection due to incorrect number of parameters: {}", method);
+ } else {
+ String propertyName = org.apache.camel.util.ObjectHelper.getPropertyName(method);
+ Object value = getInjectionPropertyValue(parameterTypes[0], propertyValue, propertyDefaultValue, propertyName, bean, beanName);
+ ObjectHelper.invokeMethod(method, bean, value);
+ }
+ }
+
+ protected void setterBeanInjection(Method method, String name, Object bean, String beanName) {
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes.length != 1) {
+ LOG.warn("Ignoring badly annotated method for injection due to incorrect number of parameters: {}", method);
+ } else {
+ Object value = getInjectionBeanValue(parameterTypes[0], name);
+ ObjectHelper.invokeMethod(method, bean, value);
+ }
+ }
+
+ protected void setterInjection(Method method, Object bean, String beanName, String endpointUri, String endpointProperty) {
+ Class<?>[] parameterTypes = method.getParameterTypes();
+ if (parameterTypes.length != 1) {
+ LOG.warn("Ignoring badly annotated method for injection due to incorrect number of parameters: {}", method);
+ } else {
+ String propertyName = org.apache.camel.util.ObjectHelper.getPropertyName(method);
+ Object value = getInjectionValue(parameterTypes[0], endpointUri, endpointProperty, propertyName, bean, beanName);
+ ObjectHelper.invokeMethod(method, bean, value);
+ }
+ }
+
+ @Override
+ public Object afterInit(Object bean, String beanName, BeanCreator beanCreator, BeanMetadata beanMetadata) {
+ LOG.trace("After init of bean: {} -> {}", beanName, bean);
+ // we cannot inject CamelContextAware beans as the CamelContext may not be ready
+ // TODO: use bean post processor instead
+ injectFields(bean, beanName);
+ injectMethods(bean, beanName);
+ return bean;
+ }
+
+ @Override
+ public void beforeDestroy(Object bean, String beanName) {
+ }
+
+ @Override
+ public void afterDestroy(Object bean, String beanName) {
+ }
+
+ @Override
+ protected boolean isSingleton(Object bean, String beanName) {
+ if (beanName != null) {
+ ComponentMetadata meta = blueprintContainer.getComponentMetadata(beanName);
+ if (meta instanceof BeanMetadata) {
+ String scope = ((BeanMetadata) meta).getScope();
+ if (scope != null) {
+ return BeanMetadata.SCOPE_SINGLETON.equals(scope);
+ }
+ }
+ }
+ // fallback to super, which will assume singleton
+ // for beans not implementing Camel's IsSingleton interface
+ return super.isSingleton(bean, beanName);
+ }
+ }
+
+ public static class CamelDependenciesFinder implements ComponentDefinitionRegistryProcessor {
+
+ private final String camelContextName;
+ private final ParserContext context;
+ private BlueprintContainer blueprintContainer;
+
+ public CamelDependenciesFinder(String camelContextName, ParserContext context) {
+ this.camelContextName = camelContextName;
+ this.context = context;
+ }
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ public void process(ComponentDefinitionRegistry componentDefinitionRegistry) {
+ CamelContextFactoryBean ccfb = (CamelContextFactoryBean) blueprintContainer.getComponentInstance(".camelBlueprint.factory." + camelContextName);
+ CamelContext camelContext = ccfb.getContext();
+
+ Set<String> components = new HashSet<>();
+ Set<String> languages = new HashSet<>();
+ Set<String> dataformats = new HashSet<>();
+
+ // regular camel routes
+ for (RouteDefinition rd : camelContext.getExtension(Model.class).getRouteDefinitions()) {
+ findInputComponents(rd.getInput(), components, languages, dataformats);
+ findOutputComponents(rd.getOutputs(), components, languages, dataformats);
+ }
+
+ // rest services can have embedded routes or a singular to
+ for (RestDefinition rd : camelContext.getExtension(Model.class).getRestDefinitions()) {
+ for (VerbDefinition vd : rd.getVerbs()) {
+ Object o = vd.getToOrRoute();
+ if (o instanceof RouteDefinition) {
+ RouteDefinition route = (RouteDefinition) o;
+ findInputComponents(route.getInput(), components, languages, dataformats);
+ findOutputComponents(route.getOutputs(), components, languages, dataformats);
+ } else if (o instanceof ToDefinition) {
+ findUriComponent(((ToDefinition) o).getUri(), components);
+ } else if (o instanceof ToDynamicDefinition) {
+ findUriComponent(((ToDynamicDefinition) o).getUri(), components);
+ }
+ }
+ }
+
+ if (ccfb.getRestConfiguration() != null) {
+ // rest configuration may refer to a component to use
+ String component = ccfb.getRestConfiguration().getComponent();
+ if (component != null) {
+ components.add(component);
+ }
+ component = ccfb.getRestConfiguration().getApiComponent();
+ if (component != null) {
+ components.add(component);
+ }
+
+ // check what data formats are used in binding mode
+ RestBindingMode mode = ccfb.getRestConfiguration().getBindingMode();
+ String json = ccfb.getRestConfiguration().getJsonDataFormat();
+ if (json == null && mode != null) {
+ if (RestBindingMode.json.equals(mode) || RestBindingMode.json_xml.equals(mode)) {
+ // jackson is the default json data format
+ json = "json-jackson";
+ }
+ }
+ if (json != null) {
+ dataformats.add(json);
+ }
+ String xml = ccfb.getRestConfiguration().getXmlDataFormat();
+ if (xml == null && mode != null) {
+ if (RestBindingMode.xml.equals(mode) || RestBindingMode.json_xml.equals(mode)) {
+ // jaxb is the default xml data format
+ dataformats.add("jaxb");
+ }
+ }
+ if (xml != null) {
+ dataformats.add(xml);
+ }
+ }
+
+ // We can only add service references to resolvers, but we can't make the factory depends on those
+ // because the factory has already been instantiated
+ try {
+ for (String component : components) {
+ if (camelContext.getComponent(component, false) == null) {
+ // component not already in camel-context so resolve an OSGi reference to it
+ getComponentResolverReference(context, component);
+ } else {
+ LOG.debug("Not creating a service reference for component {} because a component already exists in the Camel Context", component);
+ }
+ }
+ for (String language : languages) {
+ getLanguageResolverReference(context, language);
+ }
+ for (String dataformat : dataformats) {
+ getDataformatResolverReference(context, dataformat);
+ }
+ } catch (UnsupportedOperationException e) {
+ LOG.warn("Unable to add dependencies to Camel components OSGi services. "
+ + "The Apache Aries blueprint implementation used is too old and the blueprint bundle cannot see the org.apache.camel.spi package.");
+ components.clear();
+ languages.clear();
+ dataformats.clear();
+ }
+
+ }
+
+ private void findInputComponents(FromDefinition from, Set<String> components, Set<String> languages, Set<String> dataformats) {
+ if (from != null) {
+ findUriComponent(from.getUri(), components);
+ findSchedulerUriComponent(from.getUri(), components);
+ }
+ }
+
+ @SuppressWarnings({"rawtypes"})
+ private void findOutputComponents(List<ProcessorDefinition<?>> defs, Set<String> components, Set<String> languages, Set<String> dataformats) {
+ if (defs != null) {
+ for (ProcessorDefinition<?> def : defs) {
+ if (def instanceof SendDefinition) {
+ findUriComponent(((SendDefinition) def).getUri(), components);
+ }
+ if (def instanceof MarshalDefinition) {
+ findDataFormat(((MarshalDefinition) def).getDataFormatType(), dataformats);
+ }
+ if (def instanceof UnmarshalDefinition) {
+ findDataFormat(((UnmarshalDefinition) def).getDataFormatType(), dataformats);
+ }
+ if (def instanceof ExpressionNode) {
+ findLanguage(((ExpressionNode) def).getExpression(), languages);
+ }
+ if (def instanceof ResequenceDefinition) {
+ findLanguage(((ResequenceDefinition) def).getExpression(), languages);
+ }
+ if (def instanceof AggregateDefinition) {
+ findLanguage(((AggregateDefinition) def).getExpression(), languages);
+ findLanguage(((AggregateDefinition) def).getCorrelationExpression(), languages);
+ findLanguage(((AggregateDefinition) def).getCompletionPredicate(), languages);
+ findLanguage(((AggregateDefinition) def).getCompletionTimeoutExpression(), languages);
+ findLanguage(((AggregateDefinition) def).getCompletionSizeExpression(), languages);
+ }
+ if (def instanceof CatchDefinition) {
+ CatchDefinition doCatch = (CatchDefinition) def;
+ if (doCatch.getOnWhen() != null) {
+ findLanguage(doCatch.getOnWhen().getExpression(), languages);
+ }
+ }
+ if (def instanceof OnExceptionDefinition) {
+ findLanguage(((OnExceptionDefinition) def).getRetryWhile(), languages);
+ findLanguage(((OnExceptionDefinition) def).getHandled(), languages);
+ findLanguage(((OnExceptionDefinition) def).getContinued(), languages);
+ }
+ if (def instanceof SortDefinition) {
+ findLanguage(((SortDefinition) def).getExpression(), languages);
+ }
+ if (def instanceof WireTapDefinition) {
+ findLanguage(((WireTapDefinition<?>) def).getNewExchangeExpression(), languages);
+ }
+ findOutputComponents(def.getOutputs(), components, languages, dataformats);
+ }
+ }
+ }
+
+ private void findLanguage(ExpressionDefinition expression, Set<String> languages) {
+ if (expression != null) {
+ String lang = expression.getLanguage();
+ if (lang != null && lang.length() > 0) {
+ languages.add(lang);
+ }
+ }
+ }
+
+ private void findLanguage(ExpressionSubElementDefinition expression, Set<String> languages) {
+ if (expression != null) {
+ findLanguage(expression.getExpressionType(), languages);
+ }
+ }
+
+ private void findDataFormat(DataFormatDefinition dfd, Set<String> dataformats) {
+ if (dfd != null && dfd.getDataFormatName() != null) {
+ dataformats.add(dfd.getDataFormatName());
+ }
+ }
+
+ private void findUriComponent(String uri, Set<String> components) {
+ // if the uri is a placeholder then skip it
+ if (uri == null || uri.startsWith(PropertiesComponent.PREFIX_TOKEN)) {
+ return;
+ }
+
+ // validate uri here up-front so a meaningful error can be logged for blueprint
+ // it will also speed up tests in case of failure
+ if (!validateUri(uri)) {
+ return;
+ }
+
+ String splitURI[] = StringHelper.splitOnCharacter(uri, ":", 2);
+ if (splitURI[1] != null) {
+ String scheme = splitURI[0];
+ components.add(scheme);
+ }
+ }
+
+ private void findSchedulerUriComponent(String uri, Set<String> components) {
+
+ // the input may use a scheduler which can be quartz or spring
+ if (uri != null) {
+ try {
+ URI u = new URI(uri);
+ Map<String, Object> parameters = URISupport.parseParameters(u);
+ Object value = parameters.get("scheduler");
+ if (value != null) {
+ // the scheduler can be quartz or spring based, so add reference to camel component
+ // from these components os blueprint knows about the requirement
+ String name = value.toString();
+ if ("quartz".equals(name)) {
+ components.add("quartz");
+ } else if ("spring".equals(name)) {
+ components.add("spring-event");
+ }
+ }
+ } catch (URISyntaxException e) {
+ // ignore as uri should be already validated at findUriComponent method
+ }
+ }
+ }
+
+ private static boolean validateUri(String uri) {
+ try {
+ // the same validation as done in DefaultCamelContext#normalizeEndpointUri(String)
+ URISupport.normalizeUri(uri);
+ } catch (URISyntaxException | UnsupportedEncodingException e) {
+ LOG.error("Endpoint URI '" + uri + "' is not valid due to: " + e.getMessage(), e);
+ return false;
+ }
+ return true;
+ }
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/package-info.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/package-info.java
new file mode 100644
index 0000000..fb86ca9
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://camel.apache.org/schema/spring", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package org.apache.camel.blueprint;
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/KeyManagersParametersFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/KeyManagersParametersFactoryBean.java
new file mode 100644
index 0000000..5df575b
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/KeyManagersParametersFactoryBean.java
@@ -0,0 +1,68 @@
+/*
+ * 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.util.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.blueprint.BlueprintCamelContextLookupHelper;
+import org.apache.camel.core.xml.util.jsse.AbstractKeyManagersParametersFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+public class KeyManagersParametersFactoryBean extends AbstractKeyManagersParametersFactoryBean {
+
+ KeyStoreParametersFactoryBean keyStore;
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ @Override
+ public KeyStoreParametersFactoryBean getKeyStore() {
+ return this.keyStore;
+ }
+
+ public void setKeyStore(KeyStoreParametersFactoryBean keyStore) {
+ this.keyStore = keyStore;
+ }
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/KeyStoreParametersFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/KeyStoreParametersFactoryBean.java
new file mode 100644
index 0000000..41fb3db
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/KeyStoreParametersFactoryBean.java
@@ -0,0 +1,59 @@
+/*
+ * 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.util.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.blueprint.BlueprintCamelContextLookupHelper;
+import org.apache.camel.core.xml.util.jsse.AbstractKeyStoreParametersFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+@XmlRootElement(name = "keyStoreParameters")
+public class KeyStoreParametersFactoryBean extends AbstractKeyStoreParametersFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextClientParametersFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextClientParametersFactoryBean.java
new file mode 100644
index 0000000..2d1deb5
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextClientParametersFactoryBean.java
@@ -0,0 +1,59 @@
+/*
+ * 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.util.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.blueprint.BlueprintCamelContextLookupHelper;
+import org.apache.camel.core.xml.util.jsse.AbstractSSLContextClientParametersFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+@XmlType(propOrder = {})
+public class SSLContextClientParametersFactoryBean extends AbstractSSLContextClientParametersFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextParametersFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextParametersFactoryBean.java
new file mode 100644
index 0000000..e02048b
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextParametersFactoryBean.java
@@ -0,0 +1,110 @@
+/*
+ * 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.util.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.blueprint.BlueprintCamelContextLookupHelper;
+import org.apache.camel.core.xml.util.jsse.AbstractSSLContextParametersFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+@XmlRootElement(name = "sslContextParameters")
+@XmlType(propOrder = {})
+public class SSLContextParametersFactoryBean extends AbstractSSLContextParametersFactoryBean {
+
+ private KeyManagersParametersFactoryBean keyManagers;
+ private TrustManagersParametersFactoryBean trustManagers;
+ private SecureRandomParametersFactoryBean secureRandom;
+ private SSLContextClientParametersFactoryBean clientParameters;
+ private SSLContextServerParametersFactoryBean serverParameters;
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ @Override
+ public KeyManagersParametersFactoryBean getKeyManagers() {
+ return keyManagers;
+ }
+
+ public void setKeyManagers(KeyManagersParametersFactoryBean keyManagers) {
+ this.keyManagers = keyManagers;
+ }
+
+ @Override
+ public TrustManagersParametersFactoryBean getTrustManagers() {
+ return trustManagers;
+ }
+
+ public void setTrustManagers(TrustManagersParametersFactoryBean trustManagers) {
+ this.trustManagers = trustManagers;
+ }
+
+ @Override
+ public SecureRandomParametersFactoryBean getSecureRandom() {
+ return secureRandom;
+ }
+
+ public void setSecureRandom(SecureRandomParametersFactoryBean secureRandom) {
+ this.secureRandom = secureRandom;
+ }
+
+ @Override
+ public SSLContextClientParametersFactoryBean getClientParameters() {
+ return clientParameters;
+ }
+
+ public void setClientParameters(SSLContextClientParametersFactoryBean clientParameters) {
+ this.clientParameters = clientParameters;
+ }
+
+ @Override
+ public SSLContextServerParametersFactoryBean getServerParameters() {
+ return serverParameters;
+ }
+
+ public void setServerParameters(SSLContextServerParametersFactoryBean serverParameters) {
+ this.serverParameters = serverParameters;
+ }
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextServerParametersFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextServerParametersFactoryBean.java
new file mode 100644
index 0000000..e544af8
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SSLContextServerParametersFactoryBean.java
@@ -0,0 +1,59 @@
+/*
+ * 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.util.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.blueprint.BlueprintCamelContextLookupHelper;
+import org.apache.camel.core.xml.util.jsse.AbstractSSLContextServerParametersFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+@XmlType(propOrder = {})
+public class SSLContextServerParametersFactoryBean extends AbstractSSLContextServerParametersFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SecureRandomParametersFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SecureRandomParametersFactoryBean.java
new file mode 100644
index 0000000..a43515c
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/SecureRandomParametersFactoryBean.java
@@ -0,0 +1,59 @@
+/*
+ * 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.util.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.blueprint.BlueprintCamelContextLookupHelper;
+import org.apache.camel.core.xml.util.jsse.AbstractSecureRandomParametersFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+@XmlRootElement(name = "secureRandomParameters")
+public class SecureRandomParametersFactoryBean extends AbstractSecureRandomParametersFactoryBean {
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/TrustManagersParametersFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/TrustManagersParametersFactoryBean.java
new file mode 100644
index 0000000..f463988
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/TrustManagersParametersFactoryBean.java
@@ -0,0 +1,68 @@
+/*
+ * 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.util.blueprint;
+
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.blueprint.BlueprintCamelContextLookupHelper;
+import org.apache.camel.core.xml.util.jsse.AbstractTrustManagersParametersFactoryBean;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+
+public class TrustManagersParametersFactoryBean extends AbstractTrustManagersParametersFactoryBean {
+
+ KeyStoreParametersFactoryBean keyStore;
+
+ @XmlTransient
+ private BlueprintContainer blueprintContainer;
+
+ @Override
+ public KeyStoreParametersFactoryBean getKeyStore() {
+ return this.keyStore;
+ }
+
+ public void setKeyStore(KeyStoreParametersFactoryBean keyStore) {
+ this.keyStore = keyStore;
+ }
+
+ public void setBlueprintContainer(BlueprintContainer blueprintContainer) {
+ this.blueprintContainer = blueprintContainer;
+ }
+
+ @Override
+ protected CamelContext getCamelContextWithId(String camelContextId) {
+ if (blueprintContainer != null) {
+ return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
+ }
+ return null;
+ }
+
+ @Override
+ protected CamelContext discoverDefaultCamelContext() {
+ if (blueprintContainer != null) {
+ Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
+ if (ids.size() == 1) {
+ // there is only 1 id for a BlueprintCamelContext so fallback and use this
+ return getCamelContextWithId(ids.iterator().next());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/package-info.java b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/package-info.java
new file mode 100644
index 0000000..5095afa
--- /dev/null
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/util/blueprint/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://camel.apache.org/schema/spring",
+ elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package org.apache.camel.util.blueprint;
diff --git a/components/camel-blueprint/src/main/resources/OSGI-INF/blueprint/camel-blueprint.xml b/components/camel-blueprint/src/main/resources/OSGI-INF/blueprint/camel-blueprint.xml
new file mode 100644
index 0000000..ba46264
--- /dev/null
+++ b/components/camel-blueprint/src/main/resources/OSGI-INF/blueprint/camel-blueprint.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+ <service interface="org.apache.aries.blueprint.NamespaceHandler">
+ <service-properties>
+ <entry key="osgi.service.blueprint.namespace">
+ <array value-type="java.lang.String">
+ <value>http://camel.apache.org/schema/blueprint</value>
+ <value>http://camel.apache.org/schema/placeholder</value>
+ </array>
+ </entry>
+ </service-properties>
+ <bean class="org.apache.camel.blueprint.handler.CamelNamespaceHandler"/>
+ </service>
+
+</blueprint>
\ No newline at end of file
diff --git a/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintComponentResolverTest.java b/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintComponentResolverTest.java
new file mode 100644
index 0000000..db10c35
--- /dev/null
+++ b/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintComponentResolverTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.blueprint;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.Registry;
+import org.apache.camel.support.DefaultRegistry;
+import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.test.junit4.TestSupport;
+import org.junit.Test;
+
+public class BlueprintComponentResolverTest extends TestSupport {
+
+ @Test
+ public void testOsgiResolverFindComponentFallbackTest() throws Exception {
+ Registry registry = new DefaultRegistry();
+ registry.bind("allstar-component", new SampleComponent(true));
+
+ CamelContext camelContext = new DefaultCamelContext(registry);
+
+ BlueprintComponentResolver resolver = new BlueprintComponentResolver(null);
+ Component component = resolver.resolveComponent("allstar", camelContext);
+ assertNotNull("We should find the super component", component);
+ assertTrue("We should get the super component here", component instanceof SampleComponent);
+ }
+
+ @Test
+ public void testOsgiResolverFindLanguageDoubleFallbackTest() throws Exception {
+ Registry registry = new DefaultRegistry();
+ registry.bind("allstar", new SampleComponent(false));
+ registry.bind("allstar-component", new SampleComponent(true));
+
+ CamelContext camelContext = new DefaultCamelContext(registry);
+
+ BlueprintComponentResolver resolver = new BlueprintComponentResolver(null);
+ Component component = resolver.resolveComponent("allstar", camelContext);
+ assertNotNull("We should find the super component", component);
+ assertTrue("We should get the super component here", component instanceof SampleComponent);
+ assertFalse("We should NOT find the fallback component", ((SampleComponent) component).isFallback());
+ }
+
+ private static class SampleComponent extends ServiceSupport implements Component {
+
+ private boolean fallback;
+
+ SampleComponent(boolean fallback) {
+ this.fallback = fallback;
+ }
+
+ @Override
+ public void setCamelContext(CamelContext camelContext) {
+ throw new UnsupportedOperationException("Should not be called");
+ }
+
+ @Override
+ public CamelContext getCamelContext() {
+ throw new UnsupportedOperationException("Should not be called");
+ }
+
+ @Override
+ public Endpoint createEndpoint(String uri) throws Exception {
+ throw new UnsupportedOperationException("Should not be called");
+ }
+
+ @Override
+ public Endpoint createEndpoint(String uri, Map<String, Object> parameters) throws Exception {
+ throw new UnsupportedOperationException("Should not be called");
+ }
+
+ @Override
+ public boolean useRawUri() {
+ throw new UnsupportedOperationException("Should not be called");
+ }
+
+ public boolean isFallback() {
+ return fallback;
+ }
+
+ public void setFallback(boolean fallback) {
+ this.fallback = fallback;
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ // noop
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ // noop
+ }
+ }
+
+}
diff --git a/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintJaxbRestTest.java b/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintJaxbRestTest.java
new file mode 100644
index 0000000..54b10e0
--- /dev/null
+++ b/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintJaxbRestTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.blueprint;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.camel.blueprint.handler.CamelNamespaceHandler;
+import org.apache.camel.test.junit4.TestSupport;
+import org.junit.Test;
+
+public class BlueprintJaxbRestTest extends TestSupport {
+
+ @Test
+ public void test() throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document doc = db.parse(getClass().getClassLoader().getResourceAsStream("test-rest.xml"));
+ Element elem = null;
+ NodeList nl = doc.getDocumentElement().getChildNodes();
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node node = nl.item(i);
+ if (node instanceof Element) {
+ elem = (Element) node;
+ break;
+ }
+ }
+ CamelNamespaceHandler.doBeforeParse(elem, CamelNamespaceHandler.BLUEPRINT_NS, CamelNamespaceHandler.SPRING_NS);
+
+ JAXBContext context = new BlueprintModelJAXBContextFactory(getClass().getClassLoader()).newJAXBContext();
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ Object object = unmarshaller.unmarshal(elem);
+ assertNotNull(object);
+ assertTrue(object instanceof CamelContextFactoryBean);
+ assertNotNull(((CamelContextFactoryBean) object).getRoutes());
+ assertEquals(0, ((CamelContextFactoryBean) object).getRoutes().size());
+
+ CamelContextFactoryBean cfb = (CamelContextFactoryBean) object;
+ assertEquals(2, cfb.getRests().size());
+ assertEquals("/say/hello", cfb.getRests().get(0).getPath());
+ assertEquals("/say/bye", cfb.getRests().get(1).getPath());
+
+ assertEquals(1, cfb.getRests().get(0).getVerbs().size());
+ assertEquals(2, cfb.getRests().get(1).getVerbs().size());
+ assertEquals("get", cfb.getRests().get(0).getVerbs().get(0).asVerb());
+ assertEquals("get", cfb.getRests().get(1).getVerbs().get(0).asVerb());
+ assertEquals("post", cfb.getRests().get(1).getVerbs().get(1).asVerb());
+
+ assertEquals("dummy-rest", cfb.getRestConfiguration().getComponent());
+ assertEquals("localhost", cfb.getRestConfiguration().getHost());
+ assertEquals("9090", cfb.getRestConfiguration().getPort());
+ }
+}
diff --git a/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintJaxbTest.java b/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintJaxbTest.java
new file mode 100644
index 0000000..02d9e68
--- /dev/null
+++ b/components/camel-blueprint/src/test/java/org/apache/camel/blueprint/BlueprintJaxbTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.blueprint;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.camel.blueprint.handler.CamelNamespaceHandler;
+import org.apache.camel.test.junit4.TestSupport;
+import org.junit.Test;
+
+public class BlueprintJaxbTest extends TestSupport {
+
+ @Test
+ public void test() throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ Document doc = db.parse(getClass().getClassLoader().getResourceAsStream("test.xml"));
+ Element elem = null;
+ NodeList nl = doc.getDocumentElement().getChildNodes();
+ for (int i = 0; i < nl.getLength(); i++) {
+ Node node = nl.item(i);
+ if (node instanceof Element) {
+ elem = (Element) node;
+ break;
+ }
+ }
+ CamelNamespaceHandler.doBeforeParse(elem, CamelNamespaceHandler.BLUEPRINT_NS, CamelNamespaceHandler.SPRING_NS);
+
+ JAXBContext context = new BlueprintModelJAXBContextFactory(getClass().getClassLoader()).newJAXBContext();
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ Object object = unmarshaller.unmarshal(elem);
+ assertNotNull(object);
+ assertTrue(object instanceof CamelContextFactoryBean);
+ assertNotNull(((CamelContextFactoryBean) object).getRoutes());
+ assertEquals(1, ((CamelContextFactoryBean) object).getRoutes().size());
+ assertNotNull(((CamelContextFactoryBean) object).getRoutes().get(0));
+ assertNotNull(((CamelContextFactoryBean) object).getRoutes().get(0).getInput());
+ assertNotNull(((CamelContextFactoryBean) object).getRoutes().get(0).getOutputs());
+ assertEquals(1, ((CamelContextFactoryBean) object).getRoutes().get(0).getOutputs().size());
+ assertTrue(((CamelContextFactoryBean) object).getCamelPropertyPlaceholder().isIgnoreMissingLocation());
+ }
+}
diff --git a/components/camel-blueprint/src/test/resources/log4j2.properties b/components/camel-blueprint/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..a15df5f
--- /dev/null
+++ b/components/camel-blueprint/src/test/resources/log4j2.properties
@@ -0,0 +1,28 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-blueprint-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
diff --git a/components/camel-blueprint/src/test/resources/test-rest.xml b/components/camel-blueprint/src/test/resources/test-rest.xml
new file mode 100644
index 0000000..60e9245
--- /dev/null
+++ b/components/camel-blueprint/src/test/resources/test-rest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+ <camelContext xmlns="http://camel.apache.org/schema/blueprint">
+
+ <restConfiguration component="dummy-rest" host="localhost" port="9090"/>
+
+ <rest path="/say/hello">
+ <get>
+ <to uri="direct:hello"/>
+ </get>
+ </rest>
+ <rest path="/say/bye">
+ <get>
+ <to uri="direct:bye"/>
+ </get>
+ <post>
+ <to uri="seda:update"/>
+ </post>
+ </rest>
+
+ </camelContext>
+
+</blueprint>
diff --git a/components/camel-blueprint/src/test/resources/test.xml b/components/camel-blueprint/src/test/resources/test.xml
new file mode 100644
index 0000000..58801f1
--- /dev/null
+++ b/components/camel-blueprint/src/test/resources/test.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+ <camelContext xmlns="http://camel.apache.org/schema/blueprint">
+ <propertyPlaceholder cache="true" ignoreMissingLocation="true" location="classpath:org/apache/camel/component/properties/cheese.properties"/>
+ <route>
+ <from uri="timer:test"/>
+ <to uri="log:test"/>
+ </route>
+ </camelContext>
+
+</blueprint>
diff --git a/components/pom.xml b/components/pom.xml
index d6a8e0e..51c4e34 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -32,6 +32,7 @@
<packaging>pom</packaging>
<modules>
+ <module>camel-blueprint</module>
<module>camel-kura</module>
<module>camel-paxlogging</module>
</modules>