Introduce Ribbon ServerIntrospector.
Allows ribbon load balancer implementations to answer questions like isSecure(Server).
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -177,7 +177,7 @@ public class SpringClientFactory implements DisposableBean, ApplicationContextAw
|
||||
return result;
|
||||
}
|
||||
|
||||
private <C> C getInstance(String name, Class<C> type) {
|
||||
public <C> C getInstance(String name, Class<C> type) {
|
||||
AnnotationConfigApplicationContext context = getContext(name);
|
||||
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, type).length > 0) {
|
||||
return context.getBean(type);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public class RibbonClientConfigurationTests {
|
||||
static class TestRestClient extends RibbonClientConfiguration.OverrideRestClient {
|
||||
|
||||
private TestRestClient(IClientConfig ncc) {
|
||||
super(ncc);
|
||||
super(ncc, new DefaultServerIntrospector());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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<Server> getLoadBalancer() {
|
||||
return (ZoneAwareLoadBalancer<Server>) this.factory
|
||||
|
||||
Reference in New Issue
Block a user