Create a LoadBalancerClient abstraction and a Ribbon implementation
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
package org.springframework.cloud.client;
|
||||
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* TODO: name? Server? HostAndPort? Instance?
|
||||
*/
|
||||
public interface ServiceInstance {
|
||||
public String getHost();
|
||||
public int getPort();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.springframework.cloud.client.loadbalancer;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface LoadBalancerClient {
|
||||
/**
|
||||
* Choose a {@see ServiceInstance} from the LoadBalancer for the specified service
|
||||
* @param serviceId The serviceId to use to look up the LoadBalancer
|
||||
* @return
|
||||
*/
|
||||
public ServiceInstance choose(String serviceId);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package org.springframework.cloud.netflix.ribbon;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaRibbonInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -10,7 +11,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -27,19 +27,22 @@ public class RibbonAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RestTemplate.class)
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
public RestTemplate restTemplate(RibbonInterceptor ribbonInterceptor) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
List<ClientHttpRequestInterceptor> list = new ArrayList<>();
|
||||
list.add(ribbonInterceptor);
|
||||
restTemplate.setInterceptors(list);
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RibbonInterceptor ribbonInterceptor() {
|
||||
return new RibbonInterceptor();
|
||||
@ConditionalOnMissingBean(LoadBalancerClient.class)
|
||||
public LoadBalancerClient loadBalancerClient() {
|
||||
return new RibbonLoadBalancerClient();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
List<ClientHttpRequestInterceptor> list = new ArrayList<>();
|
||||
list.add(ribbonInterceptor());
|
||||
restTemplate().setInterceptors(list);
|
||||
@Bean
|
||||
public RibbonInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient) {
|
||||
return new RibbonInterceptor(loadBalancerClient);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import com.netflix.client.ClientFactory;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
@@ -17,6 +16,13 @@ import java.net.URI;
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private LoadBalancerClient loadBalancer;
|
||||
|
||||
public RibbonInterceptor(LoadBalancerClient loadBalancer) {
|
||||
this.loadBalancer = loadBalancer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
|
||||
HttpRequestWrapper wrapper = new HttpRequestWrapper(request) {
|
||||
@@ -24,14 +30,10 @@ public class RibbonInterceptor implements ClientHttpRequestInterceptor {
|
||||
public URI getURI() {
|
||||
URI originalUri = super.getURI();
|
||||
String serviceName = originalUri.getHost();
|
||||
ILoadBalancer loadBalancer = ClientFactory.getNamedLoadBalancer(serviceName);
|
||||
Server server = loadBalancer.chooseServer(null);
|
||||
if (server == null) {
|
||||
throw new IllegalStateException("Unable to locate ILoadBalancer for service: "+ serviceName);
|
||||
}
|
||||
ServiceInstance instance = loadBalancer.choose(serviceName);
|
||||
URI uri = UriComponentsBuilder.fromUri(originalUri)
|
||||
.host(server.getHost())
|
||||
.port(server.getPort())
|
||||
.host(instance.getHost())
|
||||
.port(instance.getPort())
|
||||
.build()
|
||||
.toUri();
|
||||
return uri;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import com.netflix.client.ClientFactory;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonLoadBalancerClient implements LoadBalancerClient {
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
ILoadBalancer loadBalancer = ClientFactory.getNamedLoadBalancer(serviceId);
|
||||
Server server = loadBalancer.chooseServer(null);
|
||||
if (server == null) {
|
||||
throw new IllegalStateException("Unable to locate ILoadBalancer for service: "+ serviceId);
|
||||
}
|
||||
return new RibbonServer(server);
|
||||
}
|
||||
|
||||
private class RibbonServer implements ServiceInstance {
|
||||
private Server server;
|
||||
|
||||
private RibbonServer(Server server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return server.getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return server.getPort();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user