Browse Source

Create LoadBalancerClientFilter

pull/41/head
Spencer Gibb 8 years ago
parent
commit
5611b6ad28
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 29
      pom.xml
  2. 10
      src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
  3. 59
      src/main/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilter.java
  4. 1
      src/main/java/org/springframework/cloud/gateway/filter/RouteToRequestUrlFilter.java
  5. 26
      src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java
  6. 1
      src/test/java/org/springframework/cloud/gateway/test/GatewayTestApplication.java
  7. 12
      src/test/resources/application.yml

29
pom.xml

@ -49,6 +49,21 @@ @@ -49,6 +49,21 @@
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-transport</artifactId>
</exclusion>
<exclusion>
<groupId>io.reactivex</groupId>
<artifactId>rxnetty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
@ -75,6 +90,20 @@ @@ -75,6 +90,20 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons-dependencies</artifactId>
<version>1.2.0.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-dependencies</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

10
src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java

@ -4,12 +4,15 @@ import java.util.List; @@ -4,12 +4,15 @@ import java.util.List;
import java.util.Map;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.actuate.GatewayEndpoint;
import org.springframework.cloud.gateway.api.RouteReader;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter;
import org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter;
import org.springframework.cloud.gateway.filter.WriteResponseFilter;
import org.springframework.cloud.gateway.filter.route.AddRequestHeaderRouteFilter;
@ -86,6 +89,13 @@ public class GatewayAutoConfiguration { @@ -86,6 +89,13 @@ public class GatewayAutoConfiguration {
// GlobalFilter beans
@Bean
@ConditionalOnClass(LoadBalancerClient.class)
@ConditionalOnBean(LoadBalancerClient.class)
public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
return new LoadBalancerClientFilter(client);
}
@Bean
public RouteToRequestUrlFilter routeToRequestUrlFilter() {
return new RouteToRequestUrlFilter();

59
src/main/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilter.java

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
package org.springframework.cloud.gateway.filter;
import java.net.URI;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.UriComponentsBuilder;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getAttribute;
import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
*/
public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
private static final Log log = LogFactory.getLog(LoadBalancerClientFilter.class);
public static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10100;
private final LoadBalancerClient loadBalancer;
public LoadBalancerClientFilter(LoadBalancerClient loadBalancer) {
this.loadBalancer = loadBalancer;
}
@Override
public int getOrder() {
return LOAD_BALANCER_CLIENT_FILTER_ORDER;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
URI url = getAttribute(exchange, GATEWAY_REQUEST_URL_ATTR, URI.class);
if (url == null || !url.getScheme().equals("lb")) {
return chain.filter(exchange);
}
log.trace("LoadBalancerClientFilter url before: " + url);
final ServiceInstance instance = loadBalancer.choose(url.getHost());
URI requestUrl = UriComponentsBuilder.fromUri(url)
.scheme(instance.isSecure()? "https" : "http") //TODO: support websockets
.host(instance.getHost())
.port(instance.getPort())
.build(true)
.toUri();
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
return chain.filter(exchange);
}
}

1
src/main/java/org/springframework/cloud/gateway/filter/RouteToRequestUrlFilter.java

@ -5,7 +5,6 @@ import java.net.URI; @@ -5,7 +5,6 @@ import java.net.URI;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.config.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;

26
src/test/java/org/springframework/cloud/gateway/test/GatewayIntegrationTests.java

@ -38,7 +38,8 @@ import reactor.core.publisher.Mono; @@ -38,7 +38,8 @@ import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@SpringBootTest(webEnvironment = RANDOM_PORT,
properties = "spring.cloud.bootstrap.enabled=false")
@SuppressWarnings("unchecked")
public class GatewayIntegrationTests {
@ -209,6 +210,29 @@ public class GatewayIntegrationTests { @@ -209,6 +210,29 @@ public class GatewayIntegrationTests {
);
}
@Test
public void loadBalancerFilterWorks() {
Mono<ClientResponse> result = webClient.exchange(
GET("http://localhost:" + port + "/get")
.header("Host", "www.loadbalancerclient.org")
.build()
);
verify( () ->
StepVerifier.create(result)
.consumeNextWith(
response -> {
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
assertThat(httpHeaders.getFirst(ROUTE_ID_HEADER))
.isEqualTo("load_balancer_client_test");
HttpStatus statusCode = response.statusCode();
assertThat(statusCode).isEqualTo(HttpStatus.OK);
})
.expectComplete()
.verify(Duration.ofMinutes(5))
);
}
@Test
public void postWorks() {
ClientRequest<Mono<String>> request = POST("http://localhost:" + port + "/post")

1
src/test/java/org/springframework/cloud/gateway/test/GatewayTestApplication.java

@ -9,6 +9,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -9,6 +9,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
public class GatewayTestApplication {
public static void main(String[] args) {
System.setProperty("spring.cloud.bootstrap.enabled", "false"); //TODO: fix bootstrap
SpringApplication.run(GatewayTestApplication.class, args);
}
}

12
src/test/resources/application.yml

@ -47,6 +47,12 @@ spring: @@ -47,6 +47,12 @@ spring:
filters:
- AddResponseHeader=X-Request-Foo, Bar
# =====================================
- id: load_balancer_client_test
uri: lb://myservice
predicates:
- Host=**.loadbalancerclient.org
# =====================================
- id: redirect_to_test
uri: http://httpbin.org:80
@ -129,6 +135,12 @@ spring: @@ -129,6 +135,12 @@ spring:
predicates:
- name: Url
value: /**
myservice:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
listOfServers: httpbin.org:80
logging:
level:
org.springframework.cloud.gateway: TRACE

Loading…
Cancel
Save