You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2016/04/07 10:16:53 UTC

camel git commit: CAMEL-9830: camel-spring-javaconfig - Add routes like spring-boot does

Repository: camel
Updated Branches:
  refs/heads/master d5d659eb4 -> 1a4e34960


CAMEL-9830: camel-spring-javaconfig - Add routes like spring-boot does


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

Branch: refs/heads/master
Commit: 1a4e34960fb6953bb804717a728c294f27108a4f
Parents: d5d659e
Author: Claus Ibsen <da...@apache.org>
Authored: Thu Apr 7 10:16:43 2016 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Thu Apr 7 10:16:43 2016 +0200

----------------------------------------------------------------------
 .../spring/javaconfig/CamelConfiguration.java   |  18 +--
 ...SpringJavaconfigInitializationException.java |  24 ++++
 .../spring/javaconfig/RoutesCollector.java      | 126 +++++++++++++++++++
 3 files changed, 160 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/1a4e3496/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java b/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java
index 2df05da..d0cbc2b 100644
--- a/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java
+++ b/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java
@@ -25,7 +25,6 @@ import static java.util.Collections.emptyList;
 import org.apache.camel.CamelContext;
 import org.apache.camel.ConsumerTemplate;
 import org.apache.camel.ProducerTemplate;
-import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.spring.CamelBeanPostProcessor;
 import org.apache.camel.spring.SpringCamelContext;
@@ -44,8 +43,7 @@ import org.springframework.context.annotation.Configuration;
  * A useful base class for writing
  * <a
  * href="http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-annotation-config">
- * Spring annotation-based</a> configurations for working with Camel. Unless {@link #routes()} method is overridden, this configuration
- * automatically load all the {@link org.apache.camel.builder.RouteBuilder} instances available in the Spring context.
+ * Spring annotation-based</a> configurations for working with Camel.
  */
 @Configuration
 public abstract class CamelConfiguration implements BeanFactoryAware, ApplicationContextAware {
@@ -84,7 +82,6 @@ public abstract class CamelConfiguration implements BeanFactoryAware, Applicatio
     public <T> T getBean(String beanName, Class<T> type) {
         return beanFactory.getBean(beanName, type);
     }
-   
 
     /**
      * Invoke callbacks on the object, as though it were configured in the factory. If appropriate,
@@ -144,6 +141,9 @@ public abstract class CamelConfiguration implements BeanFactoryAware, Applicatio
         return camelContext.createConsumerTemplate();
     }
 
+    /**
+     * Camel post processor - required to support Camel annotations.
+     */
     @Bean
     public CamelBeanPostProcessor camelBeanPostProcessor() throws Exception {
         CamelBeanPostProcessor answer = new CamelBeanPostProcessor();
@@ -158,14 +158,16 @@ public abstract class CamelConfiguration implements BeanFactoryAware, Applicatio
     @Bean
     public CamelContext camelContext() throws Exception {
         CamelContext camelContext = createCamelContext();
+        SpringCamelContext.setNoStart(true);
         setupCamelContext(camelContext);
-        List<RouteBuilder> routes = routes();
-        for (RoutesBuilder route : routes) {
-            camelContext.addRoutes(route);
-        }
         return camelContext;
     }
 
+    @Bean
+    RoutesCollector routesCollector(ApplicationContext applicationContext) {
+        return new RoutesCollector(applicationContext, this);
+    }
+
     /**
      * Callback to setup {@link CamelContext} before its started
      */

http://git-wip-us.apache.org/repos/asf/camel/blob/1a4e3496/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelSpringJavaconfigInitializationException.java
----------------------------------------------------------------------
diff --git a/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelSpringJavaconfigInitializationException.java b/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelSpringJavaconfigInitializationException.java
new file mode 100644
index 0000000..c396cc9
--- /dev/null
+++ b/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelSpringJavaconfigInitializationException.java
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.javaconfig;
+
+public class CamelSpringJavaconfigInitializationException extends RuntimeException {
+
+    public CamelSpringJavaconfigInitializationException(Throwable cause) {
+        super(cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/1a4e3496/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/RoutesCollector.java
----------------------------------------------------------------------
diff --git a/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/RoutesCollector.java b/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/RoutesCollector.java
new file mode 100644
index 0000000..dccf38d
--- /dev/null
+++ b/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/RoutesCollector.java
@@ -0,0 +1,126 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.javaconfig;
+
+import java.io.FileNotFoundException;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.rest.RestDefinition;
+import org.apache.camel.model.rest.RestsDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.core.io.Resource;
+
+/**
+ * Collects routes and rests from the various sources (like Spring application context beans registry or opinionated
+ * classpath locations) and injects these into the Camel context.
+ */
+public class RoutesCollector implements ApplicationListener<ContextRefreshedEvent> {
+
+    // Static collaborators
+
+    private static final Logger LOG = LoggerFactory.getLogger(RoutesCollector.class);
+
+    // Collaborators
+
+    private final ApplicationContext applicationContext;
+    private final CamelConfiguration configuration;
+
+    // Constructors
+
+    public RoutesCollector(ApplicationContext applicationContext, CamelConfiguration configuration) {
+        this.applicationContext = applicationContext;
+        this.configuration = configuration;
+    }
+
+    // Overridden
+
+    @Override
+    public void onApplicationEvent(ContextRefreshedEvent event) {
+        ApplicationContext applicationContext = event.getApplicationContext();
+
+        // only listen to context refresh of "my" applicationContext
+        if (this.applicationContext.equals(applicationContext)) {
+
+            CamelContext camelContext = event.getApplicationContext().getBean(CamelContext.class);
+
+            // only add and start Camel if its stopped (initial state)
+            if (camelContext.getStatus().isStopped()) {
+                LOG.debug("Post-processing CamelContext bean: {}", camelContext.getName());
+                for (RoutesBuilder routesBuilder : configuration.routes()) {
+                    // filter out abstract classes
+                    boolean abs = Modifier.isAbstract(routesBuilder.getClass().getModifiers());
+                    if (!abs) {
+                        try {
+                            LOG.debug("Injecting following route into the CamelContext: {}", routesBuilder);
+                            camelContext.addRoutes(routesBuilder);
+                        } catch (Exception e) {
+                            throw new CamelSpringJavaconfigInitializationException(e);
+                        }
+                    }
+                }
+            }
+        } else {
+            LOG.debug("Ignore ContextRefreshedEvent: {}", event);
+        }
+    }
+
+    // Helpers
+
+    private void loadXmlRoutes(ApplicationContext applicationContext, CamelContext camelContext, String directory) throws Exception {
+        LOG.info("Loading additional Camel XML routes from: {}", directory);
+        try {
+            Resource[] xmlRoutes = applicationContext.getResources(directory);
+            for (Resource xmlRoute : xmlRoutes) {
+                LOG.debug("Found XML route: {}", xmlRoute);
+                RoutesDefinition xmlDefinition = camelContext.loadRoutesDefinition(xmlRoute.getInputStream());
+                camelContext.addRouteDefinitions(xmlDefinition.getRoutes());
+            }
+        } catch (FileNotFoundException e) {
+            LOG.debug("No XML routes found in {}. Skipping XML routes detection.", directory);
+        }
+    }
+
+    private void loadXmlRests(ApplicationContext applicationContext, CamelContext camelContext, String directory) {
+        LOG.info("Loading additional Camel XML rests from: {}", directory);
+        try {
+            final Resource[] xmlRests = applicationContext.getResources(directory);
+            for (final Resource xmlRest : xmlRests) {
+                final RestsDefinition xmlDefinitions = camelContext.loadRestsDefinition(xmlRest.getInputStream());
+                camelContext.addRestDefinitions(xmlDefinitions.getRests());
+                for (final RestDefinition xmlDefinition : xmlDefinitions.getRests()) {
+                    final List<RouteDefinition> routeDefinitions = xmlDefinition.asRouteDefinition(camelContext);
+                    camelContext.addRouteDefinitions(routeDefinitions);
+                }
+            }
+        } catch (FileNotFoundException e) {
+            LOG.debug("No XML rests found in {}. Skipping XML rests detection.", directory);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}