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 2019/10/17 19:09:23 UTC

[camel] 02/09: CAMEL-14050: camel-main - Add logic for automatic RouteBuilder class detection ala camel-spring-boot has

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch route-collector
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 8fd86c3c5208c69ad4372efa03e22d36b2e104c9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Oct 17 15:06:27 2019 +0200

    CAMEL-14050: camel-main - Add logic for automatic RouteBuilder class detection ala camel-spring-boot has
---
 .../camel/spring/boot/CamelAutoConfiguration.java  | 13 +++-
 ...Collector.java => RoutesCollectorListener.java} | 64 +++++-----------
 .../spring/boot/SpringBootRoutesCollector.java     | 85 ++++++++++++++++++++++
 .../boot/parent/SpringBootRefreshContextTest.java  |  4 +-
 ...utesCollector.java => BaseRoutesCollector.java} | 22 ++++--
 .../org/apache/camel/main/RoutesCollector.java     | 34 +++++++++
 6 files changed, 163 insertions(+), 59 deletions(-)

diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
index 6a5bd55..c155230 100644
--- a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
+++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
@@ -29,6 +29,7 @@ import org.apache.camel.ProducerTemplate;
 import org.apache.camel.component.properties.PropertiesComponent;
 import org.apache.camel.component.properties.PropertiesParser;
 import org.apache.camel.main.DefaultConfigurationConfigurer;
+import org.apache.camel.main.RoutesCollector;
 import org.apache.camel.model.Model;
 import org.apache.camel.spi.BeanRepository;
 import org.apache.camel.spring.CamelBeanPostProcessor;
@@ -133,7 +134,6 @@ public class CamelAutoConfiguration {
         // lookup and configure SPI beans
         DefaultConfigurationConfigurer.afterPropertiesSet(camelContext);
 
-
         return camelContext;
     }
 
@@ -144,9 +144,16 @@ public class CamelAutoConfiguration {
 
     @Bean
     @ConditionalOnMissingBean(RoutesCollector.class)
-    RoutesCollector routesCollector(ApplicationContext applicationContext, CamelConfigurationProperties config) {
+    RoutesCollector routesCollector(ApplicationContext applicationContext) {
+        return new SpringBootRoutesCollector(applicationContext);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(RoutesCollectorListener.class)
+    RoutesCollectorListener routesCollectorListener(ApplicationContext applicationContext, CamelConfigurationProperties config,
+                                                    RoutesCollector routesCollector) {
         Collection<CamelContextConfiguration> configurations = applicationContext.getBeansOfType(CamelContextConfiguration.class).values();
-        return new RoutesCollector(applicationContext, new ArrayList(configurations), config);
+        return new RoutesCollectorListener(applicationContext, new ArrayList(configurations), config, routesCollector);
     }
 
     /**
diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollector.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollectorListener.java
similarity index 84%
rename from components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollector.java
rename to components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollectorListener.java
index 1858219..0c7c4fc 100644
--- a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollector.java
+++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollectorListener.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.spring.boot;
 
-import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -29,9 +28,8 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.StartupListener;
 import org.apache.camel.main.MainDurationEventNotifier;
-import org.apache.camel.main.MainRoutesCollector;
+import org.apache.camel.main.RoutesCollector;
 import org.apache.camel.model.Model;
-import org.apache.camel.model.ModelHelper;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.spi.CamelEvent;
@@ -47,17 +45,16 @@ import org.springframework.context.ApplicationListener;
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.core.Ordered;
-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>, Ordered {
+public class RoutesCollectorListener implements ApplicationListener<ContextRefreshedEvent>, Ordered {
 
     // Static collaborators
 
-    private static final Logger LOG = LoggerFactory.getLogger(RoutesCollector.class);
+    private static final Logger LOG = LoggerFactory.getLogger(RoutesCollectorListener.class);
 
     // Collaborators
 
@@ -67,13 +64,17 @@ public class RoutesCollector implements ApplicationListener<ContextRefreshedEven
 
     private final CamelConfigurationProperties configurationProperties;
 
+    private final RoutesCollector springBootRoutesCollector;
+
     // Constructors
 
-    public RoutesCollector(ApplicationContext applicationContext, List<CamelContextConfiguration> camelContextConfigurations,
-                           CamelConfigurationProperties configurationProperties) {
+    public RoutesCollectorListener(ApplicationContext applicationContext, List<CamelContextConfiguration> camelContextConfigurations,
+                                   CamelConfigurationProperties configurationProperties,
+                                   RoutesCollector springBootRoutesCollector) {
         this.applicationContext = applicationContext;
         this.camelContextConfigurations = new ArrayList<>(camelContextConfigurations);
         this.configurationProperties = configurationProperties;
+        this.springBootRoutesCollector = springBootRoutesCollector;
     }
 
     // Overridden
@@ -87,8 +88,7 @@ public class RoutesCollector implements ApplicationListener<ContextRefreshedEven
                 && camelContext.getStatus().isStopped()) {
             LOG.debug("Post-processing CamelContext bean: {}", camelContext.getName());
 
-            MainRoutesCollector collector = new MainRoutesCollector();
-            final List<RoutesBuilder> routes = collector.collectRoutes(camelContext, configurationProperties);
+            final List<RoutesBuilder> routes = springBootRoutesCollector.collectRoutesFromRegistry(camelContext, configurationProperties);
 
             // sort routes according to ordered
             routes.sort(OrderedComparator.get());
@@ -105,12 +105,18 @@ public class RoutesCollector implements ApplicationListener<ContextRefreshedEven
             try {
                 boolean scan = !configurationProperties.getXmlRoutes().equals("false");
                 if (scan) {
-                    loadXmlRoutes(applicationContext, camelContext, configurationProperties.getXmlRoutes());
+                    List<RoutesDefinition> defs = springBootRoutesCollector.collectXmlRoutesFromDirectory(camelContext, configurationProperties.getXmlRoutes());
+                    for (RoutesDefinition def : defs) {
+                        camelContext.getExtension(Model.class).addRouteDefinitions(def.getRoutes());
+                    }
                 }
 
                 boolean scanRests = !configurationProperties.getXmlRests().equals("false");
                 if (scanRests) {
-                    loadXmlRests(applicationContext, camelContext, configurationProperties.getXmlRests());
+                    List<RestsDefinition> defs = springBootRoutesCollector.collectXmlRestsFromDirectory(camelContext, configurationProperties.getXmlRests());
+                    for (RestsDefinition def : defs) {
+                        camelContext.getExtension(Model.class).addRestDefinitions(def.getRests(), true);
+                    }
                 }
 
                 for (CamelContextConfiguration camelContextConfiguration : camelContextConfigurations) {
@@ -238,40 +244,6 @@ public class RoutesCollector implements ApplicationListener<ContextRefreshedEven
 
     // Helpers
 
-
-    private void loadXmlRoutes(ApplicationContext applicationContext, CamelContext camelContext, String directory) throws Exception {
-        String[] parts = directory.split(",");
-        for (String part : parts) {
-            LOG.info("Loading additional Camel XML routes from: {}", part);
-            try {
-                Resource[] xmlRoutes = applicationContext.getResources(part);
-                for (Resource xmlRoute : xmlRoutes) {
-                    LOG.debug("Found XML route: {}", xmlRoute);
-                    RoutesDefinition routes = ModelHelper.loadRoutesDefinition(camelContext, xmlRoute.getInputStream());
-                    camelContext.getExtension(Model.class).addRouteDefinitions(routes.getRoutes());
-                }
-            } catch (FileNotFoundException e) {
-                LOG.debug("No XML routes found in {}. Skipping XML routes detection.", part);
-            }
-        }
-    }
-
-    private void loadXmlRests(ApplicationContext applicationContext, CamelContext camelContext, String directory) throws Exception {
-        String[] parts = directory.split(",");
-        for (String part : parts) {
-            LOG.info("Loading additional Camel XML rests from: {}", part);
-            try {
-                final Resource[] xmlRests = applicationContext.getResources(part);
-                for (final Resource xmlRest : xmlRests) {
-                    RestsDefinition rests = ModelHelper.loadRestsDefinition(camelContext, xmlRest.getInputStream());
-                    camelContext.getExtension(Model.class).addRestDefinitions(rests.getRests(), true);
-                }
-            } catch (FileNotFoundException e) {
-                LOG.debug("No XML rests found in {}. Skipping XML rests detection.", part);
-            }
-        }
-    }
-
     private void terminateMainControllerAfter(final CamelContext camelContext, int seconds, final AtomicBoolean completed, final CountDownLatch latch) {
         ScheduledExecutorService executorService = camelContext.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, "CamelSpringBootTerminateTask");
         Runnable task = () -> {
diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SpringBootRoutesCollector.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SpringBootRoutesCollector.java
new file mode 100644
index 0000000..3f5d7d3
--- /dev/null
+++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SpringBootRoutesCollector.java
@@ -0,0 +1,85 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.boot;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.main.BaseRoutesCollector;
+import org.apache.camel.model.ModelHelper;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.rest.RestsDefinition;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.io.Resource;
+
+/**
+ * Spring Boot {@link org.apache.camel.main.RoutesCollector}.
+ */
+public class SpringBootRoutesCollector extends BaseRoutesCollector {
+
+    private final ApplicationContext applicationContext;
+
+    public SpringBootRoutesCollector(ApplicationContext applicationContext) {
+        this.applicationContext = applicationContext;
+    }
+
+    @Override
+    public List<RoutesDefinition> collectXmlRoutesFromDirectory(CamelContext camelContext, String directory) throws Exception {
+        List<RoutesDefinition> answer = new ArrayList<>();
+
+        String[] parts = directory.split(",");
+        for (String part : parts) {
+            log.info("Loading additional Camel XML routes from: {}", part);
+            try {
+                Resource[] xmlRoutes = applicationContext.getResources(part);
+                for (Resource xmlRoute : xmlRoutes) {
+                    log.debug("Found XML route: {}", xmlRoute);
+                    RoutesDefinition routes = ModelHelper.loadRoutesDefinition(camelContext, xmlRoute.getInputStream());
+                    answer.add(routes);
+                }
+            } catch (FileNotFoundException e) {
+                log.debug("No XML routes found in {}. Skipping XML routes detection.", part);
+            }
+        }
+
+        return answer;
+    }
+
+    @Override
+    public List<RestsDefinition> collectXmlRestsFromDirectory(CamelContext camelContext, String directory) throws Exception {
+        List<RestsDefinition> answer = new ArrayList<>();
+
+        String[] parts = directory.split(",");
+        for (String part : parts) {
+            log.info("Loading additional Camel XML rests from: {}", part);
+            try {
+                final Resource[] xmlRests = applicationContext.getResources(part);
+                for (final Resource xmlRest : xmlRests) {
+                    RestsDefinition rests = ModelHelper.loadRestsDefinition(camelContext, xmlRest.getInputStream());
+                    answer.add(rests);
+                }
+            } catch (FileNotFoundException e) {
+                log.debug("No XML rests found in {}. Skipping XML rests detection.", part);
+            }
+        }
+
+        return answer;
+    }
+
+}
diff --git a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/parent/SpringBootRefreshContextTest.java b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/parent/SpringBootRefreshContextTest.java
index 141685d..29d81a0 100644
--- a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/parent/SpringBootRefreshContextTest.java
+++ b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/parent/SpringBootRefreshContextTest.java
@@ -18,7 +18,7 @@ package org.apache.camel.spring.boot.parent;
 
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.spring.boot.RoutesCollector;
+import org.apache.camel.spring.boot.RoutesCollectorListener;
 import org.junit.Test;
 import org.springframework.boot.WebApplicationType;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -36,7 +36,7 @@ public class SpringBootRefreshContextTest {
         parent.refresh();
         ConfigurableApplicationContext context = new SpringApplicationBuilder(Configuration.class).web(WebApplicationType.NONE).parent(parent).run();
         ContextRefreshedEvent refreshEvent = new ContextRefreshedEvent(context);
-        RoutesCollector collector = context.getBean(RoutesCollector.class);
+        RoutesCollectorListener collector = context.getBean(RoutesCollectorListener.class);
         collector.onApplicationEvent(refreshEvent); //no changes should happen here
     }
 
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainRoutesCollector.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseRoutesCollector.java
similarity index 82%
rename from core/camel-main/src/main/java/org/apache/camel/main/MainRoutesCollector.java
rename to core/camel-main/src/main/java/org/apache/camel/main/BaseRoutesCollector.java
index fe5c2da..38cbfb9 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/MainRoutesCollector.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseRoutesCollector.java
@@ -23,6 +23,8 @@ import java.util.Set;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.RoutesBuilder;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.util.AntPathMatcher;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
@@ -32,14 +34,15 @@ import org.slf4j.LoggerFactory;
  * Collects routes and rests from the various sources (like registry or opinionated
  * classpath locations) and injects these into the Camel context.
  */
-public class MainRoutesCollector {
+public abstract class BaseRoutesCollector implements RoutesCollector {
 
     // TODO: Add load routes from xml and rest
     // TODO: Base class and extended for spring-boot etc
+    // TODO: Add to camel main that it uses route collector
 
-    private static final Logger LOG = LoggerFactory.getLogger(MainRoutesCollector.class);
+    protected final Logger log = LoggerFactory.getLogger(getClass());
 
-    public List<RoutesBuilder> collectRoutes(CamelContext camelContext, DefaultConfigurationProperties configurationProperties) {
+    public List<RoutesBuilder> collectRoutesFromRegistry(CamelContext camelContext, DefaultConfigurationProperties configurationProperties) {
         final List<RoutesBuilder> routes = new ArrayList<>();
 
         final AntPathMatcher matcher = new AntPathMatcher();
@@ -63,7 +66,7 @@ public class MainRoutesCollector {
                     for (String part : parts) {
                         // must negate when excluding, and hence !
                         match = !matcher.match(part, name);
-                        LOG.trace("Java RoutesBuilder: {} exclude filter: {} -> {}", name, part, match);
+                        log.trace("Java RoutesBuilder: {} exclude filter: {} -> {}", name, part, match);
                         if (!match) {
                             break;
                         }
@@ -81,7 +84,7 @@ public class MainRoutesCollector {
                     for (String part : parts) {
                         // must negate when excluding, and hence !
                         match = !matcher.match(part, name);
-                        LOG.trace("Java RoutesBuilder: {} exclude filter: {} -> {}", name, part, match);
+                        log.trace("Java RoutesBuilder: {} exclude filter: {} -> {}", name, part, match);
                         if (!match) {
                             break;
                         }
@@ -92,22 +95,25 @@ public class MainRoutesCollector {
                     String[] parts = include.split(",");
                     for (String part : parts) {
                         match = matcher.match(part, name);
-                        LOG.trace("Java RoutesBuilder: {} include filter: {} -> {}", name, part, match);
+                        log.trace("Java RoutesBuilder: {} include filter: {} -> {}", name, part, match);
                         if (match) {
                             break;
                         }
                     }
                 }
-                LOG.debug("Java RoutesBuilder: {} accepted by include/exclude filter: {}", name, match);
+                log.debug("Java RoutesBuilder: {} accepted by include/exclude filter: {}", name, match);
                 if (match) {
                     routes.add(routesBuilder);
                 }
             }
 
-
         }
 
         return routes;
     }
 
+    public abstract List<RoutesDefinition> collectXmlRoutesFromDirectory(CamelContext camelContext, String directory) throws Exception;
+
+    public abstract List<RestsDefinition> collectXmlRestsFromDirectory(CamelContext camelContext, String directory) throws Exception;
+
 }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/RoutesCollector.java b/core/camel-main/src/main/java/org/apache/camel/main/RoutesCollector.java
new file mode 100644
index 0000000..33fabb1
--- /dev/null
+++ b/core/camel-main/src/main/java/org/apache/camel/main/RoutesCollector.java
@@ -0,0 +1,34 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.main;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.rest.RestsDefinition;
+
+public interface RoutesCollector {
+
+    List<RoutesBuilder> collectRoutesFromRegistry(CamelContext camelContext, DefaultConfigurationProperties configurationProperties);
+
+    List<RoutesDefinition> collectXmlRoutesFromDirectory(CamelContext camelContext, String directory) throws Exception;
+
+    List<RestsDefinition> collectXmlRestsFromDirectory(CamelContext camelContext, String directory) throws Exception;
+
+}