Fix up sample for 1.0
This commit is contained in:
0
spring-cloud-gateway-sample/.jdk8
Normal file
0
spring-cloud-gateway-sample/.jdk8
Normal file
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
<groupId>org.springframework.cloud.gateway</groupId>
|
<groupId>org.springframework.cloud.gateway</groupId>
|
||||||
<artifactId>spring-cloud-gateway-sample</artifactId>
|
<artifactId>spring-cloud-gateway-sample</artifactId>
|
||||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Spring Cloud Gateway Sample</name>
|
<name>Spring Cloud Gateway Sample</name>
|
||||||
@@ -18,9 +17,6 @@
|
|||||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@@ -30,6 +26,11 @@
|
|||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-gateway-mvc</artifactId>
|
<artifactId>spring-cloud-gateway-mvc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.isomorphism</groupId>
|
||||||
|
<artifactId>token-bucket</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|||||||
@@ -17,55 +17,44 @@
|
|||||||
|
|
||||||
package org.springframework.cloud.gateway.sample;
|
package org.springframework.cloud.gateway.sample;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import java.net.URI;
|
||||||
import org.springframework.boot.SpringBootConfiguration;
|
import java.util.function.Function;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|
||||||
import org.springframework.cloud.gateway.EnableGateway;
|
|
||||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
|
||||||
import org.springframework.cloud.gateway.route.Routes;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
|
|
||||||
import static org.springframework.cloud.gateway.filter.factory.WebFilterFactories.addResponseHeader;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.host;
|
import org.springframework.boot.SpringApplication;
|
||||||
import static org.springframework.cloud.gateway.handler.predicate.RoutePredicates.path;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import static org.springframework.tuple.TupleBuilder.tuple;
|
import org.springframework.cloud.gateway.mvc.ProxyExchange;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Spencer Gibb
|
* @author Spencer Gibb
|
||||||
|
* @author Dave Syer
|
||||||
*/
|
*/
|
||||||
@SpringBootConfiguration
|
@RestController
|
||||||
@EnableAutoConfiguration
|
@SpringBootApplication
|
||||||
@EnableGateway
|
|
||||||
public class GatewaySampleApplication {
|
public class GatewaySampleApplication {
|
||||||
|
|
||||||
@Bean
|
@Value("${remote.home}")
|
||||||
public RouteLocator customRouteLocator(ThrottleWebFilterFactory throttle) {
|
private URI home;
|
||||||
return Routes.locator()
|
|
||||||
.route("test")
|
@GetMapping(path="/test", headers="x-host=png.abc.org")
|
||||||
.uri("http://httpbin.org:80")
|
public ResponseEntity<Object> proxy(ProxyExchange<Object> proxy) throws Exception {
|
||||||
.predicate(host("**.abc.org").and(path("/image/png")))
|
return proxy.uri(home.toString() + "/image/png")
|
||||||
.addResponseHeader("X-TestHeader", "foobar")
|
.get(header("X-TestHeader", "foobar"));
|
||||||
.and()
|
|
||||||
.route("test2")
|
|
||||||
.uri("http://httpbin.org:80")
|
|
||||||
.predicate(path("/image/webp"))
|
|
||||||
.add(addResponseHeader("X-AnotherHeader", "baz"))
|
|
||||||
.and()
|
|
||||||
.route("test3")
|
|
||||||
.order(-1)
|
|
||||||
.uri("http://httpbin.org:80")
|
|
||||||
.predicate(host("**.throttle.org").and(path("/get")))
|
|
||||||
.add(throttle.apply(tuple().of("capacity", 1,
|
|
||||||
"refillTokens", 1,
|
|
||||||
"refillPeriod", 10,
|
|
||||||
"refillUnit", "SECONDS")))
|
|
||||||
.and()
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@GetMapping("/test2")
|
||||||
public ThrottleWebFilterFactory throttleWebFilterFactory() {
|
public ResponseEntity<Object> proxyFoos(ProxyExchange<Object> proxy) throws Exception {
|
||||||
return new ThrottleWebFilterFactory();
|
return proxy.uri(home.toString() + "/image/webp").get(header("X-AnotherHeader", "baz"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Function<ResponseEntity<Object>, ResponseEntity<Object>> header(String key,
|
||||||
|
String value) {
|
||||||
|
return response -> ResponseEntity.status(response.getStatusCode())
|
||||||
|
.headers(response.getHeaders()).header(key, value)
|
||||||
|
.body(response.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013-2017 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.gateway.sample;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.isomorphism.util.TokenBucket;
|
|
||||||
import org.isomorphism.util.TokenBuckets;
|
|
||||||
import org.springframework.cloud.gateway.filter.factory.WebFilterFactory;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.tuple.Tuple;
|
|
||||||
import org.springframework.web.server.WebFilter;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample throttling filter.
|
|
||||||
* See https://github.com/bbeck/token-bucket
|
|
||||||
*/
|
|
||||||
public class ThrottleWebFilterFactory implements WebFilterFactory {
|
|
||||||
private Log log = LogFactory.getLog(getClass());
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WebFilter apply(Tuple args) {
|
|
||||||
int capacity = args.getInt("capacity");
|
|
||||||
int refillTokens = args.getInt("refillTokens");
|
|
||||||
int refillPeriod = args.getInt("refillPeriod");
|
|
||||||
TimeUnit refillUnit = TimeUnit.valueOf(args.getString("refillUnit"));
|
|
||||||
|
|
||||||
final TokenBucket tokenBucket = TokenBuckets.builder()
|
|
||||||
.withCapacity(capacity)
|
|
||||||
.withFixedIntervalRefillStrategy(refillTokens, refillPeriod, refillUnit)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
return (exchange, chain) -> {
|
|
||||||
//TODO: get a token bucket for a key
|
|
||||||
log.debug("TokenBucket capacity: " + tokenBucket.getCapacity());
|
|
||||||
boolean consumed = tokenBucket.tryConsume();
|
|
||||||
if (consumed) {
|
|
||||||
return chain.filter(exchange);
|
|
||||||
}
|
|
||||||
exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
|
|
||||||
return exchange.getResponse().setComplete();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +1,5 @@
|
|||||||
test:
|
|
||||||
hostport: httpbin.org:80
|
|
||||||
# hostport: localhost:5000
|
|
||||||
uri: http://${test.hostport}
|
|
||||||
|
|
||||||
spring:
|
|
||||||
cloud:
|
|
||||||
gateway:
|
|
||||||
default-filters:
|
|
||||||
- AddResponseHeader=X-Response-Default-Foo, Default-Bar
|
|
||||||
|
|
||||||
routes:
|
|
||||||
# =====================================
|
|
||||||
- id: default_path_to_httpbin
|
|
||||||
uri: ${test.uri}
|
|
||||||
order: 10000
|
|
||||||
predicates:
|
|
||||||
- Path=/**
|
|
||||||
|
|
||||||
logging:
|
|
||||||
level:
|
|
||||||
org.springframework.cloud.gateway: TRACE
|
|
||||||
org.springframework.http.server.reactive: DEBUG
|
|
||||||
org.springframework.web.reactive: DEBUG
|
|
||||||
reactor.ipc.netty: DEBUG
|
|
||||||
|
|
||||||
management:
|
management:
|
||||||
context-path: /admin
|
security:
|
||||||
# port: 8081
|
enabled: false
|
||||||
|
remote:
|
||||||
|
home: http://httpbin.org
|
||||||
|
|||||||
@@ -17,20 +17,18 @@
|
|||||||
|
|
||||||
package org.springframework.cloud.gateway.sample;
|
package org.springframework.cloud.gateway.sample;
|
||||||
|
|
||||||
import org.junit.Before;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.boot.web.server.LocalServerPort;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
|
||||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
import reactor.test.StepVerifier;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.RequestEntity;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||||
@@ -39,34 +37,26 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
|
|||||||
* @author Spencer Gibb
|
* @author Spencer Gibb
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest(classes = GatewaySampleApplication.class, webEnvironment = RANDOM_PORT)
|
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||||
public class GatewaySampleApplicationTests {
|
public class GatewaySampleApplicationTests {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
protected int port = 0;
|
protected int port = 0;
|
||||||
|
|
||||||
protected WebClient webClient;
|
@Autowired
|
||||||
protected String baseUri;
|
protected TestRestTemplate rest;
|
||||||
|
|
||||||
@Before
|
@Test
|
||||||
public void setup() {
|
public void passthru() {
|
||||||
baseUri = "http://localhost:" + port;
|
assertThat(rest.getForEntity("/test2", byte[].class).getStatusCode())
|
||||||
this.webClient = WebClient.create(baseUri);
|
.isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void contextLoads() {
|
public void header() throws Exception {
|
||||||
Mono<ClientResponse> result = webClient.get()
|
assertThat(rest
|
||||||
.uri("/get")
|
.exchange(RequestEntity.get(new URI("/test"))
|
||||||
.exchange();
|
.header("x-host", "png.abc.org").build(), byte[].class)
|
||||||
|
.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
StepVerifier.create(result)
|
|
||||||
.consumeNextWith(
|
|
||||||
response -> {
|
|
||||||
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
|
|
||||||
HttpHeaders httpHeaders = response.headers().asHttpHeaders();
|
|
||||||
})
|
|
||||||
.expectComplete()
|
|
||||||
.verify(Duration.ofSeconds(5));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user