Repository: camel Updated Branches: refs/heads/master 110d1c9d6 -> 567dff400
Service Call : Allow to confgire ribbon load balancer using ribbon specific properties Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/567dff40 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/567dff40 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/567dff40 Branch: refs/heads/master Commit: 567dff4003e146ae1b0364dca4fbc2d126ca219b Parents: 110d1c9 Author: lburgazzoli <lburgazz...@gmail.com> Authored: Tue Apr 18 16:52:53 2017 +0200 Committer: lburgazzoli <lburgazz...@gmail.com> Committed: Tue Apr 18 16:53:02 2017 +0200 ---------------------------------------------------------------------- .../camel-ribbon/src/main/docs/ribbon.adoc | 4 +- .../component/ribbon/RibbonConfiguration.java | 19 +++-- .../ribbon/cloud/RibbonLoadBalancer.java | 71 +++++++++++----- .../ribbon/cloud/RibbonLoadBalancerFactory.java | 8 +- .../cloud/RibbonServiceCallUpdateRouteTest.java | 4 +- ...DslRibbonPropertiesServiceCallRouteTest.java | 31 +++++++ ...gDslRibbonPropertiesServiceCallRouteTest.xml | 55 ++++++++++++ ...viceCallLoadBalancerConfigurationCommon.java | 89 ++++++++++++++++++++ ...CallLoadBalancerConfigurationProperties.java | 48 +++++++++++ .../cloud/EtcdServiceDiscoveryDisabledTest.java | 2 +- .../cloud/RibbonCloudAutoConfiguration.java | 53 ++++++++++-- .../cloud/RibbonCloudConfiguration.java | 45 ---------- .../src/main/resources/application.properties | 1 - .../cloud/RibbonLoadBalancerDisabledTest.java | 64 ++++++++++++++ .../cloud/RibbonLoadBalancerEnabledTest.java | 65 ++++++++++++++ .../src/test/resources/logback.xml | 39 +++++++++ .../SpringBootAutoConfigurationMojo.java | 12 +++ 17 files changed, 523 insertions(+), 87 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/components/camel-ribbon/src/main/docs/ribbon.adoc ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/docs/ribbon.adoc b/components/camel-ribbon/src/main/docs/ribbon.adoc index ceb2e0e..b4dc6c9 100644 --- a/components/camel-ribbon/src/main/docs/ribbon.adoc +++ b/components/camel-ribbon/src/main/docs/ribbon.adoc @@ -26,7 +26,7 @@ This component helps applying load balancing feature at the client side when usi [source,java] ---- RibbonConfiguration configuration = new RibbonConfiguration(); -configuration.setClientConfig(Collections.singletonMap("ServerListRefreshInterval", "250")); +configuration.addProperties("ServerListRefreshInterval", "250"); RibbonLoadBalancer loadBalancer = new RibbonLoadBalancer(configuration); @@ -44,7 +44,7 @@ from("direct:start") [source,properties] .application.properties ---- -camel.cloud.ribbon.client-config[ServerListRefreshInterval] = 250 +camel.cloud.ribbon.properties[ServerListRefreshInterval] = 250 ---- + [source,java] http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java index 40bcb31..41ac473 100644 --- a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.ribbon; +import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; @@ -29,7 +30,7 @@ public class RibbonConfiguration { private IRule rule; private IPing ping; private String clientName; - private Map<String, String> clientConfig; + private Map<String, String> properties; public String getNamespace() { return namespace; @@ -87,11 +88,19 @@ public class RibbonConfiguration { this.clientName = clientName; } - public Map<String, String> getClientConfig() { - return clientConfig; + public Map<String, String> getProperties() { + return properties; } - public void setClientConfig(Map<String, String> clientConfig) { - this.clientConfig = clientConfig; + public void setProperties(Map<String, String> clientConfig) { + this.properties = clientConfig; + } + + public void addProperty(String key, String value) { + if (this.properties == null) { + this.properties = new HashMap<>(); + } + + this.properties.put(key, value); } } http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancer.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancer.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancer.java index b867eea..759a602 100644 --- a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancer.java +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancer.java @@ -30,6 +30,7 @@ import com.netflix.loadbalancer.DummyPing; import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.PollingServerListUpdater; import com.netflix.loadbalancer.RoundRobinRule; +import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerList; import com.netflix.loadbalancer.ZoneAwareLoadBalancer; import org.apache.camel.CamelContext; @@ -103,12 +104,14 @@ public class RibbonLoadBalancer protected void doStart() throws Exception { ObjectHelper.notNull(configuration, "configuration"); ObjectHelper.notNull(camelContext, "camel context"); - ObjectHelper.notNull(serviceDiscovery, "service discovery"); - ObjectHelper.notNull(serviceFilter, "service filter"); - LOGGER.info("ServiceCall is using ribbon load balancer with service discovery type: {} and service filter type: {}", - serviceDiscovery.getClass(), - serviceFilter.getClass()); + if (serviceDiscovery != null) { + LOGGER.info("ServiceCall is using ribbon load balancer with service discovery type: {} and service filter: {}", + serviceDiscovery.getClass(), + serviceDiscovery != null ? serviceFilter.getClass() : "none"); + } else { + LOGGER.info("ServiceCall is using ribbon load balancer"); + } ServiceHelper.startService(serviceDiscovery); } @@ -127,28 +130,50 @@ public class RibbonLoadBalancer @Override public <T> T process(String serviceName, LoadBalancerFunction<T> request) throws Exception { - ILoadBalancer loadBalancer = loadBalancers.computeIfAbsent(serviceName, key -> createLoadBalancer(key, serviceDiscovery)); - RibbonServiceDefinition service = (RibbonServiceDefinition)loadBalancer.chooseServer(serviceName); + ILoadBalancer loadBalancer = loadBalancers.computeIfAbsent(serviceName, key -> createLoadBalancer(key)); + Server server = loadBalancer.chooseServer(serviceName); - if (service == null) { + if (server == null) { throw new RejectedExecutionException("No active services with name " + serviceName); } - return request.apply(service); + ServiceDefinition definition; + + if (server instanceof ServiceDefinition) { + // If the service discovery is one of camel provides, the definition + // is already of the expected type. + definition = (ServiceDefinition)server; + } else { + // If ribbon server list is configured through client config properties + // i.e. with listOfServers property the instance provided by the load + // balancer is of type Server so a conversion is needed + definition = new RibbonServiceDefinition( + serviceName, + server.getHost(), + server.getPort() + ); + + String zone = server.getZone(); + if (zone != null) { + server.setZone(zone); + } + } + + return request.apply(definition); } // ************************ // Helpers // ************************ - private ZoneAwareLoadBalancer<RibbonServiceDefinition> createLoadBalancer(String serviceName, ServiceDiscovery serviceDiscovery) { + private ZoneAwareLoadBalancer<RibbonServiceDefinition> createLoadBalancer(String serviceName) { // setup client config IClientConfig config = configuration.getClientName() != null ? IClientConfig.Builder.newBuilder(configuration.getClientName()).build() : IClientConfig.Builder.newBuilder().build(); - if (configuration.getClientConfig() != null) { - for (Map.Entry<String, String> entry : configuration.getClientConfig().entrySet()) { + if (configuration.getProperties() != null) { + for (Map.Entry<String, String> entry : configuration.getProperties().entrySet()) { IClientConfigKey key = IClientConfigKey.Keys.valueOf(entry.getKey()); String value = entry.getValue(); @@ -157,13 +182,21 @@ public class RibbonLoadBalancer } } - return new ZoneAwareLoadBalancer<>( - config, - configuration.getRuleOrDefault(RoundRobinRule::new), - configuration.getPingOrDefault(DummyPing::new), - new RibbonServerList(serviceName, serviceDiscovery, serviceFilter), - null, - new PollingServerListUpdater(config)); + ZoneAwareLoadBalancer<RibbonServiceDefinition> loadBalancer; + + if (serviceDiscovery != null) { + loadBalancer = new ZoneAwareLoadBalancer<>( + config, + configuration.getRuleOrDefault(RoundRobinRule::new), + configuration.getPingOrDefault(DummyPing::new), + new RibbonServerList(serviceName, serviceDiscovery, serviceFilter), + null, + new PollingServerListUpdater(config)); + } else { + loadBalancer = new ZoneAwareLoadBalancer<>(config); + } + + return loadBalancer; } static final class RibbonServerList implements ServerList<RibbonServiceDefinition> { http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancerFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancerFactory.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancerFactory.java index 5a211fc..f166011 100644 --- a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancerFactory.java +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/cloud/RibbonLoadBalancerFactory.java @@ -70,12 +70,12 @@ public class RibbonLoadBalancerFactory implements LoadBalancerFactory { configuration.setClientName(clientName); } - public Map<String, String> getClientConfig() { - return configuration.getClientConfig(); + public Map<String, String> getProperties() { + return configuration.getProperties(); } - public void setClientConfig(Map<String, String> clientConfig) { - configuration.setClientConfig(clientConfig); + public void setProperties(Map<String, String> clientConfig) { + configuration.setProperties(clientConfig); } // ************************************************************************* http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/RibbonServiceCallUpdateRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/RibbonServiceCallUpdateRouteTest.java b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/RibbonServiceCallUpdateRouteTest.java index c00f1c7..27aba3e 100644 --- a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/RibbonServiceCallUpdateRouteTest.java +++ b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/RibbonServiceCallUpdateRouteTest.java @@ -17,8 +17,6 @@ package org.apache.camel.component.ribbon.cloud; -import java.util.Collections; - import org.apache.camel.RoutesBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.ribbon.RibbonConfiguration; @@ -76,7 +74,7 @@ public class RibbonServiceCallUpdateRouteTest extends CamelTestSupport { public void configure() throws Exception { RibbonConfiguration configuration = new RibbonConfiguration(); // lets update quick so we do not have to sleep so much in the tests - configuration.setClientConfig(Collections.singletonMap("ServerListRefreshInterval", "250")); + configuration.addProperty("ServerListRefreshInterval", "250"); RibbonLoadBalancer loadBalancer = new RibbonLoadBalancer(configuration); from("direct:start") http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.java b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.java new file mode 100644 index 0000000..9456b7a --- /dev/null +++ b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.java @@ -0,0 +1,31 @@ +/** + * 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.component.ribbon.cloud; + +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.annotation.DirtiesContext; + +@DirtiesContext +public class SpringDslRibbonPropertiesServiceCallRouteTest extends SpringRibbonServiceCallRouteTest { + @Override + protected AbstractApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.xml"); + } +} + http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/components/camel-ribbon/src/test/resources/org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/resources/org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.xml b/components/camel-ribbon/src/test/resources/org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.xml new file mode 100644 index 0000000..b182bc2 --- /dev/null +++ b/components/camel-ribbon/src/test/resources/org/apache/camel/component/ribbon/cloud/SpringDslRibbonPropertiesServiceCallRouteTest.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring + http://camel.apache.org/schema/spring/camel-spring.xsd"> + + <camelContext xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="direct:start"/> + <serviceCall name="myService"> + <!-- enable ribbon load balancer --> + <ribbonLoadBalancer clientName="myClient"> + <properties key="listOfServers" value="localhost:9090,localhost:9091"/> + </ribbonLoadBalancer> + </serviceCall> + <to uri="mock:result"/> + </route> + + <route> + <from uri="jetty:http://localhost:9090"/> + <to uri="mock:9090"/> + <transform> + <constant>9090</constant> + </transform> + </route> + + <route> + <from uri="jetty:http://localhost:9091"/> + <to uri="mock:9091"/> + <transform> + <constant>9091</constant> + </transform> + </route> + </camelContext> + +</beans> http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/cloud/springboot/RibbonServiceCallLoadBalancerConfigurationCommon.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/cloud/springboot/RibbonServiceCallLoadBalancerConfigurationCommon.java b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/cloud/springboot/RibbonServiceCallLoadBalancerConfigurationCommon.java new file mode 100644 index 0000000..d45c3cc --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/cloud/springboot/RibbonServiceCallLoadBalancerConfigurationCommon.java @@ -0,0 +1,89 @@ +/** + * 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.model.cloud.springboot; + +import java.util.Map; + +/** + * Generated by camel-package-maven-plugin - do not edit this file! + */ +public class RibbonServiceCallLoadBalancerConfigurationCommon { + + /** + * The namespace + */ + private String namespace; + /** + * The username + */ + private String username; + /** + * The password + */ + private String password; + /** + * Sets the Ribbon client name + */ + private String clientName; + /** + * Set client properties to use. These properties are specific to what + * service call implementation are in use. For example if using ribbon then + * the client properties are define in + * com.netflix.client.config.CommonClientConfigKey. + */ + private Map<String, String> properties; + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public Map<String, String> getProperties() { + return properties; + } + + public void setProperties(Map<String, String> properties) { + this.properties = properties; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/cloud/springboot/RibbonServiceCallLoadBalancerConfigurationProperties.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/cloud/springboot/RibbonServiceCallLoadBalancerConfigurationProperties.java b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/cloud/springboot/RibbonServiceCallLoadBalancerConfigurationProperties.java new file mode 100644 index 0000000..a826984 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-core-starter/src/main/java/org/apache/camel/model/cloud/springboot/RibbonServiceCallLoadBalancerConfigurationProperties.java @@ -0,0 +1,48 @@ +/** + * 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.model.cloud.springboot; + +import java.util.HashMap; +import java.util.Map; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "camel.cloud.ribbon.load-balancer") +public class RibbonServiceCallLoadBalancerConfigurationProperties + extends + RibbonServiceCallLoadBalancerConfigurationCommon { + + /** + * Enable the component + */ + private boolean enabled = true; + /** + * Define additional configuration definitions + */ + private Map<String, RibbonServiceCallLoadBalancerConfigurationCommon> configurations = new HashMap<>(); + + public Map<String, RibbonServiceCallLoadBalancerConfigurationCommon> getConfigurations() { + return configurations; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-etcd-starter/src/test/java/org/apache/camel/component/etcd/springboot/cloud/EtcdServiceDiscoveryDisabledTest.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-etcd-starter/src/test/java/org/apache/camel/component/etcd/springboot/cloud/EtcdServiceDiscoveryDisabledTest.java b/platforms/spring-boot/components-starter/camel-etcd-starter/src/test/java/org/apache/camel/component/etcd/springboot/cloud/EtcdServiceDiscoveryDisabledTest.java index 5ca84bf..3d3548a 100644 --- a/platforms/spring-boot/components-starter/camel-etcd-starter/src/test/java/org/apache/camel/component/etcd/springboot/cloud/EtcdServiceDiscoveryDisabledTest.java +++ b/platforms/spring-boot/components-starter/camel-etcd-starter/src/test/java/org/apache/camel/component/etcd/springboot/cloud/EtcdServiceDiscoveryDisabledTest.java @@ -36,7 +36,7 @@ import org.springframework.test.context.junit4.SpringRunner; @SpringBootApplication @SpringBootTest( classes = { - EtcdServiceDiscoveryEnabledTest.TestConfiguration.class + EtcdServiceDiscoveryDisabledTest.TestConfiguration.class }, properties = { "debug=false", http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java index fc6a4fd..8a58108 100644 --- a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java @@ -18,13 +18,19 @@ package org.apache.camel.component.ribbon.springboot.cloud; import java.util.HashMap; import java.util.Map; +import javax.annotation.PostConstruct; import org.apache.camel.CamelContext; import org.apache.camel.cloud.LoadBalancer; import org.apache.camel.component.ribbon.cloud.RibbonLoadBalancerFactory; +import org.apache.camel.model.cloud.springboot.RibbonServiceCallLoadBalancerConfigurationCommon; +import org.apache.camel.model.cloud.springboot.RibbonServiceCallLoadBalancerConfigurationProperties; import org.apache.camel.spring.boot.CamelAutoConfiguration; import org.apache.camel.spring.boot.util.GroupCondition; import org.apache.camel.util.IntrospectionSupport; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -38,21 +44,54 @@ import org.springframework.context.annotation.Lazy; @ConditionalOnBean(CamelAutoConfiguration.class) @Conditional(RibbonCloudAutoConfiguration.Condition.class) @AutoConfigureAfter(CamelAutoConfiguration.class) -@EnableConfigurationProperties(RibbonCloudConfiguration.class) +@EnableConfigurationProperties(RibbonServiceCallLoadBalancerConfigurationProperties.class) public class RibbonCloudAutoConfiguration { + @Autowired + private CamelContext camelContext; + @Autowired + private RibbonServiceCallLoadBalancerConfigurationProperties configuration; + @Autowired + private ConfigurableBeanFactory beanFactory; + @Lazy @Bean(name = "ribbon-load-balancer") @ConditionalOnClass(CamelContext.class) - public LoadBalancer configureServiceDiscoveryFactory(CamelContext camelContext, RibbonCloudConfiguration configuration) throws Exception { + public LoadBalancer configureLoadBalancerFactory() throws Exception { RibbonLoadBalancerFactory factory = new RibbonLoadBalancerFactory(); - Map<String, Object> parameters = new HashMap<>(); - IntrospectionSupport.getProperties(configuration, parameters, null, false); - IntrospectionSupport.setProperties(camelContext, camelContext.getTypeConverter(), factory, parameters); + IntrospectionSupport.setProperties( + camelContext, + camelContext.getTypeConverter(), + factory, + IntrospectionSupport.getNonNullProperties(configuration)); return factory.newInstance(camelContext); } + @PostConstruct + public void postConstruct() { + if (beanFactory != null) { + Map<String, Object> parameters = new HashMap<>(); + + for (Map.Entry<String, RibbonServiceCallLoadBalancerConfigurationCommon> entry : configuration.getConfigurations().entrySet()) { + // clean up params + parameters.clear(); + + // The instance factory + RibbonLoadBalancerFactory factory = new RibbonLoadBalancerFactory(); + + try { + IntrospectionSupport.getProperties(entry.getValue(), parameters, null, false); + IntrospectionSupport.setProperties(camelContext, camelContext.getTypeConverter(), factory, parameters); + + beanFactory.registerSingleton(entry.getKey(), factory.newInstance(camelContext)); + } catch (Exception e) { + throw new BeanCreationException(entry.getKey(), e.getMessage(), e); + } + } + } + } + // ******************************* // Condition // ******************************* @@ -60,8 +99,8 @@ public class RibbonCloudAutoConfiguration { public static class Condition extends GroupCondition { public Condition() { super( - "camel.cloud", - "camel.cloud.ribbon" + "camel.cloud.ribbon", + "camel.cloud.ribbon.load-balancer" ); } } http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudConfiguration.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudConfiguration.java b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudConfiguration.java deleted file mode 100644 index dd31bea..0000000 --- a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * 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.component.ribbon.springboot.cloud; - -import org.apache.camel.component.ribbon.RibbonConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties(prefix = "camel.cloud.ribbon") -public class RibbonCloudConfiguration { - private boolean enabled = true; - private LoadBalancerConfiguration loadBalancer = new LoadBalancerConfiguration(); - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public LoadBalancerConfiguration getLoadBalancer() { - return loadBalancer; - } - - // ************************************************************************* - // - // ************************************************************************* - - public class LoadBalancerConfiguration extends RibbonConfiguration { - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/resources/application.properties ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/resources/application.properties b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/resources/application.properties deleted file mode 100644 index 024710e..0000000 --- a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -camel.cloud.ribbon.load-balancer. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonLoadBalancerDisabledTest.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonLoadBalancerDisabledTest.java b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonLoadBalancerDisabledTest.java new file mode 100644 index 0000000..e2e322f --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonLoadBalancerDisabledTest.java @@ -0,0 +1,64 @@ +/** + * 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.component.ribbon.springboot.cloud; + +import java.util.Map; + +import org.apache.camel.cloud.LoadBalancer; +import org.apache.camel.model.cloud.springboot.RibbonServiceCallLoadBalancerConfigurationProperties; +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.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@DirtiesContext +@SpringBootApplication +@SpringBootTest( + classes = { + RibbonLoadBalancerDisabledTest.TestConfiguration.class + }, + properties = { + "debug=false", + "camel.cloud.ribbon.load-balancer.enabled=false" +}) +public class RibbonLoadBalancerDisabledTest { + @Autowired + ApplicationContext context; + + @Test + public void testConfiguration() throws Exception { + Map<String, ?> beans; + + beans = context.getBeansOfType(RibbonServiceCallLoadBalancerConfigurationProperties.class); + Assert.assertTrue(beans.isEmpty()); + + beans = context.getBeansOfType(LoadBalancer.class); + Assert.assertTrue(beans.isEmpty()); + Assert.assertFalse(beans.containsKey("ribbon-load-balancer")); + } + + @Configuration + public static class TestConfiguration { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonLoadBalancerEnabledTest.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonLoadBalancerEnabledTest.java b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonLoadBalancerEnabledTest.java new file mode 100644 index 0000000..b7e2780 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonLoadBalancerEnabledTest.java @@ -0,0 +1,65 @@ +/** + * 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.component.ribbon.springboot.cloud; + +import java.util.Map; + +import org.apache.camel.cloud.LoadBalancer; +import org.apache.camel.model.cloud.springboot.RibbonServiceCallLoadBalancerConfigurationProperties; +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.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@DirtiesContext +@SpringBootApplication +@SpringBootTest( + classes = { + RibbonLoadBalancerEnabledTest.TestConfiguration.class + }, + properties = { + "debug=false", + "camel.cloud.ribbon.load-balancer.enabled=true" +}) +public class RibbonLoadBalancerEnabledTest { + @Autowired + ApplicationContext context; + + @Test + public void testConfiguration() throws Exception { + Map<String, ?> beans; + + beans = context.getBeansOfType(RibbonServiceCallLoadBalancerConfigurationProperties.class); + Assert.assertFalse(beans.isEmpty()); + Assert.assertEquals(1, beans.size()); + + beans = context.getBeansOfType(LoadBalancer.class); + Assert.assertFalse(beans.isEmpty()); + Assert.assertTrue(beans.containsKey("ribbon-load-balancer")); + } + + @Configuration + public static class TestConfiguration { + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/resources/logback.xml ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/resources/logback.xml b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/resources/logback.xml new file mode 100644 index 0000000..6fb40a6 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/test/resources/logback.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<configuration> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <!-- encoders are assigned the type + ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%-15.15thread] %-5level %-30.30logger - %msg%n</pattern> + </encoder> + </appender> + + <appender name="FILE" class="ch.qos.logback.core.FileAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%-15.15thread] %-5level %-30.30logger - %msg%n</pattern> + </encoder> + <file>target/camel-ribbon-starter-test.log</file> + </appender> + + <root level="INFO"> + <appender-ref ref="FILE"/> + </root> + +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/567dff40/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java ---------------------------------------------------------------------- diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java index a2f5fcd..bba8ecf 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SpringBootAutoConfigurationMojo.java @@ -263,6 +263,18 @@ public class SpringBootAutoConfigurationMojo extends AbstractMojo { createOtherModelConfigurationSource(pkg, model, "camel.cloud.kubernetes.service-discovery", true); } + // Ribbon + json = loadModelJson(files, "ribbonLoadBalancer"); + if (json != null) { + OtherModel model = generateOtherModel(json); + + int pos = model.getJavaType().lastIndexOf("."); + String pkg = model.getJavaType().substring(0, pos) + ".springboot"; + + // Generate properties, auto-configuration happens in camel-kubernetes-starter + createOtherModelConfigurationSource(pkg, model, "camel.cloud.ribbon.load-balancer", true); + } + // Rest json = loadModelJson(files, "restConfiguration"); if (json != null) {