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 5b1147bd47c18a7b57984788b36658db90a301d8
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Thu Oct 17 17:20:49 2019 +0200

    CAMEL-14050: camel-main - Add logic for automatic RouteBuilder class 
detection ala camel-spring-boot has
---
 .../src/main/docs/spring-boot.adoc                 |  3 +-
 .../camel/spring/boot/CamelAutoConfiguration.java  |  8 +-
 .../spring/boot/CamelConfigurationProperties.java  | 10 +++
 ...ava => CamelSpringBootApplicationListener.java} | 75 ++++++-------------
 .../spring/boot/SpringBootRoutesCollector.java     | 11 ++-
 .../boot/parent/SpringBootRefreshContextTest.java  |  4 +-
 .../org/apache/camel/main/BaseRoutesCollector.java | 45 +++++------
 .../camel/main/DefaultConfigurationProperties.java | 30 ++++++++
 .../org/apache/camel/main/RoutesCollector.java     | 37 +++++++--
 .../org/apache/camel/main/RoutesConfigurer.java    | 87 ++++++++++++++++++++++
 .../camel-main-configuration-metadata.json         |  7 ++
 11 files changed, 224 insertions(+), 93 deletions(-)

diff --git a/components/camel-spring-boot/src/main/docs/spring-boot.adoc 
b/components/camel-spring-boot/src/main/docs/spring-boot.adoc
index 73a8678..89a5c30 100644
--- a/components/camel-spring-boot/src/main/docs/spring-boot.adoc
+++ b/components/camel-spring-boot/src/main/docs/spring-boot.adoc
@@ -89,7 +89,7 @@ When using Spring Boot make sure to use the following Maven 
dependency to have s
 ----
 
 
-The component supports 139 options, which are listed below.
+The component supports 140 options, which are listed below.
 
 
 
@@ -182,6 +182,7 @@ The component supports 139 options, which are listed below.
 | *camel.springboot.producer-template-cache-size* | Producer template 
endpoints cache size. | 1000 | Integer
 | *camel.springboot.route-filter-exclude-pattern* | Used for filtering routes 
routes matching the given pattern, which follows the following rules: - Match 
by route id - Match by route input endpoint uri The matching is using exact 
match, by wildcard and regular expression. For example to only include routes 
which starts with foo in their route id's, use: include=foo&#42; And to exclude 
routes which starts from JMS endpoints, use: exclude=jms:&#42; Multiple 
patterns can be separated by c [...]
 | *camel.springboot.route-filter-include-pattern* | Used for filtering routes 
routes matching the given pattern, which follows the following rules: - Match 
by route id - Match by route input endpoint uri The matching is using exact 
match, by wildcard and regular expression. For example to only include routes 
which starts with foo in their route id's, use: include=foo&#42; And to exclude 
routes which starts from JMS endpoints, use: exclude=jms:&#42; Multiple 
patterns can be separated by c [...]
+| *camel.springboot.routes-collector-enabled* | Whether the routes collector 
is enabled or not. When enabled Camel will auto-discover routes (RouteBuilder 
instances from the registry and also load additional XML routes from the file 
system. The routes collector is default enabled. | true | Boolean
 | *camel.springboot.shutdown-log-inflight-exchanges-on-timeout* | Sets whether 
to log information about the inflight Exchanges which are still running during 
a shutdown which didn't complete without the given timeout. | true | Boolean
 | *camel.springboot.shutdown-now-on-timeout* | Sets whether to force shutdown 
of all consumers when a timeout occurred and thus not all consumers was 
shutdown within that period. You should have good reasons to set this option to 
false as it means that the routes keep running and is halted abruptly when 
CamelContext has been shutdown. | true | Boolean
 | *camel.springboot.shutdown-routes-in-reverse-order* | Sets whether routes 
should be shutdown in reverse or the same order as they where started. | true | 
Boolean
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 c155230..b1c73ea 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
@@ -149,11 +149,11 @@ public class CamelAutoConfiguration {
     }
 
     @Bean
-    @ConditionalOnMissingBean(RoutesCollectorListener.class)
-    RoutesCollectorListener routesCollectorListener(ApplicationContext 
applicationContext, CamelConfigurationProperties config,
-                                                    RoutesCollector 
routesCollector) {
+    @ConditionalOnMissingBean(CamelSpringBootApplicationListener.class)
+    CamelSpringBootApplicationListener 
routesCollectorListener(ApplicationContext applicationContext, 
CamelConfigurationProperties config,
+                                                               RoutesCollector 
routesCollector) {
         Collection<CamelContextConfiguration> configurations = 
applicationContext.getBeansOfType(CamelContextConfiguration.class).values();
-        return new RoutesCollectorListener(applicationContext, new 
ArrayList(configurations), config, routesCollector);
+        return new CamelSpringBootApplicationListener(applicationContext, new 
ArrayList(configurations), config, routesCollector);
     }
 
     /**
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
index 8e06364..f1c36fa 100644
--- 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelConfigurationProperties.java
@@ -408,6 +408,16 @@ public class CamelConfigurationProperties extends 
DefaultConfigurationProperties
     private LoggingLevel beanIntrospectionLoggingLevel;
 
     /**
+     * Whether the routes collector is enabled or not.
+     *
+     * When enabled Camel will auto-discover routes (RouteBuilder instances 
from the registry and
+     * also load additional XML routes from the file system.
+     *
+     * The routes collector is default enabled.
+     */
+    private boolean routesCollectorEnabled = true;
+
+    /**
      * Used for inclusive filtering component scanning of RouteBuilder classes 
with @Component annotation.
      * The exclusive filtering takes precedence over inclusive filtering.
      * The pattern is using Ant-path style pattern.
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollectorListener.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelSpringBootApplicationListener.java
similarity index 80%
rename from 
components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollectorListener.java
rename to 
components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelSpringBootApplicationListener.java
index 0c7c4fc..ed0eca1 100644
--- 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/RoutesCollectorListener.java
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelSpringBootApplicationListener.java
@@ -25,18 +25,14 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 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.RoutesCollector;
-import org.apache.camel.model.Model;
-import org.apache.camel.model.RoutesDefinition;
-import org.apache.camel.model.rest.RestsDefinition;
+import org.apache.camel.main.RoutesConfigurer;
 import org.apache.camel.spi.CamelEvent;
 import org.apache.camel.spi.CamelEvent.Type;
 import org.apache.camel.spi.EventNotifier;
 import org.apache.camel.support.EventNotifierSupport;
-import org.apache.camel.support.OrderedComparator;
 import org.apache.camel.support.service.ServiceHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,30 +43,31 @@ import 
org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.core.Ordered;
 
 /**
- * Collects routes and rests from the various sources (like Spring application 
context beans registry or opinionated
+ * A spring application listener that when spring boot is starting (refresh 
event) will setup Camel by:
+ * <p>
+ * 1. collecting routes and rests from the various sources (like Spring 
application context beans registry or opinionated
  * classpath locations) and injects these into the Camel context.
+ * 2. setting up Camel main controller if enabled.
+ * 3. setting up run duration if in use.
  */
-public class RoutesCollectorListener implements 
ApplicationListener<ContextRefreshedEvent>, Ordered {
+public class CamelSpringBootApplicationListener implements 
ApplicationListener<ContextRefreshedEvent>, Ordered {
 
     // Static collaborators
 
-    private static final Logger LOG = 
LoggerFactory.getLogger(RoutesCollectorListener.class);
+    private static final Logger LOG = 
LoggerFactory.getLogger(CamelSpringBootApplicationListener.class);
 
     // Collaborators
 
     private final ApplicationContext applicationContext;
-
     private final List<CamelContextConfiguration> camelContextConfigurations;
-
     private final CamelConfigurationProperties configurationProperties;
-
     private final RoutesCollector springBootRoutesCollector;
 
     // Constructors
 
-    public RoutesCollectorListener(ApplicationContext applicationContext, 
List<CamelContextConfiguration> camelContextConfigurations,
-                                   CamelConfigurationProperties 
configurationProperties,
-                                   RoutesCollector springBootRoutesCollector) {
+    public CamelSpringBootApplicationListener(ApplicationContext 
applicationContext, List<CamelContextConfiguration> camelContextConfigurations,
+                                              CamelConfigurationProperties 
configurationProperties,
+                                              RoutesCollector 
springBootRoutesCollector) {
         this.applicationContext = applicationContext;
         this.camelContextConfigurations = new 
ArrayList<>(camelContextConfigurations);
         this.configurationProperties = configurationProperties;
@@ -88,42 +85,18 @@ public class RoutesCollectorListener implements 
ApplicationListener<ContextRefre
                 && camelContext.getStatus().isStopped()) {
             LOG.debug("Post-processing CamelContext bean: {}", 
camelContext.getName());
 
-            final List<RoutesBuilder> routes = 
springBootRoutesCollector.collectRoutesFromRegistry(camelContext, 
configurationProperties);
+            if (configurationProperties.isRoutesCollectorEnabled()) {
+                LOG.debug("RoutesCollectorEnabled: {}", 
springBootRoutesCollector);
+                RoutesConfigurer configurer = new 
RoutesConfigurer(springBootRoutesCollector);
+                configurer.configureRoutes(camelContext, 
configurationProperties);
+            }
 
-            // sort routes according to ordered
-            routes.sort(OrderedComparator.get());
-            // then add the routes
-            for (RoutesBuilder routesBuilder : routes) {
-                try {
-                    LOG.debug("Injecting following route into the 
CamelContext: {}", routesBuilder);
-                    camelContext.addRoutes(routesBuilder);
-                } catch (Exception e) {
-                    throw new CamelSpringBootInitializationException(e);
-                }
+            for (CamelContextConfiguration camelContextConfiguration : 
camelContextConfigurations) {
+                LOG.debug("CamelContextConfiguration found. Invoking 
beforeApplicationStart: {}", camelContextConfiguration);
+                camelContextConfiguration.beforeApplicationStart(camelContext);
             }
 
             try {
-                boolean scan = 
!configurationProperties.getXmlRoutes().equals("false");
-                if (scan) {
-                    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) {
-                    List<RestsDefinition> defs = 
springBootRoutesCollector.collectXmlRestsFromDirectory(camelContext, 
configurationProperties.getXmlRests());
-                    for (RestsDefinition def : defs) {
-                        
camelContext.getExtension(Model.class).addRestDefinitions(def.getRests(), true);
-                    }
-                }
-
-                for (CamelContextConfiguration camelContextConfiguration : 
camelContextConfigurations) {
-                    LOG.debug("CamelContextConfiguration found. Invoking 
beforeApplicationStart: {}", camelContextConfiguration);
-                    
camelContextConfiguration.beforeApplicationStart(camelContext);
-                }
-
                 if (configurationProperties.isMainRunController()) {
                     CamelMainRunController controller = new 
CamelMainRunController(applicationContext, camelContext);
 
@@ -136,8 +109,8 @@ public class RoutesCollectorListener implements 
ApplicationListener<ContextRefre
                         }
                         // register lifecycle so we can trigger to shutdown 
the JVM when maximum number of messages has been processed
                         EventNotifier notifier = new 
MainDurationEventNotifier(camelContext,
-                            configurationProperties.getDurationMaxMessages(), 
configurationProperties.getDurationMaxIdleSeconds(),
-                            controller.getCompleted(), controller.getLatch(), 
true);
+                                
configurationProperties.getDurationMaxMessages(), 
configurationProperties.getDurationMaxIdleSeconds(),
+                                controller.getCompleted(), 
controller.getLatch(), true);
                         // register our event notifier
                         ServiceHelper.startService(notifier);
                         
camelContext.getManagementStrategy().addEventNotifier(notifier);
@@ -146,7 +119,7 @@ public class RoutesCollectorListener implements 
ApplicationListener<ContextRefre
                     if (configurationProperties.getDurationMaxSeconds() > 0) {
                         LOG.info("CamelSpringBoot will terminate after {} 
seconds", configurationProperties.getDurationMaxSeconds());
                         terminateMainControllerAfter(camelContext, 
configurationProperties.getDurationMaxSeconds(),
-                            controller.getCompleted(), controller.getLatch());
+                                controller.getCompleted(), 
controller.getLatch());
                     }
 
                     camelContext.addStartupListener(new StartupListener() {
@@ -185,8 +158,8 @@ public class RoutesCollectorListener implements 
ApplicationListener<ContextRefre
 
                             // register lifecycle so we can trigger to 
shutdown the JVM when maximum number of messages has been processed
                             EventNotifier notifier = new 
MainDurationEventNotifier(camelContext,
-                                
configurationProperties.getDurationMaxMessages(), 
configurationProperties.getDurationMaxIdleSeconds(),
-                                completed, latch, false);
+                                    
configurationProperties.getDurationMaxMessages(), 
configurationProperties.getDurationMaxIdleSeconds(),
+                                    completed, latch, false);
                             // register our event notifier
                             ServiceHelper.startService(notifier);
                             
camelContext.getManagementStrategy().addEventNotifier(notifier);
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
index 3f5d7d3..e2a30a1 100644
--- 
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
@@ -21,7 +21,10 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.main.BaseRoutesCollector;
+import org.apache.camel.main.DefaultConfigurationProperties;
 import org.apache.camel.model.ModelHelper;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
@@ -40,7 +43,7 @@ public class SpringBootRoutesCollector extends 
BaseRoutesCollector {
     }
 
     @Override
-    public List<RoutesDefinition> collectXmlRoutesFromDirectory(CamelContext 
camelContext, String directory) throws Exception {
+    public List<RoutesDefinition> collectXmlRoutesFromDirectory(CamelContext 
camelContext, String directory) {
         List<RoutesDefinition> answer = new ArrayList<>();
 
         String[] parts = directory.split(",");
@@ -55,6 +58,8 @@ public class SpringBootRoutesCollector extends 
BaseRoutesCollector {
                 }
             } catch (FileNotFoundException e) {
                 log.debug("No XML routes found in {}. Skipping XML routes 
detection.", part);
+            } catch (Exception e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
             }
         }
 
@@ -62,7 +67,7 @@ public class SpringBootRoutesCollector extends 
BaseRoutesCollector {
     }
 
     @Override
-    public List<RestsDefinition> collectXmlRestsFromDirectory(CamelContext 
camelContext, String directory) throws Exception {
+    public List<RestsDefinition> collectXmlRestsFromDirectory(CamelContext 
camelContext, String directory) {
         List<RestsDefinition> answer = new ArrayList<>();
 
         String[] parts = directory.split(",");
@@ -76,6 +81,8 @@ public class SpringBootRoutesCollector extends 
BaseRoutesCollector {
                 }
             } catch (FileNotFoundException e) {
                 log.debug("No XML rests found in {}. Skipping XML rests 
detection.", part);
+            } catch (Exception e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
             }
         }
 
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 29d81a0..e8ed75d 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.RoutesCollectorListener;
+import org.apache.camel.spring.boot.CamelSpringBootApplicationListener;
 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);
-        RoutesCollectorListener collector = 
context.getBean(RoutesCollectorListener.class);
+        CamelSpringBootApplicationListener collector = 
context.getBean(CamelSpringBootApplicationListener.class);
         collector.onApplicationEvent(refreshEvent); //no changes should happen 
here
     }
 
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/BaseRoutesCollector.java 
b/core/camel-main/src/main/java/org/apache/camel/main/BaseRoutesCollector.java
index 38cbfb9..17fe2a3 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/BaseRoutesCollector.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/BaseRoutesCollector.java
@@ -1,13 +1,13 @@
-/**
+/*
  * 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>
+ *
+ *      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.
@@ -23,26 +23,23 @@ 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;
 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.
+ * Base {@link RoutesCollector}.
  */
 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
 
     protected final Logger log = LoggerFactory.getLogger(getClass());
 
-    public List<RoutesBuilder> collectRoutesFromRegistry(CamelContext 
camelContext, DefaultConfigurationProperties configurationProperties) {
+    @Override
+    public List<RoutesBuilder> collectRoutesFromRegistry(CamelContext 
camelContext,
+                                                         String 
excludePattern, String includePattern) {
         final List<RoutesBuilder> routes = new ArrayList<>();
 
         final AntPathMatcher matcher = new AntPathMatcher();
@@ -55,14 +52,11 @@ public abstract class BaseRoutesCollector implements 
RoutesCollector {
                 // make name as path so we can use ant path matcher
                 name = name.replace('.', '/');
 
-                String exclude = 
configurationProperties.getJavaRoutesExcludePattern();
-                String include = 
configurationProperties.getJavaRoutesIncludePattern();
-
-                boolean match = !"false".equals(include);
+                boolean match = !"false".equals(includePattern);
                 // exclude take precedence over include
-                if (match && ObjectHelper.isNotEmpty(exclude)) {
+                if (match && ObjectHelper.isNotEmpty(excludePattern)) {
                     // there may be multiple separated by comma
-                    String[] parts = exclude.split(",");
+                    String[] parts = excludePattern.split(",");
                     for (String part : parts) {
                         // must negate when excluding, and hence !
                         match = !matcher.match(part, name);
@@ -73,14 +67,14 @@ public abstract class BaseRoutesCollector implements 
RoutesCollector {
                     }
                 }
                 // special support for testing with @ExcludeRoutes annotation 
with camel-test-spring
-                exclude = System.getProperty("CamelTestSpringExcludeRoutes");
+                excludePattern = 
System.getProperty("CamelTestSpringExcludeRoutes");
                 // exclude take precedence over include
-                if (match && ObjectHelper.isNotEmpty(exclude)) {
+                if (match && ObjectHelper.isNotEmpty(excludePattern)) {
                     // this property is a comma separated list of FQN class 
names, so we need to make
                     // name as path so we can use ant patch matcher
-                    exclude = exclude.replace('.', '/');
+                    excludePattern = excludePattern.replace('.', '/');
                     // there may be multiple separated by comma
-                    String[] parts = exclude.split(",");
+                    String[] parts = excludePattern.split(",");
                     for (String part : parts) {
                         // must negate when excluding, and hence !
                         match = !matcher.match(part, name);
@@ -90,9 +84,9 @@ public abstract class BaseRoutesCollector implements 
RoutesCollector {
                         }
                     }
                 }
-                if (match && ObjectHelper.isNotEmpty(include)) {
+                if (match && ObjectHelper.isNotEmpty(includePattern)) {
                     // there may be multiple separated by comma
-                    String[] parts = include.split(",");
+                    String[] parts = includePattern.split(",");
                     for (String part : parts) {
                         match = matcher.match(part, name);
                         log.trace("Java RoutesBuilder: {} include filter: {} 
-> {}", name, part, match);
@@ -106,14 +100,9 @@ public abstract class BaseRoutesCollector implements 
RoutesCollector {
                     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/DefaultConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index e8794c5..b0c0271 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -71,6 +71,7 @@ public abstract class DefaultConfigurationProperties<T> {
     private String routeFilterExcludePattern;
     private boolean beanIntrospectionExtendedStatistics;
     private LoggingLevel beanIntrospectionLoggingLevel;
+    private boolean routesCollectorEnabled = true;
     private String javaRoutesIncludePattern;
     private String javaRoutesExcludePattern;
     private String xmlRoutes = "classpath:camel/*.xml";
@@ -708,6 +709,22 @@ public abstract class DefaultConfigurationProperties<T> {
         this.beanIntrospectionLoggingLevel = beanIntrospectionLoggingLevel;
     }
 
+    public boolean isRoutesCollectorEnabled() {
+        return routesCollectorEnabled;
+    }
+
+    /**
+     * Whether the routes collector is enabled or not.
+     * 
+     * When enabled Camel will auto-discover routes (RouteBuilder instances 
from the registry and
+     * also load additional XML routes from the file system.
+     *
+     * The routes collector is default enabled.
+     */
+    public void setRoutesCollectorEnabled(boolean routesCollectorEnabled) {
+        this.routesCollectorEnabled = routesCollectorEnabled;
+    }
+
     public String getJavaRoutesIncludePattern() {
         return javaRoutesIncludePattern;
     }
@@ -1277,6 +1294,19 @@ public abstract class DefaultConfigurationProperties<T> {
     }
 
     /**
+     * Whether the routes collector is enabled or not.
+     *
+     * When enabled Camel will auto-discover routes (RouteBuilder instances 
from the registry and
+     * also load additional XML routes from the file system.
+     *
+     * The routes collector is default enabled.
+     */
+    public T withRoutesCollectorEnabled(boolean routesCollectorEnabled) {
+        this.routesCollectorEnabled = routesCollectorEnabled;
+        return (T) this;
+    }
+
+    /**
      * Used for inclusive filtering component scanning of RouteBuilder classes 
with @Component annotation.
      * The exclusive filtering takes precedence over inclusive filtering.
      * The pattern is using Ant-path style pattern.
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
index 33fabb1..b8e9648 100644
--- 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
@@ -1,13 +1,13 @@
-/**
+/*
  * 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>
+ *
+ *      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.
@@ -23,12 +23,39 @@ import org.apache.camel.RoutesBuilder;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 
+/**
+ * Collects routes and rests from the various sources (like registry or 
opinionated
+ * classpath locations) and injects these into the Camel context.
+ */
 public interface RoutesCollector {
 
-    List<RoutesBuilder> collectRoutesFromRegistry(CamelContext camelContext, 
DefaultConfigurationProperties configurationProperties);
+    /**
+     * Collects the {@link RoutesBuilder} instances which was discovered from 
the {@link org.apache.camel.spi.Registry} such as
+     * Spring or CDI bean containers.
+     *
+     * @param camelContext        the Camel Context
+     * @param excludePattern      exclude pattern (see 
javaRoutesExcludePattern option)
+     * @param includePattern      include pattern  (see 
javaRoutesIncludePattern option)
+     * @return the discovered routes or an empty list
+     */
+    List<RoutesBuilder> collectRoutesFromRegistry(CamelContext camelContext, 
String excludePattern, String includePattern);
 
+    /**
+     * Collects all XML routes from the given directory.
+     *
+     * @param camelContext               the Camel Context
+     * @param directory                  the directory (see xmlRoutes option)
+     * @return the discovered routes or an empty list
+     */
     List<RoutesDefinition> collectXmlRoutesFromDirectory(CamelContext 
camelContext, String directory) throws Exception;
 
+    /**
+     * Collects all XML rests from the given directory.
+     *
+     * @param camelContext               the Camel Context
+     * @param directory                  the directory (see xmlRests option)
+     * @return the discovered rests or an empty list
+     */
     List<RestsDefinition> collectXmlRestsFromDirectory(CamelContext 
camelContext, String directory) throws Exception;
 
 }
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java 
b/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java
new file mode 100644
index 0000000..fd18ad4
--- /dev/null
+++ b/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java
@@ -0,0 +1,87 @@
+/**
+ * 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.RuntimeCamelException;
+import org.apache.camel.model.Model;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.rest.RestsDefinition;
+import org.apache.camel.support.OrderedComparator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * To configure routes using {@link RoutesCollector} which collects the routes 
from various sources.
+ */
+public class RoutesConfigurer {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(RoutesConfigurer.class);
+
+    private final RoutesCollector routesCollector;
+
+    public RoutesConfigurer(RoutesCollector routesCollector) {
+        this.routesCollector = routesCollector;
+    }
+
+    /**
+     * Collects routes and rests from the various sources (like registry or 
opinionated
+     * classpath locations) and injects these into the Camel context.
+     *
+     * @param camelContext  the Camel Context
+     * @param config        the configuration
+     */
+    public void configureRoutes(CamelContext camelContext, 
DefaultConfigurationProperties config) {
+        if (config.isRoutesCollectorEnabled()) {
+            try {
+                LOG.debug("RoutesCollectorEnabled: {}", routesCollector);
+                final List<RoutesBuilder> routes = 
routesCollector.collectRoutesFromRegistry(camelContext,
+                        config.getJavaRoutesExcludePattern(),
+                        config.getJavaRoutesIncludePattern());
+
+                // sort routes according to ordered
+                routes.sort(OrderedComparator.get());
+                // then add the routes
+                for (RoutesBuilder routesBuilder : routes) {
+                    LOG.debug("Injecting following route into the 
CamelContext: {}", routesBuilder);
+                    camelContext.addRoutes(routesBuilder);
+                }
+
+                boolean scan = !config.getXmlRoutes().equals("false");
+                if (scan) {
+                    List<RoutesDefinition> defs = 
routesCollector.collectXmlRoutesFromDirectory(camelContext, 
config.getXmlRoutes());
+                    for (RoutesDefinition def : defs) {
+                        
camelContext.getExtension(Model.class).addRouteDefinitions(def.getRoutes());
+                    }
+                }
+
+                boolean scanRests = !config.getXmlRests().equals("false");
+                if (scanRests) {
+                    List<RestsDefinition> defs = 
routesCollector.collectXmlRestsFromDirectory(camelContext, 
config.getXmlRests());
+                    for (RestsDefinition def : defs) {
+                        
camelContext.getExtension(Model.class).addRestDefinitions(def.getRests(), true);
+                    }
+                }
+            } catch (Exception e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
+            }
+        }
+    }
+}
diff --git 
a/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
index e0c3bfe..67616b3 100644
--- 
a/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
@@ -249,6 +249,13 @@
                        "description":"Used for filtering routes routes 
matching the given pattern, which follows the following rules: - Match by route 
id - Match by route input endpoint uri The matching is using exact match, by 
wildcard and regular expression as documented by 
PatternHelper#matchPattern(String,String) . For example to only include routes 
which starts with foo in their route id's, use: include=foo&#42; And to exclude 
routes which starts from JMS endpoints, use: exclude=jms:&#42; Multiple patt 
[...]
                },
                {
+                       "name":"camel.main.routes-collector-enabled",
+                       "type":"boolean",
+                       
"sourceType":"org.apache.camel.main.DefaultConfigurationProperties",
+                       "description":"Whether the routes collector is enabled 
or not. When enabled Camel will auto-discover routes (RouteBuilder instances 
from the registry and also load additional XML routes from the file system. The 
routes collector is default enabled.",
+                       "defaultValue":"true"
+               },
+               {
                        
"name":"camel.main.shutdown-log-inflight-exchanges-on-timeout",
                        "type":"boolean",
                        
"sourceType":"org.apache.camel.main.DefaultConfigurationProperties",

Reply via email to