diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java new file mode 100644 index 00000000..1356ea57 --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/DefaultServerIntrospector.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed 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.springframework.cloud.netflix.ribbon; + +import com.netflix.loadbalancer.Server; + +/** + * @author Spencer Gibb + */ +public class DefaultServerIntrospector implements ServerIntrospector { + @Override + public boolean isSecure(Server server) { + // Can we do better? + return (""+server.getPort()).endsWith("443"); + } +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java index 63ce04ab..600c648b 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java @@ -26,10 +26,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; -import org.springframework.util.ClassUtils; import org.springframework.web.util.UriComponentsBuilder; -import com.netflix.appinfo.InstanceInfo.PortType; import com.netflix.client.config.DefaultClientConfigImpl; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.ConfigurationBasedServerList; @@ -44,7 +42,6 @@ import com.netflix.loadbalancer.ServerListFilter; import com.netflix.loadbalancer.ZoneAvoidanceRule; import com.netflix.loadbalancer.ZoneAwareLoadBalancer; import com.netflix.niws.client.http.RestClient; -import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; import com.netflix.servo.monitor.Monitors; import com.sun.jersey.api.client.Client; import com.sun.jersey.client.apache4.ApacheHttpClient4; @@ -95,9 +92,9 @@ public class RibbonClientConfiguration { } /** - * Create a Netflix {@link RestClient} integrated with Ribbon if none already exists in the - * application context. It is not required for Ribbon to work properly and is therefore - * created lazily if ever another component requires it. + * Create a Netflix {@link RestClient} integrated with Ribbon if none already exists + * in the application context. It is not required for Ribbon to work properly and is + * therefore created lazily if ever another component requires it. * * @param config the configuration to use by the underlying Ribbon instance * @param loadBalancer the load balancer to use by the underlying Ribbon instance @@ -106,8 +103,9 @@ public class RibbonClientConfiguration { @Bean @Lazy @ConditionalOnMissingBean - public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer) { - RestClient client = new OverrideRestClient(config); + public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer, + ServerIntrospector serverIntrospector) { + RestClient client = new OverrideRestClient(config, serverIntrospector); client.setLoadBalancer(loadBalancer); Monitors.registerObject("Client_" + this.name, client); return client; @@ -140,34 +138,33 @@ public class RibbonClientConfiguration { return new RibbonLoadBalancerContext(loadBalancer, config); } + @Bean + @ConditionalOnMissingBean + public ServerIntrospector serverIntrospector() { + return new DefaultServerIntrospector(); + } + static class OverrideRestClient extends RestClient { - protected OverrideRestClient(IClientConfig ncc) { + private ServerIntrospector serverIntrospector; + + protected OverrideRestClient(IClientConfig ncc, + ServerIntrospector serverIntrospector) { super(); + this.serverIntrospector = serverIntrospector; initWithNiwsConfig(ncc); } @Override public URI reconstructURIWithServer(Server server, URI original) { String scheme = original.getScheme(); - if (!"https".equals(scheme) && isSecure(server)) { - original = UriComponentsBuilder.fromUri(original).scheme("https").build().toUri(); + if (!"https".equals(scheme) && serverIntrospector.isSecure(server)) { + original = UriComponentsBuilder.fromUri(original).scheme("https").build() + .toUri(); } return super.reconstructURIWithServer(server, original); } - private boolean isSecure(Server server) { - if (ClassUtils.isPresent("com.netflix.niws.loadbalancer.DiscoveryEnabledServer", - null)) { - if (server instanceof DiscoveryEnabledServer) { - DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server; - return enabled.getInstanceInfo().isPortEnabled(PortType.SECURE); - } - } - // Can we do better? - return (""+server.getPort()).endsWith("443"); - } - @Override protected Client apacheHttpClientSpecificInitialization() { ApacheHttpClient4 apache = (ApacheHttpClient4) super diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java new file mode 100644 index 00000000..8842c595 --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/ServerIntrospector.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed 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.springframework.cloud.netflix.ribbon; + +import com.netflix.loadbalancer.Server; + +/** + * @author Spencer Gibb + */ +public interface ServerIntrospector { + + boolean isSecure(Server server); +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java index 1c1b5f8a..cea2941c 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java @@ -177,7 +177,7 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw return result; } - private C getInstance(String name, Class type) { + public C getInstance(String name, Class type) { AnnotationConfigApplicationContext context = getContext(name); if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, type).length > 0) { return context.getBean(type); diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java index daa28d0d..e24096a6 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientConfiguration.java @@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; +import org.springframework.cloud.netflix.ribbon.ServerIntrospector; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; @@ -101,6 +102,11 @@ public class EurekaRibbonClientConfiguration { return serverList; } + @Bean + public ServerIntrospector serverIntrospector() { + return new EurekaServerIntrospector(); + } + @PostConstruct public void preprocess() { String zone = ConfigurationManager.getDeploymentContext().getValue( diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java new file mode 100644 index 00000000..904bcf96 --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaServerIntrospector.java @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed 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.springframework.cloud.netflix.ribbon.eureka; + +import com.netflix.appinfo.InstanceInfo; +import com.netflix.loadbalancer.Server; +import com.netflix.niws.loadbalancer.DiscoveryEnabledServer; +import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; + +/** + * @author Spencer Gibb + */ +public class EurekaServerIntrospector extends DefaultServerIntrospector { + + @Override + public boolean isSecure(Server server) { + if (server instanceof DiscoveryEnabledServer) { + DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server; + return enabled.getInstanceInfo().isPortEnabled(InstanceInfo.PortType.SECURE); + } + return super.isSecure(server); + } +} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java index dc041575..101121b5 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java @@ -47,7 +47,7 @@ public class RibbonClientConfigurationTests { static class TestRestClient extends RibbonClientConfiguration.OverrideRestClient { private TestRestClient(IClientConfig ncc) { - super(ncc); + super(ncc, new DefaultServerIntrospector()); } @Override diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java index 4de08b6a..9d8bc099 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonClientPreprocessorIntegrationTests.java @@ -25,6 +25,7 @@ import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration; import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClient; +import org.springframework.cloud.netflix.ribbon.ServerIntrospector; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientPreprocessorIntegrationTests.TestConfiguration; import org.springframework.context.annotation.Configuration; @@ -63,6 +64,11 @@ public class EurekaRibbonClientPreprocessorIntegrationTests { NIWSDiscoveryPing.class.cast(getLoadBalancer().getPing()); } + @Test + public void serverIntrospectorDefaultsToEureka() throws Exception { + EurekaServerIntrospector.class.cast(this.factory.getInstance("foo", ServerIntrospector.class)); + } + @SuppressWarnings("unchecked") private ZoneAwareLoadBalancer getLoadBalancer() { return (ZoneAwareLoadBalancer) this.factory