Repository: camel Updated Branches: refs/heads/master 657be686d -> a65171f4c
CAMEL-11061: service call eip: add an option to set global defaults Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a65171f4 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a65171f4 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a65171f4 Branch: refs/heads/master Commit: a65171f4c39e9cb7bd284021cb73ea2b6bcd4bb7 Parents: 657be68 Author: lburgazzoli <lburgazz...@gmail.com> Authored: Fri Mar 24 10:52:15 2017 +0100 Committer: lburgazzoli <lburgazz...@gmail.com> Committed: Fri Mar 24 10:52:34 2017 +0100 ---------------------------------------------------------------------- .../ServiceCallConfigurationDefinition.java | 16 ++ .../model/cloud/ServiceCallDefinition.java | 16 ++ components/camel-spring-boot/pom.xml | 5 - .../CamelCloudConfigurationProperties.java | 157 +++++++++++++++++-- ...rviceCallConfigurationAutoConfiguration.java | 71 +++++++++ ...lCloudServiceDiscoveryAutoConfiguration.java | 76 +++++++-- ...amelCloudServiceFilterAutoConfiguration.java | 78 +++++++-- .../main/resources/META-INF/spring.factories | 1 + .../CamelCloudServiceCallConfigurationTest.java | 2 +- .../CamelCloudServiceCallExpressionTest.java | 90 +++++++++++ ...CloudServiceCallGlobalConfigurationTest.java | 97 ++++++++++++ .../boot/cloud/CamelCloudServiceCallTest.java | 4 +- .../src/test/resources/application.properties | 2 +- .../cloud/CamelSpringCloudDiscoveryClient.java | 1 - ...ngCloudDiscoveryClientAutoConfiguration.java | 2 - .../cloud/CamelSpringCloudLoadBalancer.java | 1 - ...pringCloudLoadBalancerAutoConfiguration.java | 3 - 17 files changed, 566 insertions(+), 56 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java index 6a910b9..005682a 100644 --- a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java @@ -31,6 +31,7 @@ import org.apache.camel.cloud.ServiceChooser; import org.apache.camel.cloud.ServiceDiscovery; import org.apache.camel.cloud.ServiceFilter; import org.apache.camel.model.IdentifiedType; +import org.apache.camel.model.language.SimpleExpression; import org.apache.camel.spi.Metadata; /** @@ -245,6 +246,13 @@ public class ServiceCallConfigurationDefinition extends IdentifiedType { this.expression = expression; } + /** + * Set a custom {@link Expression} using the {@link org.apache.camel.language.simple.SimpleLanguage} + */ + public void setSimpleExpression(String expression) { + setExpression(new SimpleExpression(expression)); + } + public ServiceCallServiceDiscoveryConfiguration getServiceDiscoveryConfiguration() { return serviceDiscoveryConfiguration; } @@ -405,6 +413,14 @@ public class ServiceCallConfigurationDefinition extends IdentifiedType { } /** + * Set a custom {@link Expression} using the {@link org.apache.camel.language.simple.SimpleLanguage} + */ + public ServiceCallConfigurationDefinition simpleExpression(String expression) { + setExpression(new SimpleExpression(expression)); + return this; + } + + /** * Configures the ServiceDiscovery using the given configuration. */ public ServiceCallConfigurationDefinition serviceDiscoveryConfiguration(ServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration) { http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java index 2fd4ed4..98a9bf7 100644 --- a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java @@ -46,6 +46,7 @@ import org.apache.camel.impl.cloud.PassThroughServiceFilter; import org.apache.camel.impl.cloud.RandomServiceChooser; import org.apache.camel.impl.cloud.RoundRobinServiceChooser; import org.apache.camel.model.NoOutputDefinition; +import org.apache.camel.model.language.SimpleExpression; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.RouteContext; import org.apache.camel.util.ObjectHelper; @@ -306,6 +307,13 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit this.expression = expression; } + /** + * Set a custom {@link Expression} using the {@link org.apache.camel.language.simple.SimpleLanguage} + */ + public void setSimpleExpression(String expression) { + setExpression(new SimpleExpression(expression)); + } + public ServiceCallServiceDiscoveryConfiguration getServiceDiscoveryConfiguration() { return serviceDiscoveryConfiguration; } @@ -475,6 +483,14 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit } /** + * Set a custom {@link Expression} using the {@link org.apache.camel.language.simple.SimpleLanguage} + */ + public ServiceCallDefinition simpleExpression(String expression) { + setExpression(new SimpleExpression(expression)); + return this; + } + + /** * Configures the ServiceDiscovery using the given configuration. */ public ServiceCallDefinition serviceDiscoveryConfiguration(ServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration) { http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/pom.xml b/components/camel-spring-boot/pom.xml index 50cc2a4..f17f90f 100644 --- a/components/camel-spring-boot/pom.xml +++ b/components/camel-spring-boot/pom.xml @@ -104,11 +104,6 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> - <artifactId>camel-http</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.camel</groupId> <artifactId>camel-netty4-http</artifactId> <scope>test</scope> </dependency> http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudConfigurationProperties.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudConfigurationProperties.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudConfigurationProperties.java index 6152547..1742745 100644 --- a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudConfigurationProperties.java +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudConfigurationProperties.java @@ -20,11 +20,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.camel.Expression; +import org.apache.camel.model.cloud.ServiceCallConstants; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "camel.cloud") public class CamelCloudConfigurationProperties { private boolean enabled = true; + private ServiceCall serviceCall = new ServiceCall(); private LoadBalancer loadBalancer = new LoadBalancer(); private ServiceDiscovery serviceDiscovery = new ServiceDiscovery(); private ServiceFilter serviceFilter = new ServiceFilter(); @@ -38,6 +41,10 @@ public class CamelCloudConfigurationProperties { this.enabled = enabled; } + public ServiceCall getServiceCall() { + return serviceCall; + } + public LoadBalancer getLoadBalancer() { return loadBalancer; } @@ -55,25 +62,109 @@ public class CamelCloudConfigurationProperties { } // ***************************************** - // Nested configurations + // Service Call // ***************************************** - public static class LoadBalancer { - private boolean enabled = true; + public class ServiceCall { + /** + * The uri of the endpoint to send to. + * The uri can be dynamic computed using the {@link org.apache.camel.language.simple.SimpleLanguage} expression. + */ + private String uri; - public boolean isEnabled() { - return enabled; + /** + * The component to use. + */ + private String component = ServiceCallConstants.DEFAULT_COMPONENT; + + /** + * A reference to the {@link org.apache.camel.cloud.ServiceDiscovery} to use. + */ + private String serviceDiscovery; + + /** + * A reference to the {@link org.apache.camel.cloud.ServiceFilter} to use. + */ + private String serviceFilter; + + /** + * A reference to the {@link org.apache.camel.cloud.ServiceChooser} to use. + */ + private String serviceChooser; + + /** + * A reference to the {@link org.apache.camel.cloud.LoadBalancer} to use. + */ + private String loadBalancer; + + /** + * Set a custom {@link Expression} using the {@link org.apache.camel.language.simple.SimpleLanguage} + */ + private String expression; + + public String getUri() { + return uri; } - public void setEnabled(boolean enabled) { - this.enabled = enabled; + public void setUri(String uri) { + this.uri = uri; + } + + public String getComponent() { + return component; + } + + public void setComponent(String component) { + this.component = component; + } + + public String getServiceDiscovery() { + return serviceDiscovery; + } + + public void setServiceDiscovery(String serviceDiscovery) { + this.serviceDiscovery = serviceDiscovery; + } + + public String getServiceFilter() { + return serviceFilter; + } + + public void setServiceFilter(String serviceFilter) { + this.serviceFilter = serviceFilter; + } + + public String getServiceChooser() { + return serviceChooser; + } + + public void setServiceChooser(String serviceChooser) { + this.serviceChooser = serviceChooser; + } + + public String getLoadBalancer() { + return loadBalancer; + } + + public void setLoadBalancer(String loadBalancer) { + this.loadBalancer = loadBalancer; + } + + public String getExpression() { + return expression; + } + + public void setExpression(String expression) { + this.expression = expression; } } - public static class ServiceDiscovery { + // ***************************************** + // Load Balancer + // ***************************************** + + public static class LoadBalancer { private boolean enabled = true; - private Map<String, List<String>> services = new HashMap<>(); - private String cacheTimeout; public boolean isEnabled() { return enabled; @@ -82,6 +173,15 @@ public class CamelCloudConfigurationProperties { public void setEnabled(boolean enabled) { this.enabled = enabled; } + } + + // ***************************************** + // Service Discovery + // ***************************************** + + public static class ServiceDiscoveryConfiguration { + private Map<String, List<String>> services = new HashMap<>(); + private String cacheTimeout; public Map<String, List<String>> getServices() { return services; @@ -96,9 +196,9 @@ public class CamelCloudConfigurationProperties { } } - public static class ServiceFilter { + public static class ServiceDiscovery extends ServiceDiscoveryConfiguration { private boolean enabled = true; - private Map<String, List<String>> blacklist = new HashMap<>(); + private Map<String, ServiceDiscoveryConfiguration> configurations = new HashMap<>(); public boolean isEnabled() { return enabled; @@ -108,11 +208,44 @@ public class CamelCloudConfigurationProperties { this.enabled = enabled; } + public Map<String, ServiceDiscoveryConfiguration> getConfigurations() { + return configurations; + } + } + + // ***************************************** + // Service Filter + // ***************************************** + + public static class ServiceFilterConfiguration { + private Map<String, List<String>> blacklist = new HashMap<>(); + public Map<String, List<String>> getBlacklist() { return blacklist; } } + public static class ServiceFilter extends ServiceFilterConfiguration { + private boolean enabled = true; + private Map<String, ServiceFilterConfiguration> configurations = new HashMap<>(); + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Map<String, ServiceFilterConfiguration> getConfigurations() { + return configurations; + } + } + + // ***************************************** + // Service Chooser + // ***************************************** + public static class ServiceChooser { private boolean enabled = true; http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationAutoConfiguration.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationAutoConfiguration.java new file mode 100644 index 0000000..12bc414 --- /dev/null +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationAutoConfiguration.java @@ -0,0 +1,71 @@ +/** + * 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.boot.cloud; + +import org.apache.camel.CamelContext; +import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; +import org.apache.camel.model.cloud.ServiceCallConstants; +import org.apache.camel.spring.boot.util.GroupCondition; +import org.apache.camel.util.ObjectHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; + +@Configuration +@ConditionalOnBean({ CamelCloudAutoConfiguration.class, CamelContext.class}) +@EnableConfigurationProperties(CamelCloudConfigurationProperties.class) +@Conditional(CamelCloudServiceCallConfigurationAutoConfiguration.ServiceCallCondition.class) +public class CamelCloudServiceCallConfigurationAutoConfiguration { + @Autowired + private CamelContext camelContext; + @Autowired + private CamelCloudConfigurationProperties configurationProperties; + + @Lazy + @Bean(name = ServiceCallConstants.DEFAULT_SERVICE_CALL_CONFIG_ID) + @ConditionalOnMissingBean(name = ServiceCallConstants.DEFAULT_SERVICE_CALL_CONFIG_ID) + public ServiceCallConfigurationDefinition serviceCallConfiguration() throws Exception { + ServiceCallConfigurationDefinition definition = new ServiceCallConfigurationDefinition(); + ObjectHelper.ifNotEmpty(configurationProperties.getServiceCall().getComponent(), definition::setComponent); + ObjectHelper.ifNotEmpty(configurationProperties.getServiceCall().getUri(), definition::setUri); + ObjectHelper.ifNotEmpty(configurationProperties.getServiceCall().getServiceDiscovery(), definition::setServiceDiscoveryRef); + ObjectHelper.ifNotEmpty(configurationProperties.getServiceCall().getServiceFilter(), definition::setServiceFilterRef); + ObjectHelper.ifNotEmpty(configurationProperties.getServiceCall().getServiceChooser(), definition::setServiceChooserRef); + ObjectHelper.ifNotEmpty(configurationProperties.getServiceCall().getLoadBalancer(), definition::setLoadBalancerRef); + ObjectHelper.ifNotEmpty(configurationProperties.getServiceCall().getExpression(), definition::setSi); + + return definition; + } + + // ******************************* + // Condition + // ******************************* + + public static class ServiceCallCondition extends GroupCondition { + public ServiceCallCondition() { + super( + "camel.cloud", + "camel.cloud.service-call" + ); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceDiscoveryAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceDiscoveryAutoConfiguration.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceDiscoveryAutoConfiguration.java index 9595063..06ef3d7 100644 --- a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceDiscoveryAutoConfiguration.java +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceDiscoveryAutoConfiguration.java @@ -17,14 +17,25 @@ package org.apache.camel.spring.boot.cloud; +import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.annotation.PostConstruct; import org.apache.camel.CamelContext; import org.apache.camel.NoTypeConversionAvailableException; import org.apache.camel.cloud.ServiceDiscovery; import org.apache.camel.impl.cloud.StaticServiceDiscovery; +import org.apache.camel.model.HystrixConfigurationDefinition; import org.apache.camel.spring.boot.util.GroupCondition; +import org.apache.camel.util.IntrospectionSupport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -34,27 +45,31 @@ import org.springframework.context.annotation.Lazy; @Configuration @EnableConfigurationProperties(CamelCloudConfigurationProperties.class) @Conditional(CamelCloudServiceDiscoveryAutoConfiguration.Condition.class) -public class CamelCloudServiceDiscoveryAutoConfiguration { +public class CamelCloudServiceDiscoveryAutoConfiguration implements BeanFactoryAware { + private static final Logger LOGGER = LoggerFactory.getLogger(CamelCloudServiceDiscoveryAutoConfiguration.class); - @Lazy - @Bean(name = "static-service-discovery") - public ServiceDiscovery staticServiceDiscovery(CamelCloudConfigurationProperties properties) { - StaticServiceDiscovery staticServiceDiscovery = new StaticServiceDiscovery(); + private BeanFactory beanFactory; - Map<String, List<String>> services = properties.getServiceDiscovery().getServices(); - for (Map.Entry<String, List<String>> entry : services.entrySet()) { - staticServiceDiscovery.addServers(entry.getKey(), entry.getValue()); - } + @Autowired + private CamelContext camelContext; + @Autowired + private CamelCloudConfigurationProperties configurationProperties; - return staticServiceDiscovery; + @Override + public void setBeanFactory(BeanFactory factory) throws BeansException { + beanFactory = factory; } @Lazy - @Bean(name = "service-discovery") - public CamelCloudServiceDiscovery serviceDiscovery( - CamelContext camelContext, CamelCloudConfigurationProperties properties, List<ServiceDiscovery> serviceDiscoveryList) throws NoTypeConversionAvailableException { + @Bean(name = "static-service-discovery") + public ServiceDiscovery staticServiceDiscovery() { + return createStaticServiceDiscovery(configurationProperties.getServiceDiscovery()); + } - String cacheTimeout = properties.getServiceDiscovery().getCacheTimeout(); + @Lazy + @Bean(name = "service-discovery") + public CamelCloudServiceDiscovery serviceDiscovery(List<ServiceDiscovery> serviceDiscoveryList) throws NoTypeConversionAvailableException { + String cacheTimeout = configurationProperties.getServiceDiscovery().getCacheTimeout(); Long timeout = null; if (cacheTimeout != null) { @@ -64,6 +79,24 @@ public class CamelCloudServiceDiscoveryAutoConfiguration { return new CamelCloudServiceDiscovery(timeout, serviceDiscoveryList); } + @PostConstruct + public void addServiceDiscoveryConfigurations() { + if (!(beanFactory instanceof ConfigurableBeanFactory)) { + LOGGER.warn("BeanFactory is not of type ConfigurableBeanFactory"); + return; + } + + final ConfigurableBeanFactory factory = (ConfigurableBeanFactory) beanFactory; + + configurationProperties.getServiceDiscovery().getConfigurations().entrySet().stream() + .forEach( + entry -> factory.registerSingleton( + entry.getKey(), + createStaticServiceDiscovery(entry.getValue()) + ) + ); + } + // ******************************* // Condition // ******************************* @@ -76,4 +109,19 @@ public class CamelCloudServiceDiscoveryAutoConfiguration { ); } } + + // ******************************* + // Helper + // ******************************* + + private ServiceDiscovery createStaticServiceDiscovery(CamelCloudConfigurationProperties.ServiceDiscoveryConfiguration configuration) { + StaticServiceDiscovery staticServiceDiscovery = new StaticServiceDiscovery(); + + Map<String, List<String>> services = configuration.getServices(); + for (Map.Entry<String, List<String>> entry : services.entrySet()) { + staticServiceDiscovery.addServers(entry.getKey(), entry.getValue()); + } + + return staticServiceDiscovery; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceFilterAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceFilterAutoConfiguration.java b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceFilterAutoConfiguration.java index 5a23d35..f3b7866 100644 --- a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceFilterAutoConfiguration.java +++ b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceFilterAutoConfiguration.java @@ -20,11 +20,21 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import javax.annotation.PostConstruct; + +import org.apache.camel.CamelContext; import org.apache.camel.impl.cloud.BlacklistServiceFilter; import org.apache.camel.impl.cloud.HealthyServiceFilter; import org.apache.camel.spring.boot.util.GroupCondition; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.StringHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -34,25 +44,43 @@ import org.springframework.context.annotation.Lazy; @Configuration @EnableConfigurationProperties(CamelCloudConfigurationProperties.class) @Conditional(CamelCloudServiceFilterAutoConfiguration.Condition.class) -public class CamelCloudServiceFilterAutoConfiguration { +public class CamelCloudServiceFilterAutoConfiguration implements BeanFactoryAware { + private static final Logger LOGGER = LoggerFactory.getLogger(CamelCloudServiceFilterAutoConfiguration.class); + + private BeanFactory beanFactory; + + @Autowired + private CamelContext camelContext; + @Autowired + private CamelCloudConfigurationProperties configurationProperties; + + @Override + public void setBeanFactory(BeanFactory factory) throws BeansException { + beanFactory = factory; + } + @Lazy @Bean(name = "service-filter") - public CamelCloudServiceFilter serviceFilter(CamelCloudConfigurationProperties properties) { - BlacklistServiceFilter blacklist = new BlacklistServiceFilter(); - - Map<String, List<String>> services = properties.getServiceFilter().getBlacklist(); - for (Map.Entry<String, List<String>> entry : services.entrySet()) { - for (String part : entry.getValue()) { - String host = StringHelper.before(part, ":"); - String port = StringHelper.after(part, ":"); + public CamelCloudServiceFilter serviceFilter() { + return createServiceFilter(configurationProperties.getServiceFilter()); + } - if (ObjectHelper.isNotEmpty(host) && ObjectHelper.isNotEmpty(port)) { - blacklist.addServer(entry.getKey(), host, Integer.parseInt(port)); - } - } + @PostConstruct + public void addServiceFilterConfigurations() { + if (!(beanFactory instanceof ConfigurableBeanFactory)) { + LOGGER.warn("BeanFactory is not of type ConfigurableBeanFactory"); + return; } - return new CamelCloudServiceFilter(Arrays.asList(new HealthyServiceFilter(), blacklist)); + final ConfigurableBeanFactory factory = (ConfigurableBeanFactory) beanFactory; + + configurationProperties.getServiceFilter().getConfigurations().entrySet().stream() + .forEach( + entry -> factory.registerSingleton( + entry.getKey(), + createServiceFilter(entry.getValue()) + ) + ); } // ******************************* @@ -67,4 +95,26 @@ public class CamelCloudServiceFilterAutoConfiguration { ); } } + + // ******************************* + // Helper + // ******************************* + + private CamelCloudServiceFilter createServiceFilter(CamelCloudConfigurationProperties.ServiceFilterConfiguration configuration) { + BlacklistServiceFilter blacklist = new BlacklistServiceFilter(); + + Map<String, List<String>> services = configuration.getBlacklist(); + for (Map.Entry<String, List<String>> entry : services.entrySet()) { + for (String part : entry.getValue()) { + String host = StringHelper.before(part, ":"); + String port = StringHelper.after(part, ":"); + + if (ObjectHelper.isNotEmpty(host) && ObjectHelper.isNotEmpty(port)) { + blacklist.addServer(entry.getKey(), host, Integer.parseInt(port)); + } + } + } + + return new CamelCloudServiceFilter(Arrays.asList(new HealthyServiceFilter(), blacklist)); + } } http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/main/resources/META-INF/spring.factories ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/main/resources/META-INF/spring.factories b/components/camel-spring-boot/src/main/resources/META-INF/spring.factories index d7ae56e..10f5de7 100644 --- a/components/camel-spring-boot/src/main/resources/META-INF/spring.factories +++ b/components/camel-spring-boot/src/main/resources/META-INF/spring.factories @@ -19,6 +19,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.apache.camel.spring.boot.CamelAutoConfiguration,\ org.apache.camel.spring.boot.CamelRestAutoConfiguration,\ org.apache.camel.spring.boot.cloud.CamelCloudAutoConfiguration,\ +org.apache.camel.spring.boot.cloud.CamelCloudServiceCallConfigurationAutoConfiguration,\ org.apache.camel.spring.boot.cloud.CamelCloudServiceDiscoveryAutoConfiguration,\ org.apache.camel.spring.boot.cloud.CamelCloudServiceFilterAutoConfiguration,\ org.apache.camel.spring.boot.cloud.CamelCloudServiceChooserAutoConfiguration,\ http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationTest.java b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationTest.java index 4ee24c5..282af31 100644 --- a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationTest.java +++ b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallConfigurationTest.java @@ -58,7 +58,7 @@ public class CamelCloudServiceCallConfigurationTest { private ApplicationContext ctx; @Test - public void doTest() throws Exception { + public void testConfiguration() throws Exception { Environment env = ctx.getEnvironment(); assertFalse(env.getProperty("camel.cloud.enabled", Boolean.class)); http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallExpressionTest.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallExpressionTest.java b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallExpressionTest.java new file mode 100644 index 0000000..24a533a --- /dev/null +++ b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallExpressionTest.java @@ -0,0 +1,90 @@ +/** + * 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.boot.cloud; + +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +@DirtiesContext +@RunWith(SpringRunner.class) +@SpringBootApplication +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + CamelCloudServiceCallExpressionTest.TestConfiguration.class + }, + properties = { + "service.name=custom-svc-list", + "camel.cloud.load-balancer.enabled=false", + "camel.cloud.service-call.component=netty4-http", + "camel.cloud.service-call.expression=${header.CamelServiceCallScheme}:http://${header.CamelServiceCallServiceHost}:${header.CamelServiceCallServicePort}/hello", + "camel.cloud.service-discovery.services[custom-svc-list]=localhost:9090,localhost:9091,localhost:9092", + "camel.cloud.service-filter.blacklist[custom-svc-list]=localhost:9091", + "ribbon.enabled=false", + "debug=true" + } +) +public class CamelCloudServiceCallExpressionTest { + @Autowired + private ProducerTemplate template; + + @Test + public void testServiceCall() throws Exception { + Assert.assertEquals("9090", template.requestBody("direct:start", null, String.class)); + Assert.assertEquals("9092", template.requestBody("direct:start", null, String.class)); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public static class TestConfiguration { + @Bean + public RouteBuilder myRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .serviceCall("{{service.name}}"); + + from("netty4-http:http://localhost:9090/hello") + .transform() + .constant("9090"); + from("netty4-http:http://localhost:9091/hello") + .transform() + .constant("9091"); + from("netty4-http:http://localhost:9092/hello") + .transform() + .constant("9092"); + } + }; + } + } +} + http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallGlobalConfigurationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallGlobalConfigurationTest.java b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallGlobalConfigurationTest.java new file mode 100644 index 0000000..aef1ca8 --- /dev/null +++ b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallGlobalConfigurationTest.java @@ -0,0 +1,97 @@ +/** + * 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.boot.cloud; + +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +@DirtiesContext +@RunWith(SpringRunner.class) +@SpringBootApplication +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + CamelCloudServiceCallGlobalConfigurationTest.TestConfiguration.class + }, + properties = { + "service.name=custom-svc-list", + "camel.cloud.load-balancer.enabled=false", + "camel.cloud.service-call.uri=netty4-http:http://${service.name}", + "camel.cloud.service-call.service-discovery=sd", + "camel.cloud.service-call.service-filter=sf", + // this should not be taken into account + "camel.cloud.service-discovery.services[custom-svc-list]=localhost:8090,localhost:8091,localhost:8092", + // this should be used + "camel.cloud.service-discovery.configurations[sd].services[custom-svc-list]=localhost:9090,localhost:9091,localhost:9092", + // this should not be taken into account + "camel.cloud.service-filter.blacklist[custom-svc-list]=localhost:9090", + // this should be used + "camel.cloud.service-filter.configurations[sf].blacklist[custom-svc-list]=localhost:9091", + "ribbon.enabled=false", + "debug=true" + } +) +public class CamelCloudServiceCallGlobalConfigurationTest { + @Autowired + private ProducerTemplate template; + + @Test + public void testServiceCall() throws Exception { + Assert.assertEquals("9090", template.requestBody("direct:start", null, String.class)); + Assert.assertEquals("9092", template.requestBody("direct:start", null, String.class)); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public static class TestConfiguration { + @Bean + public RouteBuilder myRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .serviceCall("{{service.name}}/hello"); + + from("netty4-http:http://localhost:9090/hello") + .transform() + .constant("9090"); + from("netty4-http:http://localhost:9091/hello") + .transform() + .constant("9091"); + from("netty4-http:http://localhost:9092/hello") + .transform() + .constant("9092"); + } + }; + } + } +} + http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallTest.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallTest.java b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallTest.java index f5a9735..216c37a 100644 --- a/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallTest.java +++ b/components/camel-spring-boot/src/test/java/org/apache/camel/spring/boot/cloud/CamelCloudServiceCallTest.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.camel.spring.boot.cloud; import org.apache.camel.ProducerTemplate; @@ -70,7 +69,8 @@ public class CamelCloudServiceCallTest { public void configure() throws Exception { from("direct:start") .serviceCall() - .name("custom-svc-list/hello"); + .name("custom-svc-list/hello") + .uri("netty4-http:http://custom-svc-list"); from("netty4-http:http://localhost:9090/hello") .transform() http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-boot/src/test/resources/application.properties ---------------------------------------------------------------------- diff --git a/components/camel-spring-boot/src/test/resources/application.properties b/components/camel-spring-boot/src/test/resources/application.properties index 06fe56c..e942adb 100644 --- a/components/camel-spring-boot/src/test/resources/application.properties +++ b/components/camel-spring-boot/src/test/resources/application.properties @@ -20,4 +20,4 @@ spring.main.banner_mode=off from=direct:test to=mock:test -#logging.level.org.apache.camel=DEBUG \ No newline at end of file +#logging.level.org.apache.camel=DEBUG http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClient.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClient.java b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClient.java index b210ea4..ee4aee4 100644 --- a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClient.java +++ b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClient.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.camel.spring.cloud; import java.util.Collections; http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClientAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClientAutoConfiguration.java b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClientAutoConfiguration.java index cc29cc4..dec3bc0 100644 --- a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClientAutoConfiguration.java +++ b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudDiscoveryClientAutoConfiguration.java @@ -16,8 +16,6 @@ */ package org.apache.camel.spring.cloud; - -import org.apache.camel.cloud.LoadBalancer; import org.apache.camel.spring.boot.cloud.CamelCloudAutoConfiguration; import org.apache.camel.spring.boot.cloud.CamelCloudConfigurationProperties; import org.apache.camel.spring.boot.cloud.CamelCloudServiceDiscovery; http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancer.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancer.java b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancer.java index 2cf208d..bfd6ab8 100644 --- a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancer.java +++ b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancer.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.camel.spring.cloud; import org.apache.camel.CamelContext; http://git-wip-us.apache.org/repos/asf/camel/blob/a65171f4/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancerAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancerAutoConfiguration.java b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancerAutoConfiguration.java index c6bcf74..d1c3a7f 100644 --- a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancerAutoConfiguration.java +++ b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudLoadBalancerAutoConfiguration.java @@ -16,18 +16,15 @@ */ package org.apache.camel.spring.cloud; - import org.apache.camel.cloud.LoadBalancer; import org.apache.camel.spring.boot.cloud.CamelCloudAutoConfiguration; import org.apache.camel.spring.boot.cloud.CamelCloudConfigurationProperties; -import org.apache.camel.spring.boot.cloud.CamelCloudServiceDiscovery; import org.apache.camel.spring.boot.cloud.CamelCloudServiceDiscoveryAutoConfiguration; import org.apache.camel.spring.boot.util.GroupCondition; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.context.annotation.Bean;