Browse Source

Create a LoadBalancerClient abstraction and a Ribbon implementation

pull/6/head
Spencer Gibb 10 years ago
parent
commit
23b8c96b11
  1. 11
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/ServiceInstance.java
  2. 15
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClient.java
  3. 23
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java
  4. 22
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java
  5. 40
      spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java

11
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/ServiceInstance.java

@ -0,0 +1,11 @@ @@ -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();
}

15
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClient.java

@ -0,0 +1,15 @@ @@ -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);
}

23
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java

@ -3,6 +3,7 @@ package org.springframework.cloud.netflix.ribbon; @@ -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; @@ -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 { @@ -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);
}
}

22
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonInterceptor.java

@ -1,8 +1,7 @@ @@ -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; @@ -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 { @@ -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;

40
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java

@ -0,0 +1,40 @@ @@ -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();
}
}
}
Loading…
Cancel
Save