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 <claus.ib...@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; + +}