Bumping versions

This commit is contained in:
buildmaster
2020-09-17 18:06:17 +00:00
parent c7b8e8db19
commit 38030d33be
261 changed files with 2503 additions and 4187 deletions

View File

@@ -137,8 +137,7 @@ public class ProxyExchange<T> {
/**
* Contains headers that are considered case-sensitive by default.
*/
public static Set<String> DEFAULT_SENSITIVE = new HashSet<>(
Arrays.asList("cookie", "authorization"));
public static Set<String> DEFAULT_SENSITIVE = new HashSet<>(Arrays.asList("cookie", "authorization"));
private URI uri;
@@ -160,16 +159,14 @@ public class ProxyExchange<T> {
private Type responseType;
public ProxyExchange(RestTemplate rest, NativeWebRequest webRequest,
ModelAndViewContainer mavContainer, WebDataBinderFactory binderFactory,
Type type) {
public ProxyExchange(RestTemplate rest, NativeWebRequest webRequest, ModelAndViewContainer mavContainer,
WebDataBinderFactory binderFactory, Type type) {
this.responseType = type;
this.rest = rest;
this.webRequest = webRequest;
this.mavContainer = mavContainer;
this.binderFactory = binderFactory;
this.delegate = new RequestResponseBodyMethodProcessor(
rest.getMessageConverters());
this.delegate = new RequestResponseBodyMethodProcessor(rest.getMessageConverters());
}
/**
@@ -249,28 +246,24 @@ public class ProxyExchange<T> {
}
public String path() {
return (String) this.webRequest.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE,
return (String) this.webRequest.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE,
WebRequest.SCOPE_REQUEST);
}
public String path(String prefix) {
String path = path();
if (!path.startsWith(prefix)) {
throw new IllegalArgumentException(
"Path does not start with prefix (" + prefix + "): " + path);
throw new IllegalArgumentException("Path does not start with prefix (" + prefix + "): " + path);
}
return path.substring(prefix.length());
}
public void forward(String path) {
HttpServletRequest request = this.webRequest
.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response = this.webRequest
.getNativeResponse(HttpServletResponse.class);
HttpServletRequest request = this.webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response = this.webRequest.getNativeResponse(HttpServletResponse.class);
try {
request.getRequestDispatcher(path).forward(
new BodyForwardingHttpServletRequest(request, response), response);
request.getRequestDispatcher(path).forward(new BodyForwardingHttpServletRequest(request, response),
response);
}
catch (Exception e) {
throw new IllegalStateException("Cannot forward request", e);
@@ -278,79 +271,65 @@ public class ProxyExchange<T> {
}
public ResponseEntity<T> get() {
RequestEntity<?> requestEntity = headers((BodyBuilder) RequestEntity.get(uri))
.build();
RequestEntity<?> requestEntity = headers((BodyBuilder) RequestEntity.get(uri)).build();
return exchange(requestEntity);
}
public <S> ResponseEntity<S> get(
Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
public <S> ResponseEntity<S> get(Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
return converter.apply(get());
}
public ResponseEntity<T> head() {
RequestEntity<?> requestEntity = headers((BodyBuilder) RequestEntity.head(uri))
.build();
RequestEntity<?> requestEntity = headers((BodyBuilder) RequestEntity.head(uri)).build();
return exchange(requestEntity);
}
public <S> ResponseEntity<S> head(
Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
public <S> ResponseEntity<S> head(Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
return converter.apply(head());
}
public ResponseEntity<T> options() {
RequestEntity<?> requestEntity = headers((BodyBuilder) RequestEntity.options(uri))
.build();
RequestEntity<?> requestEntity = headers((BodyBuilder) RequestEntity.options(uri)).build();
return exchange(requestEntity);
}
public <S> ResponseEntity<S> options(
Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
public <S> ResponseEntity<S> options(Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
return converter.apply(options());
}
public ResponseEntity<T> post() {
RequestEntity<Object> requestEntity = headers(RequestEntity.post(uri))
.body(body());
RequestEntity<Object> requestEntity = headers(RequestEntity.post(uri)).body(body());
return exchange(requestEntity);
}
public <S> ResponseEntity<S> post(
Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
public <S> ResponseEntity<S> post(Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
return converter.apply(post());
}
public ResponseEntity<T> delete() {
RequestEntity<Object> requestEntity = headers(
(BodyBuilder) RequestEntity.delete(uri)).body(body());
RequestEntity<Object> requestEntity = headers((BodyBuilder) RequestEntity.delete(uri)).body(body());
return exchange(requestEntity);
}
public <S> ResponseEntity<S> delete(
Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
public <S> ResponseEntity<S> delete(Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
return converter.apply(delete());
}
public ResponseEntity<T> put() {
RequestEntity<Object> requestEntity = headers(RequestEntity.put(uri))
.body(body());
RequestEntity<Object> requestEntity = headers(RequestEntity.put(uri)).body(body());
return exchange(requestEntity);
}
public <S> ResponseEntity<S> put(
Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
public <S> ResponseEntity<S> put(Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
return converter.apply(put());
}
public ResponseEntity<T> patch() {
RequestEntity<Object> requestEntity = headers(RequestEntity.patch(uri))
.body(body());
RequestEntity<Object> requestEntity = headers(RequestEntity.patch(uri)).body(body());
return exchange(requestEntity);
}
public <S> ResponseEntity<S> patch(
Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
public <S> ResponseEntity<S> patch(Function<ResponseEntity<T>, ResponseEntity<S>> converter) {
return converter.apply(patch());
}
@@ -359,8 +338,7 @@ public class ProxyExchange<T> {
if (type instanceof TypeVariable || type instanceof WildcardType) {
type = Object.class;
}
return rest.exchange(requestEntity,
ParameterizedTypeReference.forType(responseType));
return rest.exchange(requestEntity, ParameterizedTypeReference.forType(responseType));
}
private BodyBuilder headers(BodyBuilder builder) {
@@ -380,14 +358,13 @@ public class ProxyExchange<T> {
private void proxy() {
try {
URI uri = new URI(webRequest.getNativeRequest(HttpServletRequest.class)
.getRequestURL().toString());
URI uri = new URI(webRequest.getNativeRequest(HttpServletRequest.class).getRequestURL().toString());
appendForwarded(uri);
appendXForwarded(uri);
}
catch (URISyntaxException e) {
throw new IllegalStateException("Cannot create URI for request: " + webRequest
.getNativeRequest(HttpServletRequest.class).getRequestURL());
throw new IllegalStateException("Cannot create URI for request: "
+ webRequest.getNativeRequest(HttpServletRequest.class).getRequestURL());
}
}
@@ -450,8 +427,7 @@ public class ProxyExchange<T> {
return result.getTarget();
}
}
MethodParameter input = new MethodParameter(
ClassUtils.getMethod(BodyGrabber.class, "body", Object.class), 0);
MethodParameter input = new MethodParameter(ClassUtils.getMethod(BodyGrabber.class, "body", Object.class), 0);
try {
delegate.resolveArgument(input, mavContainer, webRequest, binderFactory);
}
@@ -459,8 +435,7 @@ public class ProxyExchange<T> {
throw new IllegalStateException("Cannot resolve body", e);
}
String name = Conventions.getVariableNameForParameter(input);
BindingResult result = (BindingResult) mavContainer.getModel()
.get(BindingResult.MODEL_KEY_PREFIX + name);
BindingResult result = (BindingResult) mavContainer.getModel().get(BindingResult.MODEL_KEY_PREFIX + name);
return result.getTarget();
}
@@ -493,8 +468,7 @@ public class ProxyExchange<T> {
private HttpServletResponse response;
BodyForwardingHttpServletRequest(HttpServletRequest request,
HttpServletResponse response) {
BodyForwardingHttpServletRequest(HttpServletRequest request, HttpServletResponse response) {
super(request);
this.request = request;
this.response = response;
@@ -508,16 +482,13 @@ public class ProxyExchange<T> {
@Override
public ServletInputStream getInputStream() throws IOException {
Object body = body();
MethodParameter output = new MethodParameter(
ClassUtils.getMethod(BodySender.class, "body"), -1);
ServletOutputToInputConverter response = new ServletOutputToInputConverter(
this.response);
MethodParameter output = new MethodParameter(ClassUtils.getMethod(BodySender.class, "body"), -1);
ServletOutputToInputConverter response = new ServletOutputToInputConverter(this.response);
ServletWebRequest webRequest = new ServletWebRequest(this.request, response);
try {
delegate.handleReturnValue(body, output, mavContainer, webRequest);
}
catch (HttpMessageNotWritableException
| HttpMediaTypeNotAcceptableException e) {
catch (HttpMessageNotWritableException | HttpMediaTypeNotAcceptableException e) {
throw new IllegalStateException("Cannot convert body", e);
}
return response.getInputStream();
@@ -596,8 +567,7 @@ class ServletOutputToInputConverter extends HttpServletResponseWrapper {
}
public ServletInputStream getInputStream() {
ByteArrayInputStream body = new ByteArrayInputStream(
builder.toString().getBytes());
ByteArrayInputStream body = new ByteArrayInputStream(builder.toString().getBytes());
return new ServletInputStream() {
@Override

View File

@@ -72,11 +72,9 @@ public class ProxyExchangeArgumentResolver implements HandlerMethodArgumentResol
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
ProxyExchange<?> proxy = new ProxyExchange<>(rest, webRequest, mavContainer,
binderFactory, type(parameter));
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
ProxyExchange<?> proxy = new ProxyExchange<>(rest, webRequest, mavContainer, binderFactory, type(parameter));
proxy.headers(headers);
if (this.autoForwardedHeaders.size() > 0) {
proxy.headers(extractAutoForwardedHeaders(webRequest));
@@ -97,15 +95,13 @@ public class ProxyExchangeArgumentResolver implements HandlerMethodArgumentResol
}
private HttpHeaders extractAutoForwardedHeaders(NativeWebRequest webRequest) {
HttpServletRequest nativeRequest = webRequest
.getNativeRequest(HttpServletRequest.class);
HttpServletRequest nativeRequest = webRequest.getNativeRequest(HttpServletRequest.class);
Enumeration<String> headerNames = nativeRequest.getHeaderNames();
HttpHeaders headers = new HttpHeaders();
while (headerNames.hasMoreElements()) {
String header = headerNames.nextElement();
if (this.autoForwardedHeaders.contains(header.toLowerCase())) {
headers.addAll(header,
Collections.list(nativeRequest.getHeaders(header)));
headers.addAll(header, Collections.list(nativeRequest.getHeaders(header)));
}
}
return headers;

View File

@@ -56,8 +56,8 @@ public class ProxyResponseAutoConfiguration implements WebMvcConfigurer {
@Bean
@ConditionalOnMissingBean
public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver(
Optional<RestTemplateBuilder> optional, ProxyProperties proxy) {
public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver(Optional<RestTemplateBuilder> optional,
ProxyProperties proxy) {
RestTemplateBuilder builder = optional.orElse(new RestTemplateBuilder());
RestTemplate template = builder.build();
template.setErrorHandler(new NoOpResponseErrorHandler());
@@ -67,8 +67,7 @@ public class ProxyResponseAutoConfiguration implements WebMvcConfigurer {
return true;
}
});
ProxyExchangeArgumentResolver resolver = new ProxyExchangeArgumentResolver(
template);
ProxyExchangeArgumentResolver resolver = new ProxyExchangeArgumentResolver(template);
resolver.setHeaders(proxy.convertHeaders());
resolver.setAutoForwardedHeaders(proxy.getAutoForward());
resolver.setSensitive(proxy.getSensitive()); // can be null
@@ -76,8 +75,7 @@ public class ProxyResponseAutoConfiguration implements WebMvcConfigurer {
}
@Override
public void addArgumentResolvers(
List<HandlerMethodArgumentResolver> argumentResolvers) {
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(context.getBean(ProxyExchangeArgumentResolver.class));
}

View File

@@ -84,26 +84,22 @@ public class ProductionConfigurationTests {
@Test
public void path() throws Exception {
assertThat(rest.getForObject("/proxy/path/1", Foo.class).getName())
.isEqualTo("foo");
assertThat(rest.getForObject("/proxy/path/1", Foo.class).getName()).isEqualTo("foo");
}
@Test
public void resource() throws Exception {
assertThat(rest.getForObject("/proxy/html/test.html", String.class))
.contains("<body>Test");
assertThat(rest.getForObject("/proxy/html/test.html", String.class)).contains("<body>Test");
}
@Test
public void resourceWithNoType() throws Exception {
assertThat(rest.getForObject("/proxy/typeless/test.html", String.class))
.contains("<body>Test");
assertThat(rest.getForObject("/proxy/typeless/test.html", String.class)).contains("<body>Test");
}
@Test
public void missing() throws Exception {
assertThat(rest.getForEntity("/proxy/missing/0", Foo.class).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);
assertThat(rest.getForEntity("/proxy/missing/0", Foo.class).getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
}
@Test
@@ -113,20 +109,18 @@ public class ProductionConfigurationTests {
@Test
public void post() throws Exception {
assertThat(rest.postForObject("/proxy/0", Collections.singletonMap("name", "foo"),
Bar.class).getName()).isEqualTo("host=localhost:" + port + ";foo");
assertThat(rest.postForObject("/proxy/0", Collections.singletonMap("name", "foo"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foo");
}
@Test
public void forward() throws Exception {
assertThat(rest.getForObject("/forward/foos/0", Foo.class).getName())
.isEqualTo("bye");
assertThat(rest.getForObject("/forward/foos/0", Foo.class).getName()).isEqualTo("bye");
}
@Test
public void forwardHeader() throws Exception {
ResponseEntity<Foo> result = rest.getForEntity("/forward/special/foos/0",
Foo.class);
ResponseEntity<Foo> result = rest.getForEntity("/forward/special/foos/0", Foo.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody().getName()).isEqualTo("FOO");
}
@@ -134,11 +128,8 @@ public class ProductionConfigurationTests {
@Test
public void postForwardHeader() throws Exception {
ResponseEntity<List<Bar>> result = rest.exchange(
RequestEntity
.post(rest.getRestTemplate().getUriTemplateHandler()
.expand("/forward/special/bars"))
.body(Collections
.singletonList(Collections.singletonMap("name", "foo"))),
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/forward/special/bars"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
new ParameterizedTypeReference<List<Bar>>() {
});
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
@@ -147,13 +138,11 @@ public class ProductionConfigurationTests {
@Test
public void postForwardBody() throws Exception {
ResponseEntity<String> result = rest.exchange(
RequestEntity
.post(rest.getRestTemplate().getUriTemplateHandler()
.expand("/forward/body/bars"))
.body(Collections
.singletonList(Collections.singletonMap("name", "foo"))),
String.class);
ResponseEntity<String> result = rest
.exchange(
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/forward/body/bars"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).contains("foo");
}
@@ -161,11 +150,8 @@ public class ProductionConfigurationTests {
@Test
public void postForwardForgetBody() throws Exception {
ResponseEntity<String> result = rest.exchange(
RequestEntity
.post(rest.getRestTemplate().getUriTemplateHandler()
.expand("/forward/forget/bars"))
.body(Collections
.singletonList(Collections.singletonMap("name", "foo"))),
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/forward/forget/bars"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).contains("foo");
@@ -174,11 +160,8 @@ public class ProductionConfigurationTests {
@Test
public void postForwardBodyFoo() throws Exception {
ResponseEntity<List<Bar>> result = rest.exchange(
RequestEntity
.post(rest.getRestTemplate().getUriTemplateHandler()
.expand("/forward/body/bars"))
.body(Collections
.singletonList(Collections.singletonMap("name", "foo"))),
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/forward/body/bars"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
new ParameterizedTypeReference<List<Bar>>() {
});
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
@@ -188,57 +171,44 @@ public class ProductionConfigurationTests {
@Test
public void list() throws Exception {
assertThat(rest.exchange(
RequestEntity
.post(rest.getRestTemplate().getUriTemplateHandler()
.expand("/proxy"))
.body(Collections
.singletonList(Collections.singletonMap("name", "foo"))),
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
new ParameterizedTypeReference<List<Bar>>() {
}).getBody().iterator().next().getName())
.isEqualTo("host=localhost:" + port + ";foo");
}).getBody().iterator().next().getName()).isEqualTo("host=localhost:" + port + ";foo");
}
@Test
public void bodyless() throws Exception {
assertThat(rest.postForObject("/proxy/0", Collections.singletonMap("name", "foo"),
Bar.class).getName()).isEqualTo("host=localhost:" + port + ";foo");
assertThat(rest.postForObject("/proxy/0", Collections.singletonMap("name", "foo"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foo");
}
@Test
public void entity() throws Exception {
assertThat(rest.exchange(
RequestEntity
.post(rest.getRestTemplate().getUriTemplateHandler()
.expand("/proxy/entity"))
.body(Collections.singletonMap("name", "foo")),
new ParameterizedTypeReference<List<Bar>>() {
}).getBody().iterator().next().getName())
.isEqualTo("host=localhost:" + port + ";foo");
assertThat(
rest.exchange(RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/entity"))
.body(Collections.singletonMap("name", "foo")), new ParameterizedTypeReference<List<Bar>>() {
}).getBody().iterator().next().getName()).isEqualTo("host=localhost:" + port + ";foo");
}
@Test
public void entityWithType() throws Exception {
assertThat(rest.exchange(
RequestEntity
.post(rest.getRestTemplate().getUriTemplateHandler()
.expand("/proxy/type"))
.body(Collections.singletonMap("name", "foo")),
new ParameterizedTypeReference<List<Bar>>() {
}).getBody().iterator().next().getName())
.isEqualTo("host=localhost:" + port + ";foo");
assertThat(
rest.exchange(RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/type"))
.body(Collections.singletonMap("name", "foo")), new ParameterizedTypeReference<List<Bar>>() {
}).getBody().iterator().next().getName()).isEqualTo("host=localhost:" + port + ";foo");
}
@Test
public void single() throws Exception {
assertThat(rest.postForObject("/proxy/single",
Collections.singletonMap("name", "foobar"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foobar");
assertThat(rest.postForObject("/proxy/single", Collections.singletonMap("name", "foobar"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foobar");
}
@Test
public void converter() throws Exception {
assertThat(rest.postForObject("/proxy/converter",
Collections.singletonMap("name", "foobar"), Bar.class).getName())
assertThat(
rest.postForObject("/proxy/converter", Collections.singletonMap("name", "foobar"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foobar");
}
@@ -250,8 +220,7 @@ public class ProductionConfigurationTests {
@Test
public void deleteWithoutBody() throws Exception {
ResponseEntity<Void> deleteResponse = rest.exchange("/proxy/{id}/no-body",
HttpMethod.DELETE, null, Void.TYPE,
ResponseEntity<Void> deleteResponse = rest.exchange("/proxy/{id}/no-body", HttpMethod.DELETE, null, Void.TYPE,
Collections.singletonMap("id", "123"));
assertThat(deleteResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@@ -261,28 +230,20 @@ public class ProductionConfigurationTests {
Foo foo = new Foo("to-be-deleted");
ParameterizedTypeReference<Map<String, Foo>> returnType = new ParameterizedTypeReference<Map<String, Foo>>() {
};
ResponseEntity<Map<String, Foo>> deleteResponse = rest.exchange("/proxy/{id}",
HttpMethod.DELETE, new HttpEntity<Foo>(foo), returnType,
Collections.singletonMap("id", "123"));
ResponseEntity<Map<String, Foo>> deleteResponse = rest.exchange("/proxy/{id}", HttpMethod.DELETE,
new HttpEntity<Foo>(foo), returnType, Collections.singletonMap("id", "123"));
assertThat(deleteResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(deleteResponse.getBody().get("deleted"))
.isEqualToComparingFieldByField(foo);
assertThat(deleteResponse.getBody().get("deleted")).isEqualToComparingFieldByField(foo);
}
@Test
@SuppressWarnings({ "Duplicates", "unchecked" })
public void headers() throws Exception {
Map<String, List<String>> headers = rest
.exchange(
RequestEntity
.get(rest.getRestTemplate().getUriTemplateHandler()
.expand("/proxy/headers"))
.header("foo", "bar").header("abc", "xyz")
.header("baz", "fob").build(),
Map.class)
.exchange(RequestEntity.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/headers"))
.header("foo", "bar").header("abc", "xyz").header("baz", "fob").build(), Map.class)
.getBody();
assertThat(headers).doesNotContainKey("foo").doesNotContainKey("hello")
.containsKeys("bar", "abc");
assertThat(headers).doesNotContainKey("foo").doesNotContainKey("hello").containsKeys("bar", "abc");
assertThat(headers.get("bar")).containsOnly("hello");
assertThat(headers.get("abc")).containsOnly("123");
@@ -292,9 +253,7 @@ public class ProductionConfigurationTests {
@Test
public void forwardedHeaderUsesHost() throws Exception {
Map<String, List<String>> headers = rest
.exchange(RequestEntity
.get(rest.getRestTemplate().getUriTemplateHandler()
.expand("/proxy/headers"))
.exchange(RequestEntity.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/headers"))
.header("host", "foo:1234").build(), Map.class)
.getBody();
@@ -323,35 +282,32 @@ public class ProductionConfigurationTests {
}
@GetMapping("/proxy/{id}")
public ResponseEntity<?> proxyFoos(@PathVariable Integer id,
ProxyExchange<?> proxy) throws Exception {
public ResponseEntity<?> proxyFoos(@PathVariable Integer id, ProxyExchange<?> proxy) throws Exception {
return proxy.uri(home.toString() + "/foos/" + id).get();
}
@GetMapping("/proxy/path/**")
public ResponseEntity<?> proxyPath(ProxyExchange<?> proxy,
UriComponentsBuilder uri) throws Exception {
public ResponseEntity<?> proxyPath(ProxyExchange<?> proxy, UriComponentsBuilder uri) throws Exception {
String path = proxy.path("/proxy/path/");
return proxy.uri(home.toString() + "/foos/" + path).get();
}
@GetMapping("/proxy/html/**")
public ResponseEntity<String> proxyHtml(ProxyExchange<String> proxy,
UriComponentsBuilder uri) throws Exception {
public ResponseEntity<String> proxyHtml(ProxyExchange<String> proxy, UriComponentsBuilder uri)
throws Exception {
String path = proxy.path("/proxy/html");
return proxy.uri(home.toString() + path).get();
}
@GetMapping("/proxy/typeless/**")
public ResponseEntity<?> proxyTypeless(ProxyExchange<byte[]> proxy,
UriComponentsBuilder uri) throws Exception {
public ResponseEntity<?> proxyTypeless(ProxyExchange<byte[]> proxy, UriComponentsBuilder uri)
throws Exception {
String path = proxy.path("/proxy/typeless");
return proxy.uri(home.toString() + path).get();
}
@GetMapping("/proxy/missing/{id}")
public ResponseEntity<?> proxyMissing(@PathVariable Integer id,
ProxyExchange<?> proxy) throws Exception {
public ResponseEntity<?> proxyMissing(@PathVariable Integer id, ProxyExchange<?> proxy) throws Exception {
return proxy.uri(home.toString() + "/missing/" + id).get();
}
@@ -361,47 +317,39 @@ public class ProductionConfigurationTests {
}
@PostMapping("/proxy/{id}")
public ResponseEntity<?> proxyBars(@PathVariable Integer id,
@RequestBody Map<String, Object> body,
public ResponseEntity<?> proxyBars(@PathVariable Integer id, @RequestBody Map<String, Object> body,
ProxyExchange<List<Object>> proxy) throws Exception {
body.put("id", id);
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(body))
.post(this::first);
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(body)).post(this::first);
}
@PostMapping("/proxy")
public ResponseEntity<?> barsWithNoBody(ProxyExchange<?> proxy)
throws Exception {
public ResponseEntity<?> barsWithNoBody(ProxyExchange<?> proxy) throws Exception {
return proxy.uri(home.toString() + "/bars").post();
}
@PostMapping("/proxy/entity")
public ResponseEntity<?> explicitEntity(@RequestBody Foo foo,
ProxyExchange<?> proxy) throws Exception {
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
.post();
public ResponseEntity<?> explicitEntity(@RequestBody Foo foo, ProxyExchange<?> proxy) throws Exception {
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo)).post();
}
@PostMapping("/proxy/type")
public ResponseEntity<List<Bar>> explicitEntityWithType(@RequestBody Foo foo,
ProxyExchange<List<Bar>> proxy) throws Exception {
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
.post();
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo)).post();
}
@PostMapping("/proxy/single")
public ResponseEntity<?> implicitEntity(@RequestBody Foo foo,
ProxyExchange<List<Object>> proxy) throws Exception {
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
.post(this::first);
public ResponseEntity<?> implicitEntity(@RequestBody Foo foo, ProxyExchange<List<Object>> proxy)
throws Exception {
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo)).post(this::first);
}
@PostMapping("/proxy/converter")
public ResponseEntity<Bar> implicitEntityWithConverter(@RequestBody Foo foo,
ProxyExchange<List<Bar>> proxy) throws Exception {
public ResponseEntity<Bar> implicitEntityWithConverter(@RequestBody Foo foo, ProxyExchange<List<Bar>> proxy)
throws Exception {
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
.post(response -> ResponseEntity.status(response.getStatusCode())
.headers(response.getHeaders())
.post(response -> ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders())
.body(response.getBody().iterator().next()));
}
@@ -411,18 +359,16 @@ public class ProductionConfigurationTests {
}
@DeleteMapping("/proxy/{id}/no-body")
public ResponseEntity<?> deleteWithoutBody(@PathVariable Integer id,
ProxyExchange<?> proxy) throws Exception {
public ResponseEntity<?> deleteWithoutBody(@PathVariable Integer id, ProxyExchange<?> proxy)
throws Exception {
return proxy.uri(home.toString() + "/foos/" + id + "/no-body").delete();
}
@DeleteMapping("/proxy/{id}")
public ResponseEntity<?> deleteWithBody(@PathVariable Integer id,
@RequestBody Foo foo, ProxyExchange<?> proxy) throws Exception {
return proxy.uri(home.toString() + "/foos/" + id).body(foo)
.delete(response -> ResponseEntity
.status(response.getStatusCode())
.headers(response.getHeaders()).body(response.getBody()));
public ResponseEntity<?> deleteWithBody(@PathVariable Integer id, @RequestBody Foo foo,
ProxyExchange<?> proxy) throws Exception {
return proxy.uri(home.toString() + "/foos/" + id).body(foo).delete(response -> ResponseEntity
.status(response.getStatusCode()).headers(response.getHeaders()).body(response.getBody()));
}
@GetMapping("/forward/**")
@@ -446,23 +392,20 @@ public class ProductionConfigurationTests {
}
@PostMapping("/forward/body/**")
public void postForwardBody(@RequestBody byte[] body, ProxyExchange<?> proxy)
throws Exception {
public void postForwardBody(@RequestBody byte[] body, ProxyExchange<?> proxy) throws Exception {
String path = proxy.path("/forward/body");
proxy.body(body).forward(path);
}
@PostMapping("/forward/forget/**")
public void postForwardForgetBody(@RequestBody byte[] body,
ProxyExchange<?> proxy) throws Exception {
public void postForwardForgetBody(@RequestBody byte[] body, ProxyExchange<?> proxy) throws Exception {
String path = proxy.path("/forward/forget");
proxy.forward(path);
}
@GetMapping("/proxy/headers")
@SuppressWarnings("Duplicates")
public ResponseEntity<Map<String, List<String>>> headers(
ProxyExchange<Map<String, List<String>>> proxy) {
public ResponseEntity<Map<String, List<String>>> headers(ProxyExchange<Map<String, List<String>>> proxy) {
proxy.sensitive("foo");
proxy.sensitive("hello");
proxy.header("bar", "hello");
@@ -472,8 +415,7 @@ public class ProductionConfigurationTests {
}
private <T> ResponseEntity<T> first(ResponseEntity<List<T>> response) {
return ResponseEntity.status(response.getStatusCode())
.headers(response.getHeaders())
return ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders())
.body(response.getBody().iterator().next());
}
@@ -504,18 +446,15 @@ public class ProductionConfigurationTests {
}
@DeleteMapping("/foos/{id}")
public ResponseEntity<?> deleteFoo(@PathVariable Integer id,
@RequestBody Foo foo) {
public ResponseEntity<?> deleteFoo(@PathVariable Integer id, @RequestBody Foo foo) {
return ResponseEntity.ok().body(Collections.singletonMap("deleted", foo));
}
@PostMapping("/bars")
public List<Bar> bars(@RequestBody List<Foo> foos,
@RequestHeader HttpHeaders headers) {
public List<Bar> bars(@RequestBody List<Foo> foos, @RequestHeader HttpHeaders headers) {
String custom = headers.getFirst("X-Custom");
custom = custom == null ? "" : custom;
custom = headers.getFirst("forwarded") == null ? custom
: headers.getFirst("forwarded") + ";" + custom;
custom = headers.getFirst("forwarded") == null ? custom : headers.getFirst("forwarded") + ";" + custom;
return Arrays.asList(new Bar(custom + foos.iterator().next().getName()));
}

View File

@@ -157,18 +157,16 @@ public class GatewaySampleApplication {
@Bean
public RouterFunction<ServerResponse> testFunRouterFunction() {
RouterFunction<ServerResponse> route = RouterFunctions.route(
RequestPredicates.path("/testfun"),
RouterFunction<ServerResponse> route = RouterFunctions.route(RequestPredicates.path("/testfun"),
request -> ServerResponse.ok().body(BodyInserters.fromValue("hello")));
return route;
}
@Bean
public RouterFunction<ServerResponse> testWhenMetricPathIsNotMeet() {
RouterFunction<ServerResponse> route = RouterFunctions.route(
RequestPredicates.path("/actuator/metrics/gateway.requests"),
request -> ServerResponse.ok().body(BodyInserters
.fromValue(HELLO_FROM_FAKE_ACTUATOR_METRICS_GATEWAY_REQUESTS)));
RouterFunction<ServerResponse> route = RouterFunctions
.route(RequestPredicates.path("/actuator/metrics/gateway.requests"), request -> ServerResponse.ok()
.body(BodyInserters.fromValue(HELLO_FROM_FAKE_ACTUATOR_METRICS_GATEWAY_REQUESTS)));
return route;
}

View File

@@ -84,8 +84,7 @@ public class ThrottleGatewayFilter implements GatewayFilter {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
TokenBucket tokenBucket = TokenBuckets.builder().withCapacity(capacity)
.withFixedIntervalRefillStrategy(refillTokens, refillPeriod, refillUnit)
.build();
.withFixedIntervalRefillStrategy(refillTokens, refillPeriod, refillUnit).build();
// TODO: get a token bucket for a key
log.debug("TokenBucket capacity: " + tokenBucket.getCapacity());

View File

@@ -49,8 +49,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Spencer Gibb
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { GatewaySampleApplicationTests.TestConfig.class },
webEnvironment = RANDOM_PORT, properties = "management.server.port=${test.port}")
@SpringBootTest(classes = { GatewaySampleApplicationTests.TestConfig.class }, webEnvironment = RANDOM_PORT,
properties = "management.server.port=${test.port}")
public class GatewaySampleApplicationTests {
protected static int managementPort;
@@ -77,8 +77,7 @@ public class GatewaySampleApplicationTests {
@Before
public void setup() {
baseUri = "http://localhost:" + port;
this.webClient = WebTestClient.bindToServer()
.responseTimeout(Duration.ofSeconds(10)).baseUrl(baseUri).build();
this.webClient = WebTestClient.bindToServer().responseTimeout(Duration.ofSeconds(10)).baseUrl(baseUri).build();
}
@Test
@@ -89,108 +88,88 @@ public class GatewaySampleApplicationTests {
@Test
@SuppressWarnings("unchecked")
public void readBodyPredicateStringWorks() {
webClient.post().uri("/post").header("Host", "www.readbody.org").bodyValue("hi")
.exchange().expectStatus().isOk().expectHeader()
.valueEquals("X-TestHeader", "read_body_pred").expectBody(Map.class)
.consumeWith(result -> assertThat(result.getResponseBody())
.containsEntry("data", "hi"));
webClient.post().uri("/post").header("Host", "www.readbody.org").bodyValue("hi").exchange().expectStatus()
.isOk().expectHeader().valueEquals("X-TestHeader", "read_body_pred").expectBody(Map.class)
.consumeWith(result -> assertThat(result.getResponseBody()).containsEntry("data", "hi"));
}
@Test
@SuppressWarnings("unchecked")
public void rewriteRequestBodyStringWorks() {
webClient.post().uri("/post").header("Host", "www.rewriterequestupper.org")
.bodyValue("hello").exchange().expectStatus().isOk().expectHeader()
.valueEquals("X-TestHeader", "rewrite_request_upper")
webClient.post().uri("/post").header("Host", "www.rewriterequestupper.org").bodyValue("hello").exchange()
.expectStatus().isOk().expectHeader().valueEquals("X-TestHeader", "rewrite_request_upper")
.expectBody(Map.class)
.consumeWith(result -> assertThat(result.getResponseBody())
.containsEntry("data", "HELLOHELLO"));
.consumeWith(result -> assertThat(result.getResponseBody()).containsEntry("data", "HELLOHELLO"));
}
@Test
@SuppressWarnings("unchecked")
public void rewriteRequestBodyObjectWorks() {
webClient.post().uri("/post").header("Host", "www.rewriterequestobj.org")
.bodyValue("hello").exchange().expectStatus().isOk().expectHeader()
.valueEquals("X-TestHeader", "rewrite_request").expectBody(Map.class)
.consumeWith(result -> assertThat(result.getResponseBody())
.containsEntry("data", "{\"message\":\"HELLO\"}"));
webClient.post().uri("/post").header("Host", "www.rewriterequestobj.org").bodyValue("hello").exchange()
.expectStatus().isOk().expectHeader().valueEquals("X-TestHeader", "rewrite_request")
.expectBody(Map.class).consumeWith(result -> assertThat(result.getResponseBody()).containsEntry("data",
"{\"message\":\"HELLO\"}"));
}
@Test
@SuppressWarnings("unchecked")
public void rewriteResponseBodyStringWorks() {
webClient.post().uri("/post").header("Host", "www.rewriteresponseupper.org")
.bodyValue("hello").exchange().expectStatus().isOk().expectHeader()
.valueEquals("X-TestHeader", "rewrite_response_upper")
webClient.post().uri("/post").header("Host", "www.rewriteresponseupper.org").bodyValue("hello").exchange()
.expectStatus().isOk().expectHeader().valueEquals("X-TestHeader", "rewrite_response_upper")
.expectBody(Map.class)
.consumeWith(result -> assertThat(result.getResponseBody())
.containsEntry("DATA", "HELLO"));
.consumeWith(result -> assertThat(result.getResponseBody()).containsEntry("DATA", "HELLO"));
}
@Test
@SuppressWarnings("unchecked")
public void rewriteResponseEmptyBodyToStringWorks() {
webClient.post().uri("/post/empty").header("Host", "www.rewriteemptyresponse.org")
.exchange().expectStatus().isOk().expectHeader()
.valueEquals("X-TestHeader", "rewrite_empty_response")
.expectBody(String.class)
.consumeWith(result -> assertThat(result.getResponseBody())
.isEqualTo("emptybody"));
webClient.post().uri("/post/empty").header("Host", "www.rewriteemptyresponse.org").exchange().expectStatus()
.isOk().expectHeader().valueEquals("X-TestHeader", "rewrite_empty_response").expectBody(String.class)
.consumeWith(result -> assertThat(result.getResponseBody()).isEqualTo("emptybody"));
}
@Test
@SuppressWarnings("unchecked")
public void emptyBodySupplierNotCalledWhenBodyPresent() {
webClient.post().uri("/post")
.header("Host", "www.rewriteresponsewithfailsupplier.org")
.bodyValue("hello").exchange().expectStatus().isOk().expectHeader()
.valueEquals("X-TestHeader", "rewrite_response_fail_supplier")
.expectBody(Map.class)
.consumeWith(result -> assertThat(result.getResponseBody())
.containsEntry("DATA", "HELLO"));
webClient.post().uri("/post").header("Host", "www.rewriteresponsewithfailsupplier.org").bodyValue("hello")
.exchange().expectStatus().isOk().expectHeader()
.valueEquals("X-TestHeader", "rewrite_response_fail_supplier").expectBody(Map.class)
.consumeWith(result -> assertThat(result.getResponseBody()).containsEntry("DATA", "HELLO"));
}
@Test
@SuppressWarnings("unchecked")
public void rewriteResponeBodyObjectWorks() {
webClient.post().uri("/post").header("Host", "www.rewriteresponseobj.org")
.bodyValue("hello").exchange().expectStatus().isOk().expectHeader()
.valueEquals("X-TestHeader", "rewrite_response_obj")
webClient.post().uri("/post").header("Host", "www.rewriteresponseobj.org").bodyValue("hello").exchange()
.expectStatus().isOk().expectHeader().valueEquals("X-TestHeader", "rewrite_response_obj")
.expectBody(String.class)
.consumeWith(result -> assertThat(result.getResponseBody())
.isEqualTo("hello"));
.consumeWith(result -> assertThat(result.getResponseBody()).isEqualTo("hello"));
}
@Test
public void complexPredicate() {
webClient.get().uri("/anything/png").header("Host", "www.abc.org").exchange()
.expectHeader().valueEquals("X-TestHeader", "foobar").expectStatus()
.isOk();
webClient.get().uri("/anything/png").header("Host", "www.abc.org").exchange().expectHeader()
.valueEquals("X-TestHeader", "foobar").expectStatus().isOk();
}
@Test
public void actuatorManagementPort() {
webClient.get()
.uri("http://localhost:" + managementPort + "/actuator/gateway/routes")
.exchange().expectStatus().isOk();
webClient.get().uri("http://localhost:" + managementPort + "/actuator/gateway/routes").exchange().expectStatus()
.isOk();
}
@Test
public void actuatorMetrics() {
contextLoads();
webClient.get()
.uri("http://localhost:" + managementPort
+ "/actuator/metrics/gateway.requests")
.exchange().expectStatus().isOk().expectBody().consumeWith(i -> {
webClient.get().uri("http://localhost:" + managementPort + "/actuator/metrics/gateway.requests").exchange()
.expectStatus().isOk().expectBody().consumeWith(i -> {
String body = new String(i.getResponseBodyContent());
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode actualObj = mapper.readTree(body);
JsonNode findValue = actualObj.findValue("name");
assertThat(findValue.asText())
.as("Expected to find metric with name gateway.requests")
assertThat(findValue.asText()).as("Expected to find metric with name gateway.requests")
.isEqualTo("gateway.requests");
}
catch (IOException e) {
@@ -218,10 +197,8 @@ public class GatewaySampleApplicationTests {
int port;
@Bean
public ServiceInstanceListSupplier fixedServiceInstanceListSupplier(
Environment env) {
return ServiceInstanceListSupplier.fixed(env)
.instance("localhost", port, "httpbin").build();
public ServiceInstanceListSupplier fixedServiceInstanceListSupplier(Environment env) {
return ServiceInstanceListSupplier.fixed(env).instance("localhost", port, "httpbin").build();
}
}

View File

@@ -35,8 +35,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.SocketUtils;
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "micrometer-*.jar", "spring-boot-actuator-*.jar",
"spring-boot-actuator-autoconfigure-*.jar" })
@ClassPathExclusions({ "micrometer-*.jar", "spring-boot-actuator-*.jar", "spring-boot-actuator-autoconfigure-*.jar" })
@DirtiesContext
public class GatewaySampleApplicationWithoutMetricsTests {
@@ -60,8 +59,7 @@ public class GatewaySampleApplicationWithoutMetricsTests {
@Before
public void setup() {
baseUri = "http://localhost:" + port;
this.webClient = WebTestClient.bindToServer()
.responseTimeout(Duration.ofSeconds(10)).baseUrl(baseUri).build();
this.webClient = WebTestClient.bindToServer().responseTimeout(Duration.ofSeconds(10)).baseUrl(baseUri).build();
}
protected ConfigurableApplicationContext init(Class<?> config) {
@@ -73,10 +71,9 @@ public class GatewaySampleApplicationWithoutMetricsTests {
public void actuatorMetrics() {
init(TestConfig.class);
webClient.get().uri("/get").exchange().expectStatus().isOk();
webClient.get()
.uri("http://localhost:" + port + "/actuator/metrics/gateway.requests")
.exchange().expectStatus().isOk().expectBody(String.class).isEqualTo(
GatewaySampleApplication.HELLO_FROM_FAKE_ACTUATOR_METRICS_GATEWAY_REQUESTS);
webClient.get().uri("http://localhost:" + port + "/actuator/metrics/gateway.requests").exchange().expectStatus()
.isOk().expectBody(String.class)
.isEqualTo(GatewaySampleApplication.HELLO_FROM_FAKE_ACTUATOR_METRICS_GATEWAY_REQUESTS);
}
}

View File

@@ -66,11 +66,10 @@ public class AbstractGatewayControllerEndpoint implements ApplicationEventPublis
protected ApplicationEventPublisher publisher;
public AbstractGatewayControllerEndpoint(
RouteDefinitionLocator routeDefinitionLocator,
public AbstractGatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator,
List<GlobalFilter> globalFilters, List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> routePredicates,
RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator) {
List<RoutePredicateFactory> routePredicates, RouteDefinitionWriter routeDefinitionWriter,
RouteLocator routeLocator) {
this.routeDefinitionLocator = routeDefinitionLocator;
this.globalFilters = globalFilters;
this.GatewayFilters = gatewayFilters;
@@ -128,32 +127,25 @@ public class AbstractGatewayControllerEndpoint implements ApplicationEventPublis
*/
@PostMapping("/routes/{id}")
@SuppressWarnings("unchecked")
public Mono<ResponseEntity<Object>> save(@PathVariable String id,
@RequestBody RouteDefinition route) {
public Mono<ResponseEntity<Object>> save(@PathVariable String id, @RequestBody RouteDefinition route) {
return Mono.just(route).filter(this::validateRouteDefinition)
.flatMap(routeDefinition -> this.routeDefinitionWriter
.save(Mono.just(routeDefinition).map(r -> {
r.setId(id);
log.debug("Saving route: " + route);
return r;
}))
.then(Mono.defer(() -> Mono.just(ResponseEntity
.created(URI.create("/routes/" + id)).build()))))
.switchIfEmpty(
Mono.defer(() -> Mono.just(ResponseEntity.badRequest().build())));
.flatMap(routeDefinition -> this.routeDefinitionWriter.save(Mono.just(routeDefinition).map(r -> {
r.setId(id);
log.debug("Saving route: " + route);
return r;
})).then(Mono.defer(() -> Mono.just(ResponseEntity.created(URI.create("/routes/" + id)).build()))))
.switchIfEmpty(Mono.defer(() -> Mono.just(ResponseEntity.badRequest().build())));
}
private boolean validateRouteDefinition(RouteDefinition routeDefinition) {
boolean hasValidFilterDefinitions = routeDefinition.getFilters().stream()
.allMatch(filterDefinition -> GatewayFilters.stream()
.anyMatch(gatewayFilterFactory -> filterDefinition.getName()
.equals(gatewayFilterFactory.name())));
.allMatch(filterDefinition -> GatewayFilters.stream().anyMatch(
gatewayFilterFactory -> filterDefinition.getName().equals(gatewayFilterFactory.name())));
boolean hasValidPredicateDefinitions = routeDefinition.getPredicates().stream()
.allMatch(predicateDefinition -> routePredicates.stream()
.anyMatch(routePredicate -> predicateDefinition.getName()
.equals(routePredicate.name())));
.anyMatch(routePredicate -> predicateDefinition.getName().equals(routePredicate.name())));
log.debug("FilterDefinitions valid: " + hasValidFilterDefinitions);
log.debug("PredicateDefinitions valid: " + hasValidPredicateDefinitions);
return hasValidFilterDefinitions && hasValidPredicateDefinitions;
@@ -163,15 +155,14 @@ public class AbstractGatewayControllerEndpoint implements ApplicationEventPublis
public Mono<ResponseEntity<Object>> delete(@PathVariable String id) {
return this.routeDefinitionWriter.delete(Mono.just(id))
.then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build())))
.onErrorResume(t -> t instanceof NotFoundException,
t -> Mono.just(ResponseEntity.notFound().build()));
.onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build()));
}
@GetMapping("/routes/{id}/combinedfilters")
public Mono<HashMap<String, Object>> combinedfilters(@PathVariable String id) {
// TODO: missing global filters
return this.routeLocator.getRoutes().filter(route -> route.getId().equals(id))
.reduce(new HashMap<>(), this::putItem);
return this.routeLocator.getRoutes().filter(route -> route.getId().equals(id)).reduce(new HashMap<>(),
this::putItem);
}
}

View File

@@ -45,13 +45,11 @@ import org.springframework.web.bind.annotation.PathVariable;
@RestControllerEndpoint(id = "gateway")
public class GatewayControllerEndpoint extends AbstractGatewayControllerEndpoint {
public GatewayControllerEndpoint(List<GlobalFilter> globalFilters,
List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> routePredicates,
RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator,
RouteDefinitionLocator routeDefinitionLocator) {
super(routeDefinitionLocator, globalFilters, gatewayFilters, routePredicates,
routeDefinitionWriter, routeLocator);
public GatewayControllerEndpoint(List<GlobalFilter> globalFilters, List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> routePredicates, RouteDefinitionWriter routeDefinitionWriter,
RouteLocator routeLocator, RouteDefinitionLocator routeDefinitionLocator) {
super(routeDefinitionLocator, globalFilters, gatewayFilters, routePredicates, routeDefinitionWriter,
routeLocator);
}
@GetMapping("/routedefinitions")

View File

@@ -46,16 +46,16 @@ public class GatewayLegacyControllerEndpoint extends AbstractGatewayControllerEn
public GatewayLegacyControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator,
List<GlobalFilter> globalFilters, List<GatewayFilterFactory> GatewayFilters,
List<RoutePredicateFactory> routePredicates,
RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator) {
super(routeDefinitionLocator, globalFilters, GatewayFilters, routePredicates,
routeDefinitionWriter, routeLocator);
List<RoutePredicateFactory> routePredicates, RouteDefinitionWriter routeDefinitionWriter,
RouteLocator routeLocator) {
super(routeDefinitionLocator, globalFilters, GatewayFilters, routePredicates, routeDefinitionWriter,
routeLocator);
}
@GetMapping("/routes")
public Mono<List<Map<String, Object>>> routes() {
Mono<Map<String, RouteDefinition>> routeDefs = this.routeDefinitionLocator
.getRouteDefinitions().collectMap(RouteDefinition::getId);
Mono<Map<String, RouteDefinition>> routeDefs = this.routeDefinitionLocator.getRouteDefinitions()
.collectMap(RouteDefinition::getId);
Mono<List<Route>> routes = this.routeLocator.getRoutes().collectList();
return Mono.zip(routeDefs, routes).map(tuple -> {
Map<String, RouteDefinition> defs = tuple.getT1();
@@ -102,10 +102,8 @@ public class GatewayLegacyControllerEndpoint extends AbstractGatewayControllerEn
@GetMapping("/routes/{id}")
public Mono<ResponseEntity<RouteDefinition>> route(@PathVariable String id) {
// TODO: missing RouteLocator
return this.routeDefinitionLocator.getRouteDefinitions()
.filter(route -> route.getId().equals(id)).singleOrEmpty()
.map(ResponseEntity::ok)
.switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
return this.routeDefinitionLocator.getRouteDefinitions().filter(route -> route.getId().equals(id))
.singleOrEmpty().map(ResponseEntity::ok).switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
}
}

View File

@@ -164,8 +164,7 @@ import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class,
WebFluxAutoConfiguration.class })
@AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class })
@AutoConfigureAfter({ GatewayReactiveLoadBalancerClientAutoConfiguration.class,
GatewayClassPathWarningAutoConfiguration.class })
@ConditionalOnClass(DispatcherHandler.class)
@@ -177,15 +176,13 @@ public class GatewayAutoConfiguration {
}
@Bean
public RouteLocatorBuilder routeLocatorBuilder(
ConfigurableApplicationContext context) {
public RouteLocatorBuilder routeLocatorBuilder(ConfigurableApplicationContext context) {
return new RouteLocatorBuilder(context);
}
@Bean
@ConditionalOnMissingBean
public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(
GatewayProperties properties) {
public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
return new PropertiesRouteDefinitionLocator(properties);
}
@@ -197,10 +194,8 @@ public class GatewayAutoConfiguration {
@Bean
@Primary
public RouteDefinitionLocator routeDefinitionLocator(
List<RouteDefinitionLocator> routeDefinitionLocators) {
return new CompositeRouteDefinitionLocator(
Flux.fromIterable(routeDefinitionLocators));
public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
}
@Bean
@@ -212,12 +207,10 @@ public class GatewayAutoConfiguration {
@Bean
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> predicates,
RouteDefinitionLocator routeDefinitionLocator,
ConfigurationService configurationService) {
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates,
gatewayFilters, properties, configurationService);
List<GatewayFilterFactory> gatewayFilters, List<RoutePredicateFactory> predicates,
RouteDefinitionLocator routeDefinitionLocator, ConfigurationService configurationService) {
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, gatewayFilters, properties,
configurationService);
}
@Bean
@@ -225,15 +218,12 @@ public class GatewayAutoConfiguration {
@ConditionalOnMissingBean(name = "cachedCompositeRouteLocator")
// TODO: property to disable composite?
public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
return new CachingRouteLocator(
new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}
@Bean
@ConditionalOnClass(
name = "org.springframework.cloud.client.discovery.event.HeartbeatMonitor")
public RouteRefreshListener routeRefreshListener(
ApplicationEventPublisher publisher) {
@ConditionalOnClass(name = "org.springframework.cloud.client.discovery.event.HeartbeatMonitor")
public RouteRefreshListener routeRefreshListener(ApplicationEventPublisher publisher) {
return new RouteRefreshListener(publisher);
}
@@ -248,11 +238,9 @@ public class GatewayAutoConfiguration {
}
@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(
FilteringWebHandler webHandler, RouteLocator routeLocator,
GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator,
globalCorsProperties, environment);
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
}
@Bean
@@ -268,8 +256,7 @@ public class GatewayAutoConfiguration {
}
@Bean
@ConditionalOnProperty(name = "spring.cloud.gateway.forwarded.enabled",
matchIfMissing = true)
@ConditionalOnProperty(name = "spring.cloud.gateway.forwarded.enabled", matchIfMissing = true)
public ForwardedHeadersFilter forwardedHeadersFilter() {
return new ForwardedHeadersFilter();
}
@@ -282,8 +269,7 @@ public class GatewayAutoConfiguration {
}
@Bean
@ConditionalOnProperty(name = "spring.cloud.gateway.x-forwarded.enabled",
matchIfMissing = true)
@ConditionalOnProperty(name = "spring.cloud.gateway.x-forwarded.enabled", matchIfMissing = true)
public XForwardedHeadersFilter xForwardedHeadersFilter() {
return new XForwardedHeadersFilter();
}
@@ -306,8 +292,7 @@ public class GatewayAutoConfiguration {
}
@Bean
public ForwardRoutingFilter forwardRoutingFilter(
ObjectProvider<DispatcherHandler> dispatcherHandler) {
public ForwardRoutingFilter forwardRoutingFilter(ObjectProvider<DispatcherHandler> dispatcherHandler) {
return new ForwardRoutingFilter(dispatcherHandler);
}
@@ -317,22 +302,18 @@ public class GatewayAutoConfiguration {
}
@Bean
public WebSocketService webSocketService(
RequestUpgradeStrategy requestUpgradeStrategy) {
public WebSocketService webSocketService(RequestUpgradeStrategy requestUpgradeStrategy) {
return new HandshakeWebSocketService(requestUpgradeStrategy);
}
@Bean
public WebsocketRoutingFilter websocketRoutingFilter(WebSocketClient webSocketClient,
WebSocketService webSocketService,
ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
return new WebsocketRoutingFilter(webSocketClient, webSocketService,
headersFilters);
WebSocketService webSocketService, ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
return new WebsocketRoutingFilter(webSocketClient, webSocketService, headersFilters);
}
@Bean
public WeightCalculatorWebFilter weightCalculatorWebFilter(
ConfigurationService configurationService,
public WeightCalculatorWebFilter weightCalculatorWebFilter(ConfigurationService configurationService,
ObjectProvider<RouteLocator> routeLocator) {
return new WeightCalculatorWebFilter(routeLocator, configurationService);
}
@@ -394,8 +375,7 @@ public class GatewayAutoConfiguration {
}
@Bean
public ReadBodyPredicateFactory readBodyPredicateFactory(
ServerCodecConfigurer codecConfigurer) {
public ReadBodyPredicateFactory readBodyPredicateFactory(ServerCodecConfigurer codecConfigurer) {
return new ReadBodyPredicateFactory(codecConfigurer.getReaders());
}
@@ -452,8 +432,7 @@ public class GatewayAutoConfiguration {
public ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory(
ServerCodecConfigurer codecConfigurer, Set<MessageBodyDecoder> bodyDecoders,
Set<MessageBodyEncoder> bodyEncoders) {
return new ModifyResponseBodyGatewayFilterFactory(codecConfigurer.getReaders(),
bodyDecoders, bodyEncoders);
return new ModifyResponseBodyGatewayFilterFactory(codecConfigurer.getReaders(), bodyDecoders, bodyEncoders);
}
@Bean
@@ -495,8 +474,8 @@ public class GatewayAutoConfiguration {
@Bean
@ConditionalOnBean({ RateLimiter.class, KeyResolver.class })
public RequestRateLimiterGatewayFilterFactory requestRateLimiterGatewayFilterFactory(
RateLimiter rateLimiter, KeyResolver resolver) {
public RequestRateLimiterGatewayFilterFactory requestRateLimiterGatewayFilterFactory(RateLimiter rateLimiter,
KeyResolver resolver) {
return new RequestRateLimiterGatewayFilterFactory(rateLimiter, resolver);
}
@@ -516,8 +495,7 @@ public class GatewayAutoConfiguration {
}
@Bean
public SecureHeadersGatewayFilterFactory secureHeadersGatewayFilterFactory(
SecureHeadersProperties properties) {
public SecureHeadersGatewayFilterFactory secureHeadersGatewayFilterFactory(SecureHeadersProperties properties) {
return new SecureHeadersGatewayFilterFactory(properties);
}
@@ -589,8 +567,8 @@ public class GatewayAutoConfiguration {
@Bean
@ConditionalOnProperty(name = "spring.cloud.gateway.httpserver.wiretap")
public NettyWebServerFactoryCustomizer nettyServerWiretapCustomizer(
Environment environment, ServerProperties serverProperties) {
public NettyWebServerFactoryCustomizer nettyServerWiretapCustomizer(Environment environment,
ServerProperties serverProperties) {
return new NettyWebServerFactoryCustomizer(environment, serverProperties) {
@Override
public void customize(NettyReactiveWebServerFactory factory) {
@@ -602,8 +580,7 @@ public class GatewayAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public HttpClient gatewayHttpClient(HttpClientProperties properties,
List<HttpClientCustomizer> customizers) {
public HttpClient gatewayHttpClient(HttpClientProperties properties, List<HttpClientCustomizer> customizers) {
// configure pool resources
HttpClientProperties.Pool pool = properties.getPool();
@@ -613,10 +590,9 @@ public class GatewayAutoConfiguration {
connectionProvider = ConnectionProvider.newConnection();
}
else if (pool.getType() == FIXED) {
ConnectionProvider.Builder builder = ConnectionProvider
.builder(pool.getName()).maxConnections(pool.getMaxConnections())
.pendingAcquireMaxCount(-1).pendingAcquireTimeout(
Duration.ofMillis(pool.getAcquireTimeout()));
ConnectionProvider.Builder builder = ConnectionProvider.builder(pool.getName())
.maxConnections(pool.getMaxConnections()).pendingAcquireMaxCount(-1)
.pendingAcquireTimeout(Duration.ofMillis(pool.getAcquireTimeout()));
if (pool.getMaxIdleTime() != null) {
builder.maxIdleTime(pool.getMaxIdleTime());
}
@@ -626,9 +602,8 @@ public class GatewayAutoConfiguration {
connectionProvider = builder.build();
}
else {
ConnectionProvider.Builder builder = ConnectionProvider
.builder(pool.getName()).maxConnections(Integer.MAX_VALUE)
.pendingAcquireTimeout(Duration.ofMillis(0))
ConnectionProvider.Builder builder = ConnectionProvider.builder(pool.getName())
.maxConnections(Integer.MAX_VALUE).pendingAcquireTimeout(Duration.ofMillis(0))
.pendingAcquireMaxCount(-1);
if (pool.getMaxIdleTime() != null) {
builder.maxIdleTime(pool.getMaxIdleTime());
@@ -644,20 +619,17 @@ public class GatewayAutoConfiguration {
.httpResponseDecoder(spec -> {
if (properties.getMaxHeaderSize() != null) {
// cast to int is ok, since @Max is Integer.MAX_VALUE
spec.maxHeaderSize(
(int) properties.getMaxHeaderSize().toBytes());
spec.maxHeaderSize((int) properties.getMaxHeaderSize().toBytes());
}
if (properties.getMaxInitialLineLength() != null) {
// cast to int is ok, since @Max is Integer.MAX_VALUE
spec.maxInitialLineLength(
(int) properties.getMaxInitialLineLength().toBytes());
spec.maxInitialLineLength((int) properties.getMaxInitialLineLength().toBytes());
}
return spec;
}).tcpConfiguration(tcpClient -> {
if (properties.getConnectTimeout() != null) {
tcpClient = tcpClient.option(
ChannelOption.CONNECT_TIMEOUT_MILLIS,
tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,
properties.getConnectTimeout());
}
@@ -667,19 +639,16 @@ public class GatewayAutoConfiguration {
if (StringUtils.hasText(proxy.getHost())) {
tcpClient = tcpClient.proxy(proxySpec -> {
ProxyProvider.Builder builder = proxySpec
.type(ProxyProvider.Proxy.HTTP)
ProxyProvider.Builder builder = proxySpec.type(ProxyProvider.Proxy.HTTP)
.host(proxy.getHost());
PropertyMapper map = PropertyMapper.get();
map.from(proxy::getPort).whenNonNull().to(builder::port);
map.from(proxy::getUsername).whenHasText()
.to(builder::username);
map.from(proxy::getUsername).whenHasText().to(builder::username);
map.from(proxy::getPassword).whenHasText()
.to(password -> builder.password(s -> password));
map.from(proxy::getNonProxyHostsPattern).whenHasText()
.to(builder::nonProxyHosts);
map.from(proxy::getNonProxyHostsPattern).whenHasText().to(builder::nonProxyHosts);
});
}
return tcpClient;
@@ -687,33 +656,27 @@ public class GatewayAutoConfiguration {
HttpClientProperties.Ssl ssl = properties.getSsl();
if ((ssl.getKeyStore() != null && ssl.getKeyStore().length() > 0)
|| ssl.getTrustedX509CertificatesForTrustManager().length > 0
|| ssl.isUseInsecureTrustManager()) {
|| ssl.getTrustedX509CertificatesForTrustManager().length > 0 || ssl.isUseInsecureTrustManager()) {
httpClient = httpClient.secure(sslContextSpec -> {
// configure ssl
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
X509Certificate[] trustedX509Certificates = ssl
.getTrustedX509CertificatesForTrustManager();
X509Certificate[] trustedX509Certificates = ssl.getTrustedX509CertificatesForTrustManager();
if (trustedX509Certificates.length > 0) {
sslContextBuilder = sslContextBuilder
.trustManager(trustedX509Certificates);
sslContextBuilder = sslContextBuilder.trustManager(trustedX509Certificates);
}
else if (ssl.isUseInsecureTrustManager()) {
sslContextBuilder = sslContextBuilder
.trustManager(InsecureTrustManagerFactory.INSTANCE);
sslContextBuilder = sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
}
try {
sslContextBuilder = sslContextBuilder
.keyManager(ssl.getKeyManagerFactory());
sslContextBuilder = sslContextBuilder.keyManager(ssl.getKeyManagerFactory());
}
catch (Exception e) {
logger.error(e);
}
sslContextSpec.sslContext(sslContextBuilder)
.defaultConfiguration(ssl.getDefaultConfigurationType())
sslContextSpec.sslContext(sslContextBuilder).defaultConfiguration(ssl.getDefaultConfigurationType())
.handshakeTimeout(ssl.getHandshakeTimeout())
.closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout())
.closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout());
@@ -741,25 +704,21 @@ public class GatewayAutoConfiguration {
@Bean
public NettyRoutingFilter routingFilter(HttpClient httpClient,
ObjectProvider<List<HttpHeadersFilter>> headersFilters,
HttpClientProperties properties) {
ObjectProvider<List<HttpHeadersFilter>> headersFilters, HttpClientProperties properties) {
return new NettyRoutingFilter(httpClient, headersFilters, properties);
}
@Bean
public NettyWriteResponseFilter nettyWriteResponseFilter(
GatewayProperties properties) {
public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
}
@Bean
public ReactorNettyWebSocketClient reactorNettyWebSocketClient(
HttpClientProperties properties, HttpClient httpClient) {
ReactorNettyWebSocketClient webSocketClient = new ReactorNettyWebSocketClient(
httpClient);
public ReactorNettyWebSocketClient reactorNettyWebSocketClient(HttpClientProperties properties,
HttpClient httpClient) {
ReactorNettyWebSocketClient webSocketClient = new ReactorNettyWebSocketClient(httpClient);
if (properties.getWebsocket().getMaxFramePayloadLength() != null) {
webSocketClient.setMaxFramePayloadLength(
properties.getWebsocket().getMaxFramePayloadLength());
webSocketClient.setMaxFramePayloadLength(properties.getWebsocket().getMaxFramePayloadLength());
}
webSocketClient.setHandlePing(properties.getWebsocket().isProxyPing());
return webSocketClient;
@@ -770,8 +729,7 @@ public class GatewayAutoConfiguration {
HttpClientProperties httpClientProperties) {
ReactorNettyRequestUpgradeStrategy requestUpgradeStrategy = new ReactorNettyRequestUpgradeStrategy();
HttpClientProperties.Websocket websocket = httpClientProperties
.getWebsocket();
HttpClientProperties.Websocket websocket = httpClientProperties.getWebsocket();
PropertyMapper map = PropertyMapper.get();
map.from(websocket::getMaxFramePayloadLength).whenNonNull()
.to(requestUpgradeStrategy::setMaxFramePayloadLength);
@@ -786,32 +744,25 @@ public class GatewayAutoConfiguration {
protected static class GatewayActuatorConfiguration {
@Bean
@ConditionalOnProperty(name = "spring.cloud.gateway.actuator.verbose.enabled",
matchIfMissing = true)
@ConditionalOnProperty(name = "spring.cloud.gateway.actuator.verbose.enabled", matchIfMissing = true)
@ConditionalOnAvailableEndpoint
public GatewayControllerEndpoint gatewayControllerEndpoint(
List<GlobalFilter> globalFilters,
List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> routePredicates,
public GatewayControllerEndpoint gatewayControllerEndpoint(List<GlobalFilter> globalFilters,
List<GatewayFilterFactory> gatewayFilters, List<RoutePredicateFactory> routePredicates,
RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator,
RouteDefinitionLocator routeDefinitionLocator) {
return new GatewayControllerEndpoint(globalFilters, gatewayFilters,
routePredicates, routeDefinitionWriter, routeLocator,
routeDefinitionLocator);
return new GatewayControllerEndpoint(globalFilters, gatewayFilters, routePredicates, routeDefinitionWriter,
routeLocator, routeDefinitionLocator);
}
@Bean
@Conditional(OnVerboseDisabledCondition.class)
@ConditionalOnAvailableEndpoint
public GatewayLegacyControllerEndpoint gatewayLegacyControllerEndpoint(
RouteDefinitionLocator routeDefinitionLocator,
List<GlobalFilter> globalFilters,
List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> routePredicates,
RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,
List<GatewayFilterFactory> gatewayFilters, List<RoutePredicateFactory> routePredicates,
RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator) {
return new GatewayLegacyControllerEndpoint(routeDefinitionLocator,
globalFilters, gatewayFilters, routePredicates, routeDefinitionWriter,
routeLocator);
return new GatewayLegacyControllerEndpoint(routeDefinitionLocator, globalFilters, gatewayFilters,
routePredicates, routeDefinitionWriter, routeLocator);
}
}
@@ -822,8 +773,7 @@ public class GatewayAutoConfiguration {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnProperty(name = "spring.cloud.gateway.actuator.verbose.enabled",
matchIfMissing = true)
@ConditionalOnProperty(name = "spring.cloud.gateway.actuator.verbose.enabled", matchIfMissing = true)
static class VerboseDisabled {
}

View File

@@ -28,8 +28,7 @@ import org.springframework.context.annotation.Configuration;
@AutoConfigureBefore(GatewayAutoConfiguration.class)
public class GatewayClassPathWarningAutoConfiguration {
private static final Log log = LogFactory
.getLog(GatewayClassPathWarningAutoConfiguration.class);
private static final Log log = LogFactory.getLog(GatewayClassPathWarningAutoConfiguration.class);
private static final String BORDER = "\n\n**********************************************************\n\n";

View File

@@ -26,11 +26,9 @@ import org.springframework.core.env.MapPropertySource;
public class GatewayEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment env,
SpringApplication application) {
env.getPropertySources().addFirst(
new MapPropertySource("gateway-properties", Collections.singletonMap(
"spring.webflux.hiddenmethod.filter.enabled", "false")));
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication application) {
env.getPropertySources().addFirst(new MapPropertySource("gateway-properties",
Collections.singletonMap("spring.webflux.hiddenmethod.filter.enabled", "false")));
}
}

View File

@@ -42,10 +42,8 @@ import org.springframework.web.reactive.DispatcherHandler;
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@EnableConfigurationProperties(GatewayMetricsProperties.class)
@AutoConfigureBefore(HttpHandlerAutoConfiguration.class)
@AutoConfigureAfter({ MetricsAutoConfiguration.class,
MeterRegistryAutoConfiguration.class })
@ConditionalOnClass({ DispatcherHandler.class, MeterRegistry.class,
MetricsAutoConfiguration.class })
@AutoConfigureAfter({ MetricsAutoConfiguration.class, MeterRegistryAutoConfiguration.class })
@ConditionalOnClass({ DispatcherHandler.class, MeterRegistry.class, MetricsAutoConfiguration.class })
public class GatewayMetricsAutoConfiguration {
@Bean
@@ -59,15 +57,13 @@ public class GatewayMetricsAutoConfiguration {
}
@Bean
public PropertiesTagsProvider propertiesTagsProvider(
GatewayMetricsProperties gatewayMetricsProperties) {
public PropertiesTagsProvider propertiesTagsProvider(GatewayMetricsProperties gatewayMetricsProperties) {
return new PropertiesTagsProvider(gatewayMetricsProperties.getTags());
}
@Bean
@ConditionalOnBean(MeterRegistry.class)
@ConditionalOnProperty(name = "spring.cloud.gateway.metrics.enabled",
matchIfMissing = true)
@ConditionalOnProperty(name = "spring.cloud.gateway.metrics.enabled", matchIfMissing = true)
public GatewayMetricsFilter gatewayMetricFilter(MeterRegistry meterRegistry,
List<GatewayTagsProvider> tagsProviders) {
return new GatewayMetricsFilter(meterRegistry, tagsProviders);

View File

@@ -50,8 +50,7 @@ public class GatewayNoLoadBalancerClientAutoConfiguration {
@Bean
@ConditionalOnMissingBean(ReactiveLoadBalancerClientFilter.class)
public NoLoadBalancerClientFilter noLoadBalancerClientFilter(
LoadBalancerProperties properties) {
public NoLoadBalancerClientFilter noLoadBalancerClientFilter(LoadBalancerProperties properties) {
return new NoLoadBalancerClientFilter(properties.isUse404());
}
@@ -73,13 +72,11 @@ public class GatewayNoLoadBalancerClientAutoConfiguration {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
if (url == null
|| (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
return chain.filter(exchange);
}
throw NotFoundException.create(use404,
"Unable to find instance for " + url.getHost());
throw NotFoundException.create(use404, "Unable to find instance for " + url.getHost());
}
}

View File

@@ -54,8 +54,8 @@ public class GatewayProperties {
*/
private List<FilterDefinition> defaultFilters = new ArrayList<>();
private List<MediaType> streamingMediaTypes = Arrays
.asList(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_STREAM_JSON);
private List<MediaType> streamingMediaTypes = Arrays.asList(MediaType.TEXT_EVENT_STREAM,
MediaType.APPLICATION_STREAM_JSON);
/**
* Option to fail on route definition errors, defaults to true. Otherwise, a warning
@@ -100,11 +100,9 @@ public class GatewayProperties {
@Override
public String toString() {
return new ToStringCreator(this).append("routes", routes)
.append("defaultFilters", defaultFilters)
return new ToStringCreator(this).append("routes", routes).append("defaultFilters", defaultFilters)
.append("streamingMediaTypes", streamingMediaTypes)
.append("failOnRouteDefinitionError", failOnRouteDefinitionError)
.toString();
.append("failOnRouteDefinitionError", failOnRouteDefinitionError).toString();
}

View File

@@ -36,8 +36,7 @@ import org.springframework.web.reactive.DispatcherHandler;
* @author Olga Maciaszek-Sharma
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ ReactiveLoadBalancer.class, LoadBalancerAutoConfiguration.class,
DispatcherHandler.class })
@ConditionalOnClass({ ReactiveLoadBalancer.class, LoadBalancerAutoConfiguration.class, DispatcherHandler.class })
@AutoConfigureAfter(LoadBalancerAutoConfiguration.class)
@EnableConfigurationProperties(LoadBalancerProperties.class)
public class GatewayReactiveLoadBalancerClientAutoConfiguration {
@@ -45,8 +44,8 @@ public class GatewayReactiveLoadBalancerClientAutoConfiguration {
@Bean
@ConditionalOnBean(LoadBalancerClientFactory.class)
@ConditionalOnMissingBean(ReactiveLoadBalancerClientFilter.class)
public ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter(
LoadBalancerClientFactory clientFactory, LoadBalancerProperties properties) {
public ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory,
LoadBalancerProperties properties) {
return new ReactiveLoadBalancerClientFilter(clientFactory, properties);
}

View File

@@ -49,8 +49,8 @@ class GatewayRedisAutoConfiguration {
@SuppressWarnings("unchecked")
public RedisScript redisRequestRateLimiterScript() {
DefaultRedisScript redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(new ResourceScriptSource(
new ClassPathResource("META-INF/scripts/request_rate_limiter.lua")));
redisScript.setScriptSource(
new ResourceScriptSource(new ClassPathResource("META-INF/scripts/request_rate_limiter.lua")));
redisScript.setResultType(List.class);
return redisScript;
}

View File

@@ -37,9 +37,8 @@ import org.springframework.web.reactive.DispatcherHandler;
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@AutoConfigureAfter({ ReactiveResilience4JAutoConfiguration.class })
@ConditionalOnClass({ DispatcherHandler.class,
ReactiveResilience4JAutoConfiguration.class, ReactiveCircuitBreakerFactory.class,
ReactiveResilience4JCircuitBreakerFactory.class })
@ConditionalOnClass({ DispatcherHandler.class, ReactiveResilience4JAutoConfiguration.class,
ReactiveCircuitBreakerFactory.class, ReactiveResilience4JCircuitBreakerFactory.class })
public class GatewayResilience4JCircuitBreakerAutoConfiguration {
@Bean
@@ -47,8 +46,7 @@ public class GatewayResilience4JCircuitBreakerAutoConfiguration {
public SpringCloudCircuitBreakerResilience4JFilterFactory springCloudCircuitBreakerResilience4JFilterFactory(
ReactiveResilience4JCircuitBreakerFactory reactiveCircuitBreakerFactory,
ObjectProvider<DispatcherHandler> dispatcherHandler) {
return new SpringCloudCircuitBreakerResilience4JFilterFactory(
reactiveCircuitBreakerFactory, dispatcherHandler);
return new SpringCloudCircuitBreakerResilience4JFilterFactory(reactiveCircuitBreakerFactory, dispatcherHandler);
}
@Bean

View File

@@ -248,9 +248,8 @@ public class HttpClientProperties {
@Override
public String toString() {
return "Pool{" + "type=" + type + ", name='" + name + '\''
+ ", maxConnections=" + maxConnections + ", acquireTimeout="
+ acquireTimeout + ", maxIdleTime=" + maxIdleTime + ", maxLifeTime="
return "Pool{" + "type=" + type + ", name='" + name + '\'' + ", maxConnections=" + maxConnections
+ ", acquireTimeout=" + acquireTimeout + ", maxIdleTime=" + maxIdleTime + ", maxLifeTime="
+ maxLifeTime + '}';
}
@@ -337,9 +336,8 @@ public class HttpClientProperties {
@Override
public String toString() {
return "Proxy{" + "host='" + host + '\'' + ", port=" + port + ", username='"
+ username + '\'' + ", password='" + password + '\''
+ ", nonProxyHostsPattern='" + nonProxyHostsPattern + '\'' + '}';
return "Proxy{" + "host='" + host + '\'' + ", port=" + port + ", username='" + username + '\''
+ ", password='" + password + '\'' + ", nonProxyHostsPattern='" + nonProxyHostsPattern + '\'' + '}';
}
}
@@ -433,8 +431,7 @@ public class HttpClientProperties {
public X509Certificate[] getTrustedX509CertificatesForTrustManager() {
try {
CertificateFactory certificateFactory = CertificateFactory
.getInstance("X.509");
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
ArrayList<Certificate> allCerts = new ArrayList<>();
for (String trustedCert : getTrustedX509Certificates()) {
try {
@@ -444,15 +441,13 @@ public class HttpClientProperties {
allCerts.addAll(certs);
}
catch (IOException e) {
throw new WebServerException(
"Could not load certificate '" + trustedCert + "'", e);
throw new WebServerException("Could not load certificate '" + trustedCert + "'", e);
}
}
return allCerts.toArray(new X509Certificate[allCerts.size()]);
}
catch (CertificateException e1) {
throw new WebServerException("Could not load CertificateFactory X.509",
e1);
throw new WebServerException("Could not load CertificateFactory X.509", e1);
}
}
@@ -461,8 +456,7 @@ public class HttpClientProperties {
if (getKeyStore() != null && getKeyStore().length() > 0) {
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
char[] keyPassword = getKeyPassword() != null
? getKeyPassword().toCharArray() : null;
char[] keyPassword = getKeyPassword() != null ? getKeyPassword().toCharArray() : null;
if (keyPassword == null && getKeyStorePassword() != null) {
keyPassword = getKeyStorePassword().toCharArray();
@@ -487,19 +481,17 @@ public class HttpClientProperties {
: KeyStore.getInstance(getKeyStoreType());
try {
URL url = ResourceUtils.getURL(getKeyStore());
store.load(url.openStream(), getKeyStorePassword() != null
? getKeyStorePassword().toCharArray() : null);
store.load(url.openStream(),
getKeyStorePassword() != null ? getKeyStorePassword().toCharArray() : null);
}
catch (Exception e) {
throw new WebServerException(
"Could not load key store ' " + getKeyStore() + "'", e);
throw new WebServerException("Could not load key store ' " + getKeyStore() + "'", e);
}
return store;
}
catch (KeyStoreException | NoSuchProviderException e) {
throw new WebServerException(
"Could not load KeyStore for given type and provider", e);
throw new WebServerException("Could not load KeyStore for given type and provider", e);
}
}
@@ -541,21 +533,18 @@ public class HttpClientProperties {
return defaultConfigurationType;
}
public void setDefaultConfigurationType(
SslProvider.DefaultConfigurationType defaultConfigurationType) {
public void setDefaultConfigurationType(SslProvider.DefaultConfigurationType defaultConfigurationType) {
this.defaultConfigurationType = defaultConfigurationType;
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("useInsecureTrustManager", useInsecureTrustManager)
return new ToStringCreator(this).append("useInsecureTrustManager", useInsecureTrustManager)
.append("trustedX509Certificates", trustedX509Certificates)
.append("handshakeTimeout", handshakeTimeout)
.append("closeNotifyFlushTimeout", closeNotifyFlushTimeout)
.append("closeNotifyReadTimeout", closeNotifyReadTimeout)
.append("defaultConfigurationType", defaultConfigurationType)
.toString();
.append("defaultConfigurationType", defaultConfigurationType).toString();
}
}
@@ -586,8 +575,7 @@ public class HttpClientProperties {
@Override
public String toString() {
return new ToStringCreator(this)
.append("maxFramePayloadLength", maxFramePayloadLength)
return new ToStringCreator(this).append("maxFramePayloadLength", maxFramePayloadLength)
.append("proxyPing", proxyPing).toString();
}

View File

@@ -32,8 +32,7 @@ import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(SimpleUrlHandlerMapping.class)
@ConditionalOnProperty(
name = "spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping",
@ConditionalOnProperty(name = "spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping",
matchIfMissing = false)
public class SimpleUrlHandlerMappingGlobalCorsAutoConfiguration {
@@ -45,8 +44,7 @@ public class SimpleUrlHandlerMappingGlobalCorsAutoConfiguration {
@PostConstruct
void config() {
simpleUrlHandlerMapping
.setCorsConfigurations(globalCorsProperties.getCorsConfigurations());
simpleUrlHandlerMapping.setCorsConfigurations(globalCorsProperties.getCorsConfigurations());
}
}

View File

@@ -47,8 +47,7 @@ import org.springframework.util.StringUtils;
*/
public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLocator {
private static final Log log = LogFactory
.getLog(DiscoveryClientRouteDefinitionLocator.class);
private static final Log log = LogFactory.getLog(DiscoveryClientRouteDefinitionLocator.class);
private final DiscoveryLocatorProperties properties;
@@ -65,8 +64,7 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
.flatMap(service -> discoveryClient.getInstances(service).collectList());
}
private DiscoveryClientRouteDefinitionLocator(String discoveryClientName,
DiscoveryLocatorProperties properties) {
private DiscoveryClientRouteDefinitionLocator(String discoveryClientName, DiscoveryLocatorProperties properties) {
this.properties = properties;
if (StringUtils.hasText(properties.getRouteIdPrefix())) {
routeIdPrefix = properties.getRouteIdPrefix();
@@ -74,21 +72,18 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
else {
routeIdPrefix = discoveryClientName + "_";
}
evalCtxt = SimpleEvaluationContext.forReadOnlyDataBinding().withInstanceMethods()
.build();
evalCtxt = SimpleEvaluationContext.forReadOnlyDataBinding().withInstanceMethods().build();
}
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
SpelExpressionParser parser = new SpelExpressionParser();
Expression includeExpr = parser
.parseExpression(properties.getIncludeExpression());
Expression includeExpr = parser.parseExpression(properties.getIncludeExpression());
Expression urlExpr = parser.parseExpression(properties.getUrlExpression());
Predicate<ServiceInstance> includePredicate;
if (properties.getIncludeExpression() == null
|| "true".equalsIgnoreCase(properties.getIncludeExpression())) {
if (properties.getIncludeExpression() == null || "true".equalsIgnoreCase(properties.getIncludeExpression())) {
includePredicate = instance -> true;
}
else {
@@ -101,22 +96,17 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
};
}
return serviceInstances.filter(instances -> !instances.isEmpty())
.map(instances -> instances.get(0)).filter(includePredicate)
.map(instance -> {
RouteDefinition routeDefinition = buildRouteDefinition(urlExpr,
instance);
return serviceInstances.filter(instances -> !instances.isEmpty()).map(instances -> instances.get(0))
.filter(includePredicate).map(instance -> {
RouteDefinition routeDefinition = buildRouteDefinition(urlExpr, instance);
final ServiceInstance instanceForEval = new DelegatingServiceInstance(
instance, properties);
final ServiceInstance instanceForEval = new DelegatingServiceInstance(instance, properties);
for (PredicateDefinition original : this.properties.getPredicates()) {
PredicateDefinition predicate = new PredicateDefinition();
predicate.setName(original.getName());
for (Map.Entry<String, String> entry : original.getArgs()
.entrySet()) {
String value = getValueFromExpr(evalCtxt, parser,
instanceForEval, entry);
for (Map.Entry<String, String> entry : original.getArgs().entrySet()) {
String value = getValueFromExpr(evalCtxt, parser, instanceForEval, entry);
predicate.addArg(entry.getKey(), value);
}
routeDefinition.getPredicates().add(predicate);
@@ -125,10 +115,8 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
for (FilterDefinition original : this.properties.getFilters()) {
FilterDefinition filter = new FilterDefinition();
filter.setName(original.getName());
for (Map.Entry<String, String> entry : original.getArgs()
.entrySet()) {
String value = getValueFromExpr(evalCtxt, parser,
instanceForEval, entry);
for (Map.Entry<String, String> entry : original.getArgs().entrySet()) {
String value = getValueFromExpr(evalCtxt, parser, instanceForEval, entry);
filter.addArg(entry.getKey(), value);
}
routeDefinition.getFilters().add(filter);
@@ -138,8 +126,7 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
});
}
protected RouteDefinition buildRouteDefinition(Expression urlExpr,
ServiceInstance serviceInstance) {
protected RouteDefinition buildRouteDefinition(Expression urlExpr, ServiceInstance serviceInstance) {
String serviceId = serviceInstance.getServiceId();
RouteDefinition routeDefinition = new RouteDefinition();
routeDefinition.setId(this.routeIdPrefix + serviceId);
@@ -150,8 +137,8 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
return routeDefinition;
}
String getValueFromExpr(SimpleEvaluationContext evalCtxt, SpelExpressionParser parser,
ServiceInstance instance, Map.Entry<String, String> entry) {
String getValueFromExpr(SimpleEvaluationContext evalCtxt, SpelExpressionParser parser, ServiceInstance instance,
Map.Entry<String, String> entry) {
try {
Expression valueExpr = parser.parseExpression(entry.getValue());
return valueExpr.getValue(evalCtxt, instance, String.class);
@@ -170,8 +157,7 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
private final DiscoveryLocatorProperties properties;
private DelegatingServiceInstance(ServiceInstance delegate,
DiscoveryLocatorProperties properties) {
private DelegatingServiceInstance(ServiceInstance delegate, DiscoveryLocatorProperties properties) {
this.delegate = delegate;
this.properties = properties;
}
@@ -216,8 +202,7 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
@Override
public String toString() {
return new ToStringCreator(this).append("delegate", delegate)
.append("properties", properties).toString();
return new ToStringCreator(this).append("delegate", delegate).append("properties", properties).toString();
}
}

View File

@@ -116,12 +116,10 @@ public class DiscoveryLocatorProperties {
@Override
public String toString() {
return new ToStringCreator(this).append("enabled", enabled)
.append("routeIdPrefix", routeIdPrefix)
.append("includeExpression", includeExpression)
.append("urlExpression", urlExpression)
.append("lowerCaseServiceId", lowerCaseServiceId)
.append("predicates", predicates).append("filters", filters).toString();
return new ToStringCreator(this).append("enabled", enabled).append("routeIdPrefix", routeIdPrefix)
.append("includeExpression", includeExpression).append("urlExpression", urlExpression)
.append("lowerCaseServiceId", lowerCaseServiceId).append("predicates", predicates)
.append("filters", filters).toString();
}
}

View File

@@ -48,8 +48,7 @@ import static org.springframework.cloud.gateway.support.NameUtils.normalizeRoute
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@AutoConfigureBefore(GatewayAutoConfiguration.class)
@AutoConfigureAfter(CompositeDiscoveryClientAutoConfiguration.class)
@ConditionalOnClass({ DispatcherHandler.class,
CompositeDiscoveryClientAutoConfiguration.class })
@ConditionalOnClass({ DispatcherHandler.class, CompositeDiscoveryClientAutoConfiguration.class })
@EnableConfigurationProperties
public class GatewayDiscoveryClientAutoConfiguration {
@@ -89,15 +88,13 @@ public class GatewayDiscoveryClientAutoConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.cloud.discovery.reactive.enabled",
matchIfMissing = true)
@ConditionalOnProperty(value = "spring.cloud.discovery.reactive.enabled", matchIfMissing = true)
public static class ReactiveDiscoveryClientRouteDefinitionLocatorConfiguration {
@Bean
@ConditionalOnProperty(name = "spring.cloud.gateway.discovery.locator.enabled")
public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(
ReactiveDiscoveryClient discoveryClient,
DiscoveryLocatorProperties properties) {
ReactiveDiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
}

View File

@@ -34,8 +34,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.C
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CACHED_SERVER_HTTP_REQUEST_DECORATOR_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
public class AdaptCachedBodyGlobalFilter
implements GlobalFilter, Ordered, ApplicationListener<EnableBodyCachingEvent> {
public class AdaptCachedBodyGlobalFilter implements GlobalFilter, Ordered, ApplicationListener<EnableBodyCachingEvent> {
private ConcurrentMap<String, Boolean> routesToCache = new ConcurrentHashMap<>();
@@ -49,8 +48,8 @@ public class AdaptCachedBodyGlobalFilter
// the cached ServerHttpRequest is used when the ServerWebExchange can not be
// mutated, for example, during a predicate where the body is read, but still
// needs to be cached.
ServerHttpRequest cachedRequest = exchange
.getAttributeOrDefault(CACHED_SERVER_HTTP_REQUEST_DECORATOR_ATTR, null);
ServerHttpRequest cachedRequest = exchange.getAttributeOrDefault(CACHED_SERVER_HTTP_REQUEST_DECORATOR_ATTR,
null);
if (cachedRequest != null) {
exchange.getAttributes().remove(CACHED_SERVER_HTTP_REQUEST_DECORATOR_ATTR);
return chain.filter(exchange.mutate().request(cachedRequest).build());

View File

@@ -43,9 +43,7 @@ public class ForwardPathFilter implements GlobalFilter, Ordered {
if (isAlreadyRouted(exchange) || !"forward".equals(scheme)) {
return chain.filter(exchange);
}
exchange = exchange.mutate()
.request(exchange.getRequest().mutate().path(routeUri.getPath()).build())
.build();
exchange = exchange.mutate().request(exchange.getRequest().mutate().path(routeUri.getPath()).build()).build();
return chain.filter(exchange);
}

View File

@@ -39,8 +39,7 @@ public class ForwardRoutingFilter implements GlobalFilter, Ordered {
// do not use this dispatcherHandler directly, use getDispatcherHandler() instead.
private volatile DispatcherHandler dispatcherHandler;
public ForwardRoutingFilter(
ObjectProvider<DispatcherHandler> dispatcherHandlerProvider) {
public ForwardRoutingFilter(ObjectProvider<DispatcherHandler> dispatcherHandlerProvider) {
this.dispatcherHandlerProvider = dispatcherHandlerProvider;
}

View File

@@ -43,11 +43,9 @@ public class GatewayMetricsFilter implements GlobalFilter, Ordered {
private GatewayTagsProvider compositeTagsProvider;
public GatewayMetricsFilter(MeterRegistry meterRegistry,
List<GatewayTagsProvider> tagsProviders) {
public GatewayMetricsFilter(MeterRegistry meterRegistry, List<GatewayTagsProvider> tagsProviders) {
this.meterRegistry = meterRegistry;
this.compositeTagsProvider = tagsProviders.stream()
.reduce(exchange -> Tags.empty(), GatewayTagsProvider::and);
this.compositeTagsProvider = tagsProviders.stream().reduce(exchange -> Tags.empty(), GatewayTagsProvider::and);
}
@Override
@@ -61,8 +59,7 @@ public class GatewayMetricsFilter implements GlobalFilter, Ordered {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Sample sample = Timer.start(meterRegistry);
return chain.filter(exchange)
.doOnSuccess(aVoid -> endTimerRespectingCommit(exchange, sample))
return chain.filter(exchange).doOnSuccess(aVoid -> endTimerRespectingCommit(exchange, sample))
.doOnError(throwable -> endTimerRespectingCommit(exchange, sample));
}

View File

@@ -82,8 +82,7 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
// do not use this headersFilters directly, use getHeadersFilters() instead.
private volatile List<HttpHeadersFilter> headersFilters;
public NettyRoutingFilter(HttpClient httpClient,
ObjectProvider<List<HttpHeadersFilter>> headersFiltersProvider,
public NettyRoutingFilter(HttpClient httpClient, ObjectProvider<List<HttpHeadersFilter>> headersFiltersProvider,
HttpClientProperties properties) {
this.httpClient = httpClient;
this.headersFiltersProvider = headersFiltersProvider;
@@ -108,8 +107,7 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();
if (isAlreadyRouted(exchange)
|| (!"http".equals(scheme) && !"https".equals(scheme))) {
if (isAlreadyRouted(exchange) || (!"http".equals(scheme) && !"https".equals(scheme))) {
return chain.filter(exchange);
}
setAlreadyRouted(exchange);
@@ -124,82 +122,72 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
final DefaultHttpHeaders httpHeaders = new DefaultHttpHeaders();
filtered.forEach(httpHeaders::set);
boolean preserveHost = exchange
.getAttributeOrDefault(PRESERVE_HOST_HEADER_ATTRIBUTE, false);
boolean preserveHost = exchange.getAttributeOrDefault(PRESERVE_HOST_HEADER_ATTRIBUTE, false);
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
Flux<HttpClientResponse> responseFlux = getHttpClient(route, exchange)
.headers(headers -> {
headers.add(httpHeaders);
// Will either be set below, or later by Netty
headers.remove(HttpHeaders.HOST);
if (preserveHost) {
String host = request.getHeaders().getFirst(HttpHeaders.HOST);
headers.add(HttpHeaders.HOST, host);
}
}).request(method).uri(url).send((req, nettyOutbound) -> {
if (log.isTraceEnabled()) {
nettyOutbound
.withConnection(connection -> log.trace("outbound route: "
+ connection.channel().id().asShortText()
+ ", inbound: " + exchange.getLogPrefix()));
}
return nettyOutbound.send(request.getBody().map(this::getByteBuf));
}).responseConnection((res, connection) -> {
Flux<HttpClientResponse> responseFlux = getHttpClient(route, exchange).headers(headers -> {
headers.add(httpHeaders);
// Will either be set below, or later by Netty
headers.remove(HttpHeaders.HOST);
if (preserveHost) {
String host = request.getHeaders().getFirst(HttpHeaders.HOST);
headers.add(HttpHeaders.HOST, host);
}
}).request(method).uri(url).send((req, nettyOutbound) -> {
if (log.isTraceEnabled()) {
nettyOutbound.withConnection(connection -> log.trace("outbound route: "
+ connection.channel().id().asShortText() + ", inbound: " + exchange.getLogPrefix()));
}
return nettyOutbound.send(request.getBody().map(this::getByteBuf));
}).responseConnection((res, connection) -> {
// Defer committing the response until all route filters have run
// Put client response as ServerWebExchange attribute and write
// response later NettyWriteResponseFilter
exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);
exchange.getAttributes().put(CLIENT_RESPONSE_CONN_ATTR, connection);
// Defer committing the response until all route filters have run
// Put client response as ServerWebExchange attribute and write
// response later NettyWriteResponseFilter
exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);
exchange.getAttributes().put(CLIENT_RESPONSE_CONN_ATTR, connection);
ServerHttpResponse response = exchange.getResponse();
// put headers and status so filters can modify the response
HttpHeaders headers = new HttpHeaders();
ServerHttpResponse response = exchange.getResponse();
// put headers and status so filters can modify the response
HttpHeaders headers = new HttpHeaders();
res.responseHeaders().forEach(
entry -> headers.add(entry.getKey(), entry.getValue()));
res.responseHeaders().forEach(entry -> headers.add(entry.getKey(), entry.getValue()));
String contentTypeValue = headers.getFirst(HttpHeaders.CONTENT_TYPE);
if (StringUtils.hasLength(contentTypeValue)) {
exchange.getAttributes().put(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR,
contentTypeValue);
}
String contentTypeValue = headers.getFirst(HttpHeaders.CONTENT_TYPE);
if (StringUtils.hasLength(contentTypeValue)) {
exchange.getAttributes().put(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR, contentTypeValue);
}
setResponseStatus(res, response);
setResponseStatus(res, response);
// make sure headers filters run after setting status so it is
// available in response
HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter(
getHeadersFilters(), headers, exchange, Type.RESPONSE);
// make sure headers filters run after setting status so it is
// available in response
HttpHeaders filteredResponseHeaders = HttpHeadersFilter.filter(getHeadersFilters(), headers, exchange,
Type.RESPONSE);
if (!filteredResponseHeaders
.containsKey(HttpHeaders.TRANSFER_ENCODING)
&& filteredResponseHeaders
.containsKey(HttpHeaders.CONTENT_LENGTH)) {
// It is not valid to have both the transfer-encoding header and
// the content-length header.
// Remove the transfer-encoding header in the response if the
// content-length header is present.
response.getHeaders().remove(HttpHeaders.TRANSFER_ENCODING);
}
if (!filteredResponseHeaders.containsKey(HttpHeaders.TRANSFER_ENCODING)
&& filteredResponseHeaders.containsKey(HttpHeaders.CONTENT_LENGTH)) {
// It is not valid to have both the transfer-encoding header and
// the content-length header.
// Remove the transfer-encoding header in the response if the
// content-length header is present.
response.getHeaders().remove(HttpHeaders.TRANSFER_ENCODING);
}
exchange.getAttributes().put(CLIENT_RESPONSE_HEADER_NAMES,
filteredResponseHeaders.keySet());
exchange.getAttributes().put(CLIENT_RESPONSE_HEADER_NAMES, filteredResponseHeaders.keySet());
response.getHeaders().putAll(filteredResponseHeaders);
response.getHeaders().putAll(filteredResponseHeaders);
return Mono.just(res);
});
return Mono.just(res);
});
Duration responseTimeout = getResponseTimeout(route);
if (responseTimeout != null) {
responseFlux = responseFlux
.timeout(responseTimeout, Mono.error(new TimeoutException(
"Response took longer than timeout: " + responseTimeout)))
.timeout(responseTimeout,
Mono.error(new TimeoutException("Response took longer than timeout: " + responseTimeout)))
.onErrorMap(TimeoutException.class,
th -> new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT,
th.getMessage(), th));
th -> new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT, th.getMessage(), th));
}
return responseFlux.then(chain.filter(exchange));
@@ -215,12 +203,10 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
DefaultDataBuffer buffer = (DefaultDataBuffer) dataBuffer;
return Unpooled.wrappedBuffer(buffer.getNativeBuffer());
}
throw new IllegalArgumentException(
"Unable to handle DataBuffer of type " + dataBuffer.getClass());
throw new IllegalArgumentException("Unable to handle DataBuffer of type " + dataBuffer.getClass());
}
private void setResponseStatus(HttpClientResponse clientResponse,
ServerHttpResponse response) {
private void setResponseStatus(HttpClientResponse clientResponse, ServerHttpResponse response) {
HttpStatus status = HttpStatus.resolve(clientResponse.status().code());
if (status != null) {
response.setStatusCode(status);
@@ -230,14 +216,12 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
response = ((ServerHttpResponseDecorator) response).getDelegate();
}
if (response instanceof AbstractServerHttpResponse) {
((AbstractServerHttpResponse) response)
.setStatusCodeValue(clientResponse.status().code());
((AbstractServerHttpResponse) response).setStatusCodeValue(clientResponse.status().code());
}
else {
// TODO: log warning here, not throw error?
throw new IllegalStateException("Unable to set status code "
+ clientResponse.status().code() + " on response of type "
+ response.getClass().getName());
throw new IllegalStateException("Unable to set status code " + clientResponse.status().code()
+ " on response of type " + response.getClass().getName());
}
}
}
@@ -255,8 +239,8 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
Object connectTimeoutAttr = route.getMetadata().get(CONNECT_TIMEOUT_ATTR);
if (connectTimeoutAttr != null) {
Integer connectTimeout = getInteger(connectTimeoutAttr);
return this.httpClient.tcpConfiguration((tcpClient) -> tcpClient
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout));
return this.httpClient.tcpConfiguration(
(tcpClient) -> tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout));
}
return httpClient;
}
@@ -283,8 +267,7 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
responseTimeout = Long.valueOf(responseTimeoutAttr.toString());
}
}
return responseTimeout != null ? Duration.ofMillis(responseTimeout)
: properties.getResponseTimeout();
return responseTimeout != null ? Duration.ofMillis(responseTimeout) : properties.getResponseTimeout();
}
}

View File

@@ -104,18 +104,15 @@ public class NettyWriteResponseFilter implements GlobalFilter, Ordered {
protected DataBuffer wrap(ByteBuf byteBuf, ServerHttpResponse response) {
if (response.bufferFactory() instanceof NettyDataBufferFactory) {
NettyDataBufferFactory factory = (NettyDataBufferFactory) response
.bufferFactory();
NettyDataBufferFactory factory = (NettyDataBufferFactory) response.bufferFactory();
return factory.wrap(byteBuf);
}
// MockServerHttpResponse creates these
else if (response.bufferFactory() instanceof DefaultDataBufferFactory) {
DefaultDataBufferFactory factory = (DefaultDataBufferFactory) response
.bufferFactory();
DefaultDataBufferFactory factory = (DefaultDataBufferFactory) response.bufferFactory();
return factory.wrap(byteBuf.nioBuffer());
}
throw new IllegalArgumentException(
"Unkown DataBufferFactory type " + response.bufferFactory().getClass());
throw new IllegalArgumentException("Unkown DataBufferFactory type " + response.bufferFactory().getClass());
}
private void cleanup(ServerWebExchange exchange) {
@@ -128,8 +125,7 @@ public class NettyWriteResponseFilter implements GlobalFilter, Ordered {
// TODO: use framework if possible
// TODO: port to WebClientWriteResponseFilter
private boolean isStreamingMediaType(@Nullable MediaType contentType) {
return (contentType != null && this.streamingMediaTypes.stream()
.anyMatch(contentType::isCompatibleWith));
return (contentType != null && this.streamingMediaTypes.stream().anyMatch(contentType::isCompatibleWith));
}
}

View File

@@ -51,8 +51,7 @@ public class OrderedGatewayFilter implements GatewayFilter, Ordered {
@Override
public String toString() {
return new StringBuilder("[").append(delegate).append(", order = ").append(order)
.append("]").toString();
return new StringBuilder("[").append(delegate).append(", order = ").append(order).append("]").toString();
}
}

View File

@@ -50,8 +50,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.a
*/
public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered {
private static final Log log = LogFactory
.getLog(ReactiveLoadBalancerClientFilter.class);
private static final Log log = LogFactory.getLog(ReactiveLoadBalancerClientFilter.class);
/**
* Order of filter.
@@ -78,23 +77,20 @@ public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
if (url == null
|| (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
return chain.filter(exchange);
}
// preserve the original url
addOriginalRequestUrl(exchange, url);
if (log.isTraceEnabled()) {
log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName()
+ " url before: " + url);
log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);
}
return choose(exchange).doOnNext(response -> {
if (!response.hasServer()) {
throw NotFoundException.create(properties.isUse404(),
"Unable to find instance for " + url.getHost());
throw NotFoundException.create(properties.isUse404(), "Unable to find instance for " + url.getHost());
}
URI uri = exchange.getRequest().getURI();
@@ -106,8 +102,8 @@ public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered {
overrideScheme = url.getScheme();
}
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(
response.getServer(), overrideScheme);
DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(response.getServer(),
overrideScheme);
URI requestUrl = reconstructURI(serviceInstance, uri);
@@ -125,8 +121,8 @@ public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered {
@SuppressWarnings("deprecation")
private Mono<Response<ServiceInstance>> choose(ServerWebExchange exchange) {
URI uri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
ReactorLoadBalancer<ServiceInstance> loadBalancer = this.clientFactory
.getInstance(uri.getHost(), ReactorServiceInstanceLoadBalancer.class);
ReactorLoadBalancer<ServiceInstance> loadBalancer = this.clientFactory.getInstance(uri.getHost(),
ReactorServiceInstanceLoadBalancer.class);
if (loadBalancer == null) {
throw new NotFoundException("No loadbalancer available for " + uri.getHost());
}

View File

@@ -50,8 +50,8 @@ public class RouteToRequestUrlFilter implements GlobalFilter, Ordered {
/* for testing */
static boolean hasAnotherScheme(URI uri) {
return schemePattern.matcher(uri.getSchemeSpecificPart()).matches()
&& uri.getHost() == null && uri.getRawPath() == null;
return schemePattern.matcher(uri.getSchemeSpecificPart()).matches() && uri.getHost() == null
&& uri.getRawPath() == null;
}
@Override
@@ -73,8 +73,7 @@ public class RouteToRequestUrlFilter implements GlobalFilter, Ordered {
if (hasAnotherScheme(routeUri)) {
// this is a special url, save scheme to special attribute
// replace routeUri with schemeSpecificPart
exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR,
routeUri.getScheme());
exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, routeUri.getScheme());
routeUri = URI.create(routeUri.getSchemeSpecificPart());
}
@@ -88,8 +87,7 @@ public class RouteToRequestUrlFilter implements GlobalFilter, Ordered {
URI mergedUrl = UriComponentsBuilder.fromUri(uri)
// .uri(routeUri)
.scheme(routeUri.getScheme()).host(routeUri.getHost())
.port(routeUri.getPort()).build(encoded).toUri();
.scheme(routeUri.getScheme()).host(routeUri.getHost()).port(routeUri.getPort()).build(encoded).toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);
return chain.filter(exchange);
}

View File

@@ -76,8 +76,7 @@ public class WebClientHttpRoutingFilter implements GlobalFilter, Ordered {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();
if (isAlreadyRouted(exchange)
|| (!"http".equals(scheme) && !"https".equals(scheme))) {
if (isAlreadyRouted(exchange) || (!"http".equals(scheme) && !"https".equals(scheme))) {
return chain.filter(exchange);
}
setAlreadyRouted(exchange);
@@ -88,17 +87,15 @@ public class WebClientHttpRoutingFilter implements GlobalFilter, Ordered {
HttpHeaders filteredHeaders = filterRequest(getHeadersFilters(), exchange);
boolean preserveHost = exchange
.getAttributeOrDefault(PRESERVE_HOST_HEADER_ATTRIBUTE, false);
boolean preserveHost = exchange.getAttributeOrDefault(PRESERVE_HOST_HEADER_ATTRIBUTE, false);
RequestBodySpec bodySpec = this.webClient.method(method).uri(requestUrl)
.headers(httpHeaders -> {
httpHeaders.addAll(filteredHeaders);
// TODO: can this support preserviceHostHeader?
if (!preserveHost) {
httpHeaders.remove(HttpHeaders.HOST);
}
});
RequestBodySpec bodySpec = this.webClient.method(method).uri(requestUrl).headers(httpHeaders -> {
httpHeaders.addAll(filteredHeaders);
// TODO: can this support preserviceHostHeader?
if (!preserveHost) {
httpHeaders.remove(HttpHeaders.HOST);
}
});
RequestHeadersSpec<?> headersSpec;
if (requiresBody(method)) {

View File

@@ -49,22 +49,18 @@ public class WebClientWriteResponseFilter implements GlobalFilter, Ordered {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_ATTR is not added
// until the WebHandler is run
return chain.filter(exchange).doOnError(throwable -> cleanup(exchange))
.then(Mono.defer(() -> {
ClientResponse clientResponse = exchange
.getAttribute(CLIENT_RESPONSE_ATTR);
if (clientResponse == null) {
return Mono.empty();
}
log.trace("WebClientWriteResponseFilter start");
ServerHttpResponse response = exchange.getResponse();
return chain.filter(exchange).doOnError(throwable -> cleanup(exchange)).then(Mono.defer(() -> {
ClientResponse clientResponse = exchange.getAttribute(CLIENT_RESPONSE_ATTR);
if (clientResponse == null) {
return Mono.empty();
}
log.trace("WebClientWriteResponseFilter start");
ServerHttpResponse response = exchange.getResponse();
return response
.writeWith(
clientResponse.body(BodyExtractors.toDataBuffers()))
// .log("webClient response")
.doOnCancel(() -> cleanup(exchange));
}));
return response.writeWith(clientResponse.body(BodyExtractors.toDataBuffers()))
// .log("webClient response")
.doOnCancel(() -> cleanup(exchange));
}));
}
private void cleanup(ServerWebExchange exchange) {

View File

@@ -68,8 +68,7 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
// do not use this headersFilters directly, use getHeadersFilters() instead.
private volatile List<HttpHeadersFilter> headersFilters;
public WebsocketRoutingFilter(WebSocketClient webSocketClient,
WebSocketService webSocketService,
public WebsocketRoutingFilter(WebSocketClient webSocketClient, WebSocketService webSocketService,
ObjectProvider<List<HttpHeadersFilter>> headersFiltersProvider) {
this.webSocketClient = webSocketClient;
this.webSocketService = webSocketService;
@@ -95,8 +94,7 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();
if (isAlreadyRouted(exchange)
|| (!"ws".equals(scheme) && !"wss".equals(scheme))) {
if (isAlreadyRouted(exchange) || (!"ws".equals(scheme) && !"wss".equals(scheme))) {
return chain.filter(exchange);
}
setAlreadyRouted(exchange);
@@ -106,27 +104,23 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
List<String> protocols = headers.get(SEC_WEBSOCKET_PROTOCOL);
if (protocols != null) {
protocols = headers.get(SEC_WEBSOCKET_PROTOCOL).stream().flatMap(
header -> Arrays.stream(commaDelimitedListToStringArray(header)))
.map(String::trim).collect(Collectors.toList());
protocols = headers.get(SEC_WEBSOCKET_PROTOCOL).stream()
.flatMap(header -> Arrays.stream(commaDelimitedListToStringArray(header))).map(String::trim)
.collect(Collectors.toList());
}
return this.webSocketService.handleRequest(exchange, new ProxyWebSocketHandler(
requestUrl, this.webSocketClient, filtered, protocols));
return this.webSocketService.handleRequest(exchange,
new ProxyWebSocketHandler(requestUrl, this.webSocketClient, filtered, protocols));
}
private List<HttpHeadersFilter> getHeadersFilters() {
if (this.headersFilters == null) {
this.headersFilters = this.headersFiltersProvider
.getIfAvailable(ArrayList::new);
this.headersFilters = this.headersFiltersProvider.getIfAvailable(ArrayList::new);
headersFilters.add((headers, exchange) -> {
HttpHeaders filtered = new HttpHeaders();
headers.entrySet().stream()
.filter(entry -> !entry.getKey().toLowerCase()
.startsWith("sec-websocket"))
.forEach(header -> filtered.addAll(header.getKey(),
header.getValue()));
headers.entrySet().stream().filter(entry -> !entry.getKey().toLowerCase().startsWith("sec-websocket"))
.forEach(header -> filtered.addAll(header.getKey(), header.getValue()));
return filtered;
});
}
@@ -140,12 +134,10 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
String scheme = requestUrl.getScheme().toLowerCase();
String upgrade = exchange.getRequest().getHeaders().getUpgrade();
// change the scheme if the socket client send a "http" or "https"
if ("WebSocket".equalsIgnoreCase(upgrade)
&& ("http".equals(scheme) || "https".equals(scheme))) {
if ("WebSocket".equalsIgnoreCase(upgrade) && ("http".equals(scheme) || "https".equals(scheme))) {
String wsScheme = convertHttpToWs(scheme);
boolean encoded = containsEncodedParts(requestUrl);
URI wsRequestUrl = UriComponentsBuilder.fromUri(requestUrl).scheme(wsScheme)
.build(encoded).toUri();
URI wsRequestUrl = UriComponentsBuilder.fromUri(requestUrl).scheme(wsScheme).build(encoded).toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, wsRequestUrl);
if (log.isTraceEnabled()) {
log.trace("changeSchemeTo:[" + wsRequestUrl + "]");
@@ -163,8 +155,7 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
private final List<String> subProtocols;
ProxyWebSocketHandler(URI url, WebSocketClient client, HttpHeaders headers,
List<String> protocols) {
ProxyWebSocketHandler(URI url, WebSocketClient client, HttpHeaders headers, List<String> protocols) {
this.client = client;
this.url = url;
this.headers = headers;
@@ -191,8 +182,8 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
Mono<Void> proxySessionSend = proxySession
.send(session.receive().doOnNext(WebSocketMessage::retain));
// .log("proxySessionSend", Level.FINE);
Mono<Void> serverSessionSend = session.send(
proxySession.receive().doOnNext(WebSocketMessage::retain));
Mono<Void> serverSessionSend = session
.send(proxySession.receive().doOnNext(WebSocketMessage::retain));
// .log("sessionSend", Level.FINE);
return Mono.zip(proxySessionSend, serverSessionSend).then();
}

View File

@@ -49,8 +49,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.W
* @author Spencer Gibb
* @author Alexey Nakidkin
*/
public class WeightCalculatorWebFilter
implements WebFilter, Ordered, SmartApplicationListener {
public class WeightCalculatorWebFilter implements WebFilter, Ordered, SmartApplicationListener {
/**
* Order of Weight Calculator Web filter.
@@ -138,15 +137,13 @@ public class WeightCalculatorWebFilter
WeightConfig config = new WeightConfig(event.getRouteId());
this.configurationService.with(config).name(WeightConfig.CONFIG_PREFIX)
.normalizedProperties(args).bind();
this.configurationService.with(config).name(WeightConfig.CONFIG_PREFIX).normalizedProperties(args).bind();
addWeightConfig(config);
}
private boolean hasRelevantKey(Map<String, Object> args) {
return args.keySet().stream()
.anyMatch(key -> key.startsWith(WeightConfig.CONFIG_PREFIX + "."));
return args.keySet().stream().anyMatch(key -> key.startsWith(WeightConfig.CONFIG_PREFIX + "."));
}
/* for testing */ void addWeightConfig(WeightConfig weightConfig) {
@@ -227,8 +224,7 @@ public class WeightCalculatorWebFilter
List<Double> ranges = config.ranges;
if (log.isTraceEnabled()) {
log.trace("Weight for group: " + group + ", ranges: " + ranges + ", r: "
+ r);
log.trace("Weight for group: " + group + ", ranges: " + ranges + ", r: " + r);
}
for (int i = 0; i < ranges.size() - 1; i++) {
@@ -272,10 +268,8 @@ public class WeightCalculatorWebFilter
@Override
public String toString() {
return new ToStringCreator(this).append("group", group)
.append("weights", weights)
.append("normalizedWeights", normalizedWeights)
.append("rangeIndexes", rangeIndexes).toString();
return new ToStringCreator(this).append("group", group).append("weights", weights)
.append("normalizedWeights", normalizedWeights).append("rangeIndexes", rangeIndexes).toString();
}
}

View File

@@ -33,8 +33,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.G
*
* @author Toshiaki Maki
*/
public abstract class AbstractChangeRequestUriGatewayFilterFactory<T>
extends AbstractGatewayFilterFactory<T> {
public abstract class AbstractChangeRequestUriGatewayFilterFactory<T> extends AbstractGatewayFilterFactory<T> {
private final int order;
@@ -47,8 +46,7 @@ public abstract class AbstractChangeRequestUriGatewayFilterFactory<T>
this(clazz, RouteToRequestUrlFilter.ROUTE_TO_URL_FILTER_ORDER + 1);
}
protected abstract Optional<URI> determineRequestUri(ServerWebExchange exchange,
T config);
protected abstract Optional<URI> determineRequestUri(ServerWebExchange exchange, T config);
public GatewayFilter apply(T config) {
return new OrderedGatewayFilter((exchange, chain) -> {

View File

@@ -25,8 +25,8 @@ import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.core.style.ToStringCreator;
import org.springframework.validation.annotation.Validated;
public abstract class AbstractNameValueGatewayFilterFactory extends
AbstractGatewayFilterFactory<AbstractNameValueGatewayFilterFactory.NameValueConfig> {
public abstract class AbstractNameValueGatewayFilterFactory
extends AbstractGatewayFilterFactory<AbstractNameValueGatewayFilterFactory.NameValueConfig> {
public AbstractNameValueGatewayFilterFactory() {
super(NameValueConfig.class);
@@ -65,8 +65,7 @@ public abstract class AbstractNameValueGatewayFilterFactory extends
@Override
public String toString() {
return new ToStringCreator(this).append("name", name).append("value", value)
.toString();
return new ToStringCreator(this).append("name", name).append("value", value).toString();
}
}

View File

@@ -29,18 +29,15 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
/**
* @author Spencer Gibb
*/
public class AddRequestHeaderGatewayFilterFactory
extends AbstractNameValueGatewayFilterFactory {
public class AddRequestHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
ServerHttpRequest request = exchange.getRequest().mutate()
.header(config.getName(), value).build();
ServerHttpRequest request = exchange.getRequest().mutate().header(config.getName(), value).build();
return chain.filter(exchange.mutate().request(request).build());
}

View File

@@ -33,15 +33,13 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
/**
* @author Spencer Gibb
*/
public class AddRequestParameterGatewayFilterFactory
extends AbstractNameValueGatewayFilterFactory {
public class AddRequestParameterGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI uri = exchange.getRequest().getURI();
StringBuilder query = new StringBuilder();
String originalQuery = uri.getRawQuery();
@@ -60,17 +58,14 @@ public class AddRequestParameterGatewayFilterFactory
query.append(value);
try {
URI newUri = UriComponentsBuilder.fromUri(uri)
.replaceQuery(query.toString()).build(true).toUri();
URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(query.toString()).build(true).toUri();
ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri)
.build();
ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
return chain.filter(exchange.mutate().request(request).build());
}
catch (RuntimeException ex) {
throw new IllegalStateException(
"Invalid URI query: \"" + query.toString() + "\"");
throw new IllegalStateException("Invalid URI query: \"" + query.toString() + "\"");
}
}

View File

@@ -28,15 +28,13 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
/**
* @author Spencer Gibb
*/
public class AddResponseHeaderGatewayFilterFactory
extends AbstractNameValueGatewayFilterFactory {
public class AddResponseHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
exchange.getResponse().getHeaders().add(config.getName(), value);

View File

@@ -69,8 +69,8 @@ Modified response header Access-Control-Allow-Credentials: true
/**
* @author Vitaliy Pavlyuk
*/
public class DedupeResponseHeaderGatewayFilterFactory extends
AbstractGatewayFilterFactory<DedupeResponseHeaderGatewayFilterFactory.Config> {
public class DedupeResponseHeaderGatewayFilterFactory
extends AbstractGatewayFilterFactory<DedupeResponseHeaderGatewayFilterFactory.Config> {
private static final String STRATEGY_KEY = "strategy";
@@ -87,18 +87,15 @@ public class DedupeResponseHeaderGatewayFilterFactory extends
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(
() -> dedupe(exchange.getResponse().getHeaders(), config)));
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> dedupe(exchange.getResponse().getHeaders(), config)));
}
@Override
public String toString() {
return filterToStringCreator(
DedupeResponseHeaderGatewayFilterFactory.this)
.append(config.getName(), config.getStrategy())
.toString();
return filterToStringCreator(DedupeResponseHeaderGatewayFilterFactory.this)
.append(config.getName(), config.getStrategy()).toString();
}
};
}

View File

@@ -45,8 +45,7 @@ public class FallbackHeadersGatewayFilterFactory
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
Throwable exception = exchange
.getAttribute(CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR);
Throwable exception = exchange.getAttribute(CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR);
ServerWebExchange filteredExchange;
if (exception == null) {
filteredExchange = exchange;
@@ -58,19 +57,15 @@ public class FallbackHeadersGatewayFilterFactory
};
}
private ServerWebExchange addFallbackHeaders(Config config,
ServerWebExchange exchange, Throwable executionException) {
private ServerWebExchange addFallbackHeaders(Config config, ServerWebExchange exchange,
Throwable executionException) {
ServerHttpRequest.Builder requestBuilder = exchange.getRequest().mutate();
requestBuilder.header(config.executionExceptionTypeHeaderName,
executionException.getClass().getName());
requestBuilder.header(config.executionExceptionMessageHeaderName,
executionException.getMessage());
requestBuilder.header(config.executionExceptionTypeHeaderName, executionException.getClass().getName());
requestBuilder.header(config.executionExceptionMessageHeaderName, executionException.getMessage());
Throwable rootCause = getRootCause(executionException);
if (rootCause != null) {
requestBuilder.header(config.rootCauseExceptionTypeHeaderName,
rootCause.getClass().getName());
requestBuilder.header(config.rootCauseExceptionMessageHeaderName,
rootCause.getMessage());
requestBuilder.header(config.rootCauseExceptionTypeHeaderName, rootCause.getClass().getName());
requestBuilder.header(config.rootCauseExceptionMessageHeaderName, rootCause.getMessage());
}
return exchange.mutate().request(requestBuilder.build()).build();
}
@@ -111,8 +106,7 @@ public class FallbackHeadersGatewayFilterFactory
return executionExceptionTypeHeaderName;
}
public void setExecutionExceptionTypeHeaderName(
String executionExceptionTypeHeaderName) {
public void setExecutionExceptionTypeHeaderName(String executionExceptionTypeHeaderName) {
this.executionExceptionTypeHeaderName = executionExceptionTypeHeaderName;
}
@@ -120,8 +114,7 @@ public class FallbackHeadersGatewayFilterFactory
return executionExceptionMessageHeaderName;
}
public void setExecutionExceptionMessageHeaderName(
String executionExceptionMessageHeaderName) {
public void setExecutionExceptionMessageHeaderName(String executionExceptionMessageHeaderName) {
this.executionExceptionMessageHeaderName = executionExceptionMessageHeaderName;
}
@@ -129,8 +122,7 @@ public class FallbackHeadersGatewayFilterFactory
return rootCauseExceptionTypeHeaderName;
}
public void setRootCauseExceptionTypeHeaderName(
String rootCauseExceptionTypeHeaderName) {
public void setRootCauseExceptionTypeHeaderName(String rootCauseExceptionTypeHeaderName) {
this.rootCauseExceptionTypeHeaderName = rootCauseExceptionTypeHeaderName;
}
@@ -138,8 +130,7 @@ public class FallbackHeadersGatewayFilterFactory
return rootCauseExceptionMessageHeaderName;
}
public void setCauseExceptionMessageHeaderName(
String causeExceptionMessageHeaderName) {
public void setCauseExceptionMessageHeaderName(String causeExceptionMessageHeaderName) {
this.rootCauseExceptionMessageHeaderName = causeExceptionMessageHeaderName;
}

View File

@@ -32,8 +32,8 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
/**
* @author Tony Clarke
*/
public class MapRequestHeaderGatewayFilterFactory extends
AbstractGatewayFilterFactory<MapRequestHeaderGatewayFilterFactory.Config> {
public class MapRequestHeaderGatewayFilterFactory
extends AbstractGatewayFilterFactory<MapRequestHeaderGatewayFilterFactory.Config> {
/**
* From Header key.
@@ -57,18 +57,14 @@ public class MapRequestHeaderGatewayFilterFactory extends
public GatewayFilter apply(MapRequestHeaderGatewayFilterFactory.Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
if (!exchange.getRequest().getHeaders()
.containsKey(config.getFromHeader())) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (!exchange.getRequest().getHeaders().containsKey(config.getFromHeader())) {
return chain.filter(exchange);
}
List<String> headerValues = exchange.getRequest().getHeaders()
.get(config.getFromHeader());
List<String> headerValues = exchange.getRequest().getHeaders().get(config.getFromHeader());
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(i -> i.addAll(config.getToHeader(), headerValues))
.build();
.headers(i -> i.addAll(config.getToHeader(), headerValues)).build();
return chain.filter(exchange.mutate().request(request).build());
}

View File

@@ -44,8 +44,7 @@ public class PrefixPathGatewayFilterFactory
*/
public static final String PREFIX_KEY = "prefix";
private static final Log log = LogFactory
.getLog(PrefixPathGatewayFilterFactory.class);
private static final Log log = LogFactory.getLog(PrefixPathGatewayFilterFactory.class);
public PrefixPathGatewayFilterFactory() {
super(Config.class);
@@ -60,10 +59,8 @@ public class PrefixPathGatewayFilterFactory
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
boolean alreadyPrefixed = exchange
.getAttributeOrDefault(GATEWAY_ALREADY_PREFIXED_ATTR, false);
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
boolean alreadyPrefixed = exchange.getAttributeOrDefault(GATEWAY_ALREADY_PREFIXED_ATTR, false);
if (alreadyPrefixed) {
return chain.filter(exchange);
}
@@ -78,8 +75,7 @@ public class PrefixPathGatewayFilterFactory
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());
if (log.isTraceEnabled()) {
log.trace("Prefixed URI with: " + config.prefix + " -> "
+ request.getURI());
log.trace("Prefixed URI with: " + config.prefix + " -> " + request.getURI());
}
return chain.filter(exchange.mutate().request(request).build());
@@ -87,8 +83,8 @@ public class PrefixPathGatewayFilterFactory
@Override
public String toString() {
return filterToStringCreator(PrefixPathGatewayFilterFactory.this)
.append("prefix", config.getPrefix()).toString();
return filterToStringCreator(PrefixPathGatewayFilterFactory.this).append("prefix", config.getPrefix())
.toString();
}
};
}

View File

@@ -38,16 +38,14 @@ public class PreserveHostHeaderGatewayFilterFactory extends AbstractGatewayFilte
public GatewayFilter apply(Object config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
exchange.getAttributes().put(PRESERVE_HOST_HEADER_ATTRIBUTE, true);
return chain.filter(exchange);
}
@Override
public String toString() {
return filterToStringCreator(PreserveHostHeaderGatewayFilterFactory.this)
.toString();
return filterToStringCreator(PreserveHostHeaderGatewayFilterFactory.this).toString();
}
};
}

View File

@@ -66,8 +66,7 @@ public class RedirectToGatewayFilterFactory
public GatewayFilter apply(String statusString, String urlString) {
HttpStatusHolder httpStatus = HttpStatusHolder.parse(statusString);
Assert.isTrue(httpStatus.is3xxRedirection(),
"status must be a 3xx code, but was " + statusString);
Assert.isTrue(httpStatus.is3xxRedirection(), "status must be a 3xx code, but was " + statusString);
final URI url = URI.create(urlString);
return apply(httpStatus, url);
}
@@ -79,8 +78,7 @@ public class RedirectToGatewayFilterFactory
public GatewayFilter apply(HttpStatusHolder httpStatus, URI uri) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (!exchange.getResponse().isCommitted()) {
setResponseStatus(exchange, httpStatus);
@@ -100,8 +98,7 @@ public class RedirectToGatewayFilterFactory
else {
status = httpStatus.getStatus().toString();
}
return filterToStringCreator(RedirectToGatewayFilterFactory.this)
.append(status, uri).toString();
return filterToStringCreator(RedirectToGatewayFilterFactory.this).append(status, uri).toString();
}
};
}

View File

@@ -47,11 +47,9 @@ public class RemoveRequestHeaderGatewayFilterFactory
public GatewayFilter apply(NameConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> httpHeaders.remove(config.getName()))
.build();
.headers(httpHeaders -> httpHeaders.remove(config.getName())).build();
return chain.filter(exchange.mutate().request(request).build());
}

View File

@@ -52,28 +52,23 @@ public class RemoveRequestParameterGatewayFilterFactory
public GatewayFilter apply(NameConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>(
request.getQueryParams());
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>(request.getQueryParams());
queryParams.remove(config.getName());
URI newUri = UriComponentsBuilder.fromUri(request.getURI())
.replaceQueryParams(unmodifiableMultiValueMap(queryParams))
.build().toUri();
.replaceQueryParams(unmodifiableMultiValueMap(queryParams)).build().toUri();
ServerHttpRequest updatedRequest = exchange.getRequest().mutate()
.uri(newUri).build();
ServerHttpRequest updatedRequest = exchange.getRequest().mutate().uri(newUri).build();
return chain.filter(exchange.mutate().request(updatedRequest).build());
}
@Override
public String toString() {
return filterToStringCreator(
RemoveRequestParameterGatewayFilterFactory.this)
.append("name", config.getName()).toString();
return filterToStringCreator(RemoveRequestParameterGatewayFilterFactory.this)
.append("name", config.getName()).toString();
}
};
}

View File

@@ -46,17 +46,15 @@ public class RemoveResponseHeaderGatewayFilterFactory
public GatewayFilter apply(NameConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> exchange
.getResponse().getHeaders().remove(config.getName())));
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> exchange.getResponse().getHeaders().remove(config.getName())));
}
@Override
public String toString() {
return filterToStringCreator(
RemoveResponseHeaderGatewayFilterFactory.this)
.append("name", config.getName()).toString();
return filterToStringCreator(RemoveResponseHeaderGatewayFilterFactory.this)
.append("name", config.getName()).toString();
}
};
}

View File

@@ -40,8 +40,8 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
* @author Sakalya Deshpande
*/
public class RequestHeaderSizeGatewayFilterFactory extends
AbstractGatewayFilterFactory<RequestHeaderSizeGatewayFilterFactory.Config> {
public class RequestHeaderSizeGatewayFilterFactory
extends AbstractGatewayFilterFactory<RequestHeaderSizeGatewayFilterFactory.Config> {
private static String ERROR = "Request Header/s size is larger than permissible limit."
+ " Request Header/s size is %s where permissible limit is %s";
@@ -54,8 +54,7 @@ public class RequestHeaderSizeGatewayFilterFactory extends
public GatewayFilter apply(RequestHeaderSizeGatewayFilterFactory.Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
Long headerSizeInBytes = 0L;
@@ -68,8 +67,7 @@ public class RequestHeaderSizeGatewayFilterFactory extends
}
if (headerSizeInBytes > config.getMaxSize().toBytes()) {
exchange.getResponse()
.setStatusCode(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE);
exchange.getResponse().setStatusCode(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE);
exchange.getResponse().getHeaders().add("errorMessage",
getErrorMessage(headerSizeInBytes, config.getMaxSize()));
return exchange.getResponse().setComplete();
@@ -88,8 +86,7 @@ public class RequestHeaderSizeGatewayFilterFactory extends
}
private static String getErrorMessage(Long currentRequestSize, DataSize maxSize) {
return String.format(ERROR, DataSize.of(currentRequestSize, DataUnit.BYTES),
maxSize);
return String.format(ERROR, DataSize.of(currentRequestSize, DataUnit.BYTES), maxSize);
}
public static class Config {

View File

@@ -38,11 +38,10 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
*
* @author Toshiaki Maki
*/
public class RequestHeaderToRequestUriGatewayFilterFactory extends
AbstractChangeRequestUriGatewayFilterFactory<AbstractGatewayFilterFactory.NameConfig> {
public class RequestHeaderToRequestUriGatewayFilterFactory
extends AbstractChangeRequestUriGatewayFilterFactory<AbstractGatewayFilterFactory.NameConfig> {
private final Logger log = LoggerFactory
.getLogger(RequestHeaderToRequestUriGatewayFilterFactory.class);
private final Logger log = LoggerFactory.getLogger(RequestHeaderToRequestUriGatewayFilterFactory.class);
public RequestHeaderToRequestUriGatewayFilterFactory() {
super(NameConfig.class);
@@ -61,24 +60,21 @@ public class RequestHeaderToRequestUriGatewayFilterFactory extends
return new OrderedGatewayFilter(gatewayFilter, gatewayFilter.getOrder()) {
@Override
public String toString() {
return filterToStringCreator(
RequestHeaderToRequestUriGatewayFilterFactory.this)
.append("name", config.getName()).toString();
return filterToStringCreator(RequestHeaderToRequestUriGatewayFilterFactory.this)
.append("name", config.getName()).toString();
}
};
}
@Override
protected Optional<URI> determineRequestUri(ServerWebExchange exchange,
NameConfig config) {
protected Optional<URI> determineRequestUri(ServerWebExchange exchange, NameConfig config) {
String requestUrl = exchange.getRequest().getHeaders().getFirst(config.getName());
return Optional.ofNullable(requestUrl).map(url -> {
try {
return new URL(url).toURI();
}
catch (MalformedURLException | URISyntaxException e) {
log.info("Request url is invalid : url={}, error={}", requestUrl,
e.getMessage());
log.info("Request url is invalid : url={}, error={}", requestUrl, e.getMessage());
return null;
}
});

View File

@@ -35,8 +35,8 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.s
* https://gist.github.com/ptarjan/e38f45f2dfe601419ca3af937fff574d#file-1-check_request_rate_limiter-rb-L11-L34.
*/
@ConfigurationProperties("spring.cloud.gateway.filter.request-rate-limiter")
public class RequestRateLimiterGatewayFilterFactory extends
AbstractGatewayFilterFactory<RequestRateLimiterGatewayFilterFactory.Config> {
public class RequestRateLimiterGatewayFilterFactory
extends AbstractGatewayFilterFactory<RequestRateLimiterGatewayFilterFactory.Config> {
/**
* Key-Resolver key.
@@ -57,8 +57,7 @@ public class RequestRateLimiterGatewayFilterFactory extends
/** HttpStatus to return when denyEmptyKey is true, defaults to FORBIDDEN. */
private String emptyKeyStatusCode = HttpStatus.FORBIDDEN.name();
public RequestRateLimiterGatewayFilterFactory(RateLimiter defaultRateLimiter,
KeyResolver defaultKeyResolver) {
public RequestRateLimiterGatewayFilterFactory(RateLimiter defaultRateLimiter, KeyResolver defaultKeyResolver) {
super(Config.class);
this.defaultRateLimiter = defaultRateLimiter;
this.defaultKeyResolver = defaultKeyResolver;
@@ -92,43 +91,38 @@ public class RequestRateLimiterGatewayFilterFactory extends
@Override
public GatewayFilter apply(Config config) {
KeyResolver resolver = getOrDefault(config.keyResolver, defaultKeyResolver);
RateLimiter<Object> limiter = getOrDefault(config.rateLimiter,
defaultRateLimiter);
RateLimiter<Object> limiter = getOrDefault(config.rateLimiter, defaultRateLimiter);
boolean denyEmpty = getOrDefault(config.denyEmptyKey, this.denyEmptyKey);
HttpStatusHolder emptyKeyStatus = HttpStatusHolder
.parse(getOrDefault(config.emptyKeyStatus, this.emptyKeyStatusCode));
return (exchange, chain) -> resolver.resolve(exchange).defaultIfEmpty(EMPTY_KEY)
.flatMap(key -> {
if (EMPTY_KEY.equals(key)) {
if (denyEmpty) {
setResponseStatus(exchange, emptyKeyStatus);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
String routeId = config.getRouteId();
if (routeId == null) {
Route route = exchange
.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
routeId = route.getId();
}
return limiter.isAllowed(routeId, key).flatMap(response -> {
return (exchange, chain) -> resolver.resolve(exchange).defaultIfEmpty(EMPTY_KEY).flatMap(key -> {
if (EMPTY_KEY.equals(key)) {
if (denyEmpty) {
setResponseStatus(exchange, emptyKeyStatus);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
String routeId = config.getRouteId();
if (routeId == null) {
Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
routeId = route.getId();
}
return limiter.isAllowed(routeId, key).flatMap(response -> {
for (Map.Entry<String, String> header : response.getHeaders()
.entrySet()) {
exchange.getResponse().getHeaders().add(header.getKey(),
header.getValue());
}
for (Map.Entry<String, String> header : response.getHeaders().entrySet()) {
exchange.getResponse().getHeaders().add(header.getKey(), header.getValue());
}
if (response.isAllowed()) {
return chain.filter(exchange);
}
if (response.isAllowed()) {
return chain.filter(exchange);
}
setResponseStatus(exchange, config.getStatusCode());
return exchange.getResponse().setComplete();
});
});
setResponseStatus(exchange, config.getStatusCode());
return exchange.getResponse().setComplete();
});
});
}
private <T> T getOrDefault(T configValue, T defaultValue) {

View File

@@ -35,8 +35,8 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
*
* @author Arpan
*/
public class RequestSizeGatewayFilterFactory extends
AbstractGatewayFilterFactory<RequestSizeGatewayFilterFactory.RequestSizeConfig> {
public class RequestSizeGatewayFilterFactory
extends AbstractGatewayFilterFactory<RequestSizeGatewayFilterFactory.RequestSizeConfig> {
private static String PREFIX = "kMGTPE";
@@ -48,8 +48,7 @@ public class RequestSizeGatewayFilterFactory extends
}
private static String getErrorMessage(Long currentRequestSize, Long maxSize) {
return String.format(ERROR, getReadableByteCount(currentRequestSize),
getReadableByteCount(maxSize));
return String.format(ERROR, getReadableByteCount(currentRequestSize), getReadableByteCount(maxSize));
}
private static String getReadableByteCount(long bytes) {
@@ -63,24 +62,20 @@ public class RequestSizeGatewayFilterFactory extends
}
@Override
public GatewayFilter apply(
RequestSizeGatewayFilterFactory.RequestSizeConfig requestSizeConfig) {
public GatewayFilter apply(RequestSizeGatewayFilterFactory.RequestSizeConfig requestSizeConfig) {
requestSizeConfig.validate();
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String contentLength = request.getHeaders().getFirst("content-length");
if (!StringUtils.isEmpty(contentLength)) {
Long currentRequestSize = Long.valueOf(contentLength);
if (currentRequestSize > requestSizeConfig.getMaxSize().toBytes()) {
exchange.getResponse()
.setStatusCode(HttpStatus.PAYLOAD_TOO_LARGE);
exchange.getResponse().setStatusCode(HttpStatus.PAYLOAD_TOO_LARGE);
if (!exchange.getResponse().isCommitted()) {
exchange.getResponse().getHeaders().add("errorMessage",
getErrorMessage(currentRequestSize,
requestSizeConfig.getMaxSize().toBytes()));
getErrorMessage(currentRequestSize, requestSizeConfig.getMaxSize().toBytes()));
}
return exchange.getResponse().setComplete();
}
@@ -105,8 +100,7 @@ public class RequestSizeGatewayFilterFactory extends
return maxSize;
}
public RequestSizeGatewayFilterFactory.RequestSizeConfig setMaxSize(
DataSize maxSize) {
public RequestSizeGatewayFilterFactory.RequestSizeConfig setMaxSize(DataSize maxSize) {
this.maxSize = maxSize;
return this;
}

View File

@@ -48,8 +48,7 @@ import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator;
public class RetryGatewayFilterFactory
extends AbstractGatewayFilterFactory<RetryGatewayFilterFactory.RetryConfig> {
public class RetryGatewayFilterFactory extends AbstractGatewayFilterFactory<RetryGatewayFilterFactory.RetryConfig> {
/**
* Retry iteration key.
@@ -80,8 +79,7 @@ public class RetryGatewayFilterFactory
HttpStatus statusCode = exchange.getResponse().getStatusCode();
boolean retryableStatusCode = retryConfig.getStatuses()
.contains(statusCode);
boolean retryableStatusCode = retryConfig.getStatuses().contains(statusCode);
if (!retryableStatusCode && statusCode != null) { // null status code
// might mean a
@@ -93,14 +91,14 @@ public class RetryGatewayFilterFactory
final boolean finalRetryableStatusCode = retryableStatusCode;
trace("retryableStatusCode: %b, statusCode %s, configured statuses %s, configured series %s",
() -> finalRetryableStatusCode, () -> statusCode,
retryConfig::getStatuses, retryConfig::getSeries);
() -> finalRetryableStatusCode, () -> statusCode, retryConfig::getStatuses,
retryConfig::getSeries);
HttpMethod httpMethod = exchange.getRequest().getMethod();
boolean retryableMethod = retryConfig.getMethods().contains(httpMethod);
trace("retryableMethod: %b, httpMethod %s, configured methods %s",
() -> retryableMethod, () -> httpMethod, retryConfig::getMethods);
trace("retryableMethod: %b, httpMethod %s, configured methods %s", () -> retryableMethod,
() -> httpMethod, retryConfig::getMethods);
return retryableMethod && finalRetryableStatusCode;
};
@@ -126,54 +124,44 @@ public class RetryGatewayFilterFactory
}
Throwable exception = context.exception();
for (Class<? extends Throwable> retryableClass : retryConfig
.getExceptions()) {
if (retryableClass.isInstance(exception) || (exception != null
&& retryableClass.isInstance(exception.getCause()))) {
for (Class<? extends Throwable> retryableClass : retryConfig.getExceptions()) {
if (retryableClass.isInstance(exception)
|| (exception != null && retryableClass.isInstance(exception.getCause()))) {
trace("exception or its cause is retryable %s, configured exceptions %s",
() -> getExceptionNameWithCause(exception),
retryConfig::getExceptions);
() -> getExceptionNameWithCause(exception), retryConfig::getExceptions);
HttpMethod httpMethod = exchange.getRequest().getMethod();
boolean retryableMethod = retryConfig.getMethods()
.contains(httpMethod);
trace("retryableMethod: %b, httpMethod %s, configured methods %s",
() -> retryableMethod, () -> httpMethod,
retryConfig::getMethods);
boolean retryableMethod = retryConfig.getMethods().contains(httpMethod);
trace("retryableMethod: %b, httpMethod %s, configured methods %s", () -> retryableMethod,
() -> httpMethod, retryConfig::getMethods);
return retryableMethod;
}
}
trace("exception or its cause is not retryable %s, configured exceptions %s",
() -> getExceptionNameWithCause(exception),
retryConfig::getExceptions);
() -> getExceptionNameWithCause(exception), retryConfig::getExceptions);
return false;
};
exceptionRetry = Retry.onlyIf(retryContextPredicate)
.doOnRetry(context -> reset(context.applicationContext()))
.retryMax(retryConfig.getRetries());
.doOnRetry(context -> reset(context.applicationContext())).retryMax(retryConfig.getRetries());
BackoffConfig backoff = retryConfig.getBackoff();
if (backoff != null) {
exceptionRetry = exceptionRetry.backoff(getBackoff(backoff));
}
}
GatewayFilter gatewayFilter = apply(retryConfig.getRouteId(), statusCodeRepeat,
exceptionRetry);
GatewayFilter gatewayFilter = apply(retryConfig.getRouteId(), statusCodeRepeat, exceptionRetry);
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return gatewayFilter.filter(exchange, chain);
}
@Override
public String toString() {
return filterToStringCreator(RetryGatewayFilterFactory.this)
.append("retries", retryConfig.getRetries())
.append("series", retryConfig.getSeries())
.append("statuses", retryConfig.getStatuses())
.append("methods", retryConfig.getMethods())
.append("exceptions", retryConfig.getExceptions()).toString();
return filterToStringCreator(RetryGatewayFilterFactory.this).append("retries", retryConfig.getRetries())
.append("series", retryConfig.getSeries()).append("statuses", retryConfig.getStatuses())
.append("methods", retryConfig.getMethods()).append("exceptions", retryConfig.getExceptions())
.toString();
}
};
}
@@ -193,18 +181,17 @@ public class RetryGatewayFilterFactory
}
private Backoff getBackoff(BackoffConfig backoff) {
return Backoff.exponential(backoff.firstBackoff, backoff.maxBackoff,
backoff.factor, backoff.basedOnPreviousValue);
return Backoff.exponential(backoff.firstBackoff, backoff.maxBackoff, backoff.factor,
backoff.basedOnPreviousValue);
}
public boolean exceedsMaxIterations(ServerWebExchange exchange,
RetryConfig retryConfig) {
public boolean exceedsMaxIterations(ServerWebExchange exchange, RetryConfig retryConfig) {
Integer iteration = exchange.getAttribute(RETRY_ITERATION_KEY);
// TODO: deal with null iteration
boolean exceeds = iteration != null && iteration >= retryConfig.getRetries();
trace("exceedsMaxIterations %b, iteration %d, configured retries %d",
() -> exceeds, () -> iteration, retryConfig::getRetries);
trace("exceedsMaxIterations %b, iteration %d, configured retries %d", () -> exceeds, () -> iteration,
retryConfig::getRetries);
return exceeds;
}
@@ -216,8 +203,7 @@ public class RetryGatewayFilterFactory
ServerWebExchangeUtils.reset(exchange);
}
public GatewayFilter apply(String routeId, Repeat<ServerWebExchange> repeat,
Retry<ServerWebExchange> retry) {
public GatewayFilter apply(String routeId, Repeat<ServerWebExchange> repeat, Retry<ServerWebExchange> retry) {
if (routeId != null && getPublisher() != null) {
// send an event to enable caching
getPublisher().publishEvent(new EnableBodyCachingEvent(this, routeId));
@@ -228,20 +214,18 @@ public class RetryGatewayFilterFactory
// chain.filter returns a Mono<Void>
Publisher<Void> publisher = chain.filter(exchange)
// .log("retry-filter", Level.INFO)
.doOnSuccess(aVoid -> updateIteration(exchange))
.doOnError(throwable -> updateIteration(exchange));
.doOnSuccess(aVoid -> updateIteration(exchange)).doOnError(throwable -> updateIteration(exchange));
if (retry != null) {
// retryWhen returns a Mono<Void>
// retry needs to go before repeat
publisher = ((Mono<Void>) publisher).retryWhen(reactor.util.retry.Retry
.withThrowable(retry.withApplicationContext(exchange)));
publisher = ((Mono<Void>) publisher)
.retryWhen(reactor.util.retry.Retry.withThrowable(retry.withApplicationContext(exchange)));
}
if (repeat != null) {
// repeatWhen returns a Flux<Void>
// so this needs to be last and the variable a Publisher<Void>
publisher = ((Mono<Void>) publisher)
.repeatWhen(repeat.withApplicationContext(exchange));
publisher = ((Mono<Void>) publisher).repeatWhen(repeat.withApplicationContext(exchange));
}
return Mono.fromDirect(publisher);
@@ -281,8 +265,7 @@ public class RetryGatewayFilterFactory
private List<HttpMethod> methods = toList(HttpMethod.GET);
private List<Class<? extends Throwable>> exceptions = toList(IOException.class,
TimeoutException.class);
private List<Class<? extends Throwable>> exceptions = toList(IOException.class, TimeoutException.class);
private BackoffConfig backoff;
@@ -292,9 +275,7 @@ public class RetryGatewayFilterFactory
public void validate() {
Assert.isTrue(this.retries > 0, "retries must be greater than 0");
Assert.isTrue(
!this.series.isEmpty() || !this.statuses.isEmpty()
|| !this.exceptions.isEmpty(),
Assert.isTrue(!this.series.isEmpty() || !this.statuses.isEmpty() || !this.exceptions.isEmpty(),
"series, status and exceptions may not all be empty");
Assert.notEmpty(this.methods, "methods may not be empty");
if (this.backoff != null) {
@@ -311,10 +292,9 @@ public class RetryGatewayFilterFactory
return this;
}
public RetryConfig setBackoff(Duration firstBackoff, Duration maxBackoff,
int factor, boolean basedOnPreviousValue) {
this.backoff = new BackoffConfig(firstBackoff, maxBackoff, factor,
basedOnPreviousValue);
public RetryConfig setBackoff(Duration firstBackoff, Duration maxBackoff, int factor,
boolean basedOnPreviousValue) {
this.backoff = new BackoffConfig(firstBackoff, maxBackoff, factor, basedOnPreviousValue);
return this;
}
@@ -388,8 +368,7 @@ public class RetryGatewayFilterFactory
public BackoffConfig() {
}
public BackoffConfig(Duration firstBackoff, Duration maxBackoff, int factor,
boolean basedOnPreviousValue) {
public BackoffConfig(Duration firstBackoff, Duration maxBackoff, int factor, boolean basedOnPreviousValue) {
this.firstBackoff = firstBackoff;
this.maxBackoff = maxBackoff;
this.factor = factor;

View File

@@ -93,8 +93,8 @@ Modified (not) Location response header: http://object-service.prod.example.net/
/**
* @author Vitaliy Pavlyuk
*/
public class RewriteLocationResponseHeaderGatewayFilterFactory extends
AbstractGatewayFilterFactory<RewriteLocationResponseHeaderGatewayFilterFactory.Config> {
public class RewriteLocationResponseHeaderGatewayFilterFactory
extends AbstractGatewayFilterFactory<RewriteLocationResponseHeaderGatewayFilterFactory.Config> {
private static final String STRIP_VERSION_KEY = "stripVersion";
@@ -108,11 +108,9 @@ public class RewriteLocationResponseHeaderGatewayFilterFactory extends
private static final String DEFAULT_PROTOCOLS = "https?|ftps?";
private static final Pattern DEFAULT_HOST_PORT = compileHostPortPattern(
DEFAULT_PROTOCOLS);
private static final Pattern DEFAULT_HOST_PORT = compileHostPortPattern(DEFAULT_PROTOCOLS);
private static final Pattern DEFAULT_HOST_PORT_VERSION = compileHostPortVersionPattern(
DEFAULT_PROTOCOLS);
private static final Pattern DEFAULT_HOST_PORT_VERSION = compileHostPortVersionPattern(DEFAULT_PROTOCOLS);
public RewriteLocationResponseHeaderGatewayFilterFactory() {
super(Config.class);
@@ -123,24 +121,20 @@ public class RewriteLocationResponseHeaderGatewayFilterFactory extends
}
private static Pattern compileHostPortVersionPattern(String protocols) {
return Pattern.compile(
"(?<=^(?:" + protocols + ")://)[^:/]+(?::\\d+)?(?:/v\\d+)?(?=/)");
return Pattern.compile("(?<=^(?:" + protocols + ")://)[^:/]+(?::\\d+)?(?:/v\\d+)?(?=/)");
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(STRIP_VERSION_KEY, LOCATION_HEADER_NAME_KEY, HOST_VALUE_KEY,
PROTOCOLS_KEY);
return Arrays.asList(STRIP_VERSION_KEY, LOCATION_HEADER_NAME_KEY, HOST_VALUE_KEY, PROTOCOLS_KEY);
}
@Override
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> rewriteLocation(exchange, config)));
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> rewriteLocation(exchange, config)));
}
@Override
@@ -159,26 +153,21 @@ public class RewriteLocationResponseHeaderGatewayFilterFactory extends
}
void rewriteLocation(ServerWebExchange exchange, Config config) {
final String location = exchange.getResponse().getHeaders()
.getFirst(config.getLocationHeaderName());
final String location = exchange.getResponse().getHeaders().getFirst(config.getLocationHeaderName());
final String host = config.getHostValue() != null ? config.getHostValue()
: exchange.getRequest().getHeaders().getFirst(HttpHeaders.HOST);
final String path = exchange.getRequest().getURI().getPath();
if (location != null && host != null) {
final String fixedLocation = fixedLocation(location, host, path,
config.getStripVersion(), config.getHostPortPattern(),
config.getHostPortVersionPattern());
exchange.getResponse().getHeaders().set(config.getLocationHeaderName(),
fixedLocation);
final String fixedLocation = fixedLocation(location, host, path, config.getStripVersion(),
config.getHostPortPattern(), config.getHostPortVersionPattern());
exchange.getResponse().getHeaders().set(config.getLocationHeaderName(), fixedLocation);
}
}
String fixedLocation(String location, String host, String path,
StripVersion stripVersion, Pattern hostPortPattern,
String fixedLocation(String location, String host, String path, StripVersion stripVersion, Pattern hostPortPattern,
Pattern hostPortVersionPattern) {
final boolean doStrip = StripVersion.ALWAYS_STRIP.equals(stripVersion)
|| (StripVersion.AS_IN_REQUEST.equals(stripVersion)
&& !VERSIONED_PATH.matcher(path).matches());
|| (StripVersion.AS_IN_REQUEST.equals(stripVersion) && !VERSIONED_PATH.matcher(path).matches());
final Pattern pattern = doStrip ? hostPortVersionPattern : hostPortPattern;
return pattern.matcher(location).replaceFirst(host);
}

View File

@@ -61,8 +61,7 @@ public class RewritePathGatewayFilterFactory
String replacement = config.replacement.replace("$\\", "$");
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest req = exchange.getRequest();
addOriginalRequestUrl(exchange, req.getURI());
String path = req.getURI().getRawPath();

View File

@@ -32,8 +32,8 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
/**
* @author Vitaliy Pavlyuk
*/
public class RewriteResponseHeaderGatewayFilterFactory extends
AbstractGatewayFilterFactory<RewriteResponseHeaderGatewayFilterFactory.Config> {
public class RewriteResponseHeaderGatewayFilterFactory
extends AbstractGatewayFilterFactory<RewriteResponseHeaderGatewayFilterFactory.Config> {
/**
* Regexp key.
@@ -58,20 +58,15 @@ public class RewriteResponseHeaderGatewayFilterFactory extends
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> rewriteHeaders(exchange, config)));
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange).then(Mono.fromRunnable(() -> rewriteHeaders(exchange, config)));
}
@Override
public String toString() {
return filterToStringCreator(
RewriteResponseHeaderGatewayFilterFactory.this)
.append("name", config.getName())
.append("regexp", config.getRegexp())
.append("replacement", config.getReplacement())
.toString();
return filterToStringCreator(RewriteResponseHeaderGatewayFilterFactory.this)
.append("name", config.getName()).append("regexp", config.getRegexp())
.append("replacement", config.getReplacement()).toString();
}
};
}
@@ -88,8 +83,7 @@ public class RewriteResponseHeaderGatewayFilterFactory extends
}
protected List<String> rewriteHeaders(Config config, List<String> headers) {
return headers.stream()
.map(val -> rewrite(val, config.getRegexp(), config.getReplacement()))
return headers.stream().map(val -> rewrite(val, config.getRegexp(), config.getReplacement()))
.collect(Collectors.toList());
}

View File

@@ -41,16 +41,13 @@ public class SaveSessionGatewayFilterFactory extends AbstractGatewayFilterFactor
public GatewayFilter apply(Object config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
return exchange.getSession().map(WebSession::save)
.then(chain.filter(exchange));
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return exchange.getSession().map(WebSession::save).then(chain.filter(exchange));
}
@Override
public String toString() {
return filterToStringCreator(SaveSessionGatewayFilterFactory.this)
.toString();
return filterToStringCreator(SaveSessionGatewayFilterFactory.this).toString();
}
};
}

View File

@@ -86,20 +86,17 @@ public class SecureHeadersGatewayFilterFactory extends AbstractGatewayFilterFact
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
HttpHeaders headers = exchange.getResponse().getHeaders();
List<String> disabled = properties.getDisable();
if (isEnabled(disabled, X_XSS_PROTECTION_HEADER)) {
headers.add(X_XSS_PROTECTION_HEADER,
properties.getXssProtectionHeader());
headers.add(X_XSS_PROTECTION_HEADER, properties.getXssProtectionHeader());
}
if (isEnabled(disabled, STRICT_TRANSPORT_SECURITY_HEADER)) {
headers.add(STRICT_TRANSPORT_SECURITY_HEADER,
properties.getStrictTransportSecurity());
headers.add(STRICT_TRANSPORT_SECURITY_HEADER, properties.getStrictTransportSecurity());
}
if (isEnabled(disabled, X_FRAME_OPTIONS_HEADER)) {
@@ -107,8 +104,7 @@ public class SecureHeadersGatewayFilterFactory extends AbstractGatewayFilterFact
}
if (isEnabled(disabled, X_CONTENT_TYPE_OPTIONS_HEADER)) {
headers.add(X_CONTENT_TYPE_OPTIONS_HEADER,
properties.getContentTypeOptions());
headers.add(X_CONTENT_TYPE_OPTIONS_HEADER, properties.getContentTypeOptions());
}
if (isEnabled(disabled, REFERRER_POLICY_HEADER)) {
@@ -116,18 +112,15 @@ public class SecureHeadersGatewayFilterFactory extends AbstractGatewayFilterFact
}
if (isEnabled(disabled, CONTENT_SECURITY_POLICY_HEADER)) {
headers.add(CONTENT_SECURITY_POLICY_HEADER,
properties.getContentSecurityPolicy());
headers.add(CONTENT_SECURITY_POLICY_HEADER, properties.getContentSecurityPolicy());
}
if (isEnabled(disabled, X_DOWNLOAD_OPTIONS_HEADER)) {
headers.add(X_DOWNLOAD_OPTIONS_HEADER,
properties.getDownloadOptions());
headers.add(X_DOWNLOAD_OPTIONS_HEADER, properties.getDownloadOptions());
}
if (isEnabled(disabled, X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER)) {
headers.add(X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER,
properties.getPermittedCrossDomainPolicies());
headers.add(X_PERMITTED_CROSS_DOMAIN_POLICIES_HEADER, properties.getPermittedCrossDomainPolicies());
}
return chain.filter(exchange);
@@ -135,8 +128,7 @@ public class SecureHeadersGatewayFilterFactory extends AbstractGatewayFilterFact
@Override
public String toString() {
return filterToStringCreator(SecureHeadersGatewayFilterFactory.this)
.toString();
return filterToStringCreator(SecureHeadersGatewayFilterFactory.this).toString();
}
};
}

View File

@@ -176,15 +176,13 @@ public class SecureHeadersProperties {
public String toString() {
final StringBuffer sb = new StringBuffer("SecureHeadersProperties{");
sb.append("xssProtectionHeader='").append(xssProtectionHeader).append('\'');
sb.append(", strictTransportSecurity='").append(strictTransportSecurity)
.append('\'');
sb.append(", strictTransportSecurity='").append(strictTransportSecurity).append('\'');
sb.append(", frameOptions='").append(frameOptions).append('\'');
sb.append(", contentTypeOptions='").append(contentTypeOptions).append('\'');
sb.append(", referrerPolicy='").append(referrerPolicy).append('\'');
sb.append(", contentSecurityPolicy='").append(contentSecurityPolicy).append('\'');
sb.append(", downloadOptions='").append(downloadOptions).append('\'');
sb.append(", permittedCrossDomainPolicies='").append(permittedCrossDomainPolicies)
.append('\'');
sb.append(", permittedCrossDomainPolicies='").append(permittedCrossDomainPolicies).append('\'');
sb.append(", disabled='").append(disable).append('\'');
sb.append('}');
return sb.toString();

View File

@@ -37,8 +37,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.g
/**
* @author Spencer Gibb
*/
public class SetPathGatewayFilterFactory
extends AbstractGatewayFilterFactory<SetPathGatewayFilterFactory.Config> {
public class SetPathGatewayFilterFactory extends AbstractGatewayFilterFactory<SetPathGatewayFilterFactory.Config> {
/**
* Template key.
@@ -60,8 +59,7 @@ public class SetPathGatewayFilterFactory
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest req = exchange.getRequest();
addOriginalRequestUrl(exchange, req.getURI());
@@ -79,8 +77,8 @@ public class SetPathGatewayFilterFactory
@Override
public String toString() {
return filterToStringCreator(SetPathGatewayFilterFactory.this)
.append("template", config.getTemplate()).toString();
return filterToStringCreator(SetPathGatewayFilterFactory.this).append("template", config.getTemplate())
.toString();
}
};
}

View File

@@ -29,19 +29,16 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
/**
* @author Spencer Gibb
*/
public class SetRequestHeaderGatewayFilterFactory
extends AbstractNameValueGatewayFilterFactory {
public class SetRequestHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> httpHeaders.set(config.name, value))
.build();
.headers(httpHeaders -> httpHeaders.set(config.name, value)).build();
return chain.filter(exchange.mutate().request(request).build());
}

View File

@@ -33,8 +33,8 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.P
/**
* @author Andrew Fitzgerald
*/
public class SetRequestHostHeaderGatewayFilterFactory extends
AbstractGatewayFilterFactory<SetRequestHostHeaderGatewayFilterFactory.Config> {
public class SetRequestHostHeaderGatewayFilterFactory
extends AbstractGatewayFilterFactory<SetRequestHostHeaderGatewayFilterFactory.Config> {
public SetRequestHostHeaderGatewayFilterFactory() {
super(Config.class);
@@ -49,15 +49,13 @@ public class SetRequestHostHeaderGatewayFilterFactory extends
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getHost());
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> {
httpHeaders.remove("Host");
httpHeaders.add("Host", value);
}).build();
ServerHttpRequest request = exchange.getRequest().mutate().headers(httpHeaders -> {
httpHeaders.remove("Host");
httpHeaders.add("Host", value);
}).build();
// Make sure the header we just set is preserved
exchange.getAttributes().put(PRESERVE_HOST_HEADER_ATTRIBUTE, true);
@@ -67,9 +65,8 @@ public class SetRequestHostHeaderGatewayFilterFactory extends
@Override
public String toString() {
return filterToStringCreator(
SetRequestHostHeaderGatewayFilterFactory.this)
.append(config.getHost()).toString();
return filterToStringCreator(SetRequestHostHeaderGatewayFilterFactory.this).append(config.getHost())
.toString();
}
};
}

View File

@@ -28,18 +28,16 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
/**
* @author Spencer Gibb
*/
public class SetResponseHeaderGatewayFilterFactory
extends AbstractNameValueGatewayFilterFactory {
public class SetResponseHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
return chain.filter(exchange).then(Mono.fromRunnable(() -> exchange
.getResponse().getHeaders().set(config.name, value)));
return chain.filter(exchange)
.then(Mono.fromRunnable(() -> exchange.getResponse().getHeaders().set(config.name, value)));
}
@Override

View File

@@ -36,8 +36,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.s
* @author Spencer Gibb
*/
@ConfigurationProperties("spring.cloud.gateway.set-status")
public class SetStatusGatewayFilterFactory
extends AbstractGatewayFilterFactory<SetStatusGatewayFilterFactory.Config> {
public class SetStatusGatewayFilterFactory extends AbstractGatewayFilterFactory<SetStatusGatewayFilterFactory.Config> {
/**
* Status key.
@@ -64,8 +63,7 @@ public class SetStatusGatewayFilterFactory
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// option 1 (runs in filter order)
/*
* exchange.getResponse().beforeCommit(() -> {
@@ -78,8 +76,7 @@ public class SetStatusGatewayFilterFactory
// check not really needed, since it is guarded in setStatusCode,
// but it's a good example
HttpStatus statusCode = exchange.getResponse().getStatusCode();
boolean isStatusCodeUpdated = setResponseStatus(exchange,
statusHolder);
boolean isStatusCodeUpdated = setResponseStatus(exchange, statusHolder);
if (isStatusCodeUpdated && originalStatusHeaderName != null) {
exchange.getResponse().getHeaders().set(originalStatusHeaderName,
singletonList(statusCode.value()).toString());
@@ -89,8 +86,8 @@ public class SetStatusGatewayFilterFactory
@Override
public String toString() {
return filterToStringCreator(SetStatusGatewayFilterFactory.this)
.append("status", config.getStatus()).toString();
return filterToStringCreator(SetStatusGatewayFilterFactory.this).append("status", config.getStatus())
.toString();
}
};
}

View File

@@ -51,8 +51,8 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.r
/**
* @author Ryan Baxter
*/
public abstract class SpringCloudCircuitBreakerFilterFactory extends
AbstractGatewayFilterFactory<SpringCloudCircuitBreakerFilterFactory.Config> {
public abstract class SpringCloudCircuitBreakerFilterFactory
extends AbstractGatewayFilterFactory<SpringCloudCircuitBreakerFilterFactory.Config> {
private ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory;
@@ -63,8 +63,7 @@ public abstract class SpringCloudCircuitBreakerFilterFactory extends
// do not use this dispatcherHandler directly, use getDispatcherHandler() instead.
private volatile DispatcherHandler dispatcherHandler;
public SpringCloudCircuitBreakerFilterFactory(
ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory,
public SpringCloudCircuitBreakerFilterFactory(ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory,
ObjectProvider<DispatcherHandler> dispatcherHandlerProvider) {
super(Config.class);
this.reactiveCircuitBreakerFactory = reactiveCircuitBreakerFactory;
@@ -87,15 +86,13 @@ public abstract class SpringCloudCircuitBreakerFilterFactory extends
@Override
public GatewayFilter apply(Config config) {
ReactiveCircuitBreaker cb = reactiveCircuitBreakerFactory.create(config.getId());
Set<HttpStatus> statuses = config.getStatusCodes().stream()
.map(HttpStatusHolder::parse)
.filter(statusHolder -> statusHolder.getHttpStatus() != null)
.map(HttpStatusHolder::getHttpStatus).collect(Collectors.toSet());
Set<HttpStatus> statuses = config.getStatusCodes().stream().map(HttpStatusHolder::parse)
.filter(statusHolder -> statusHolder.getHttpStatus() != null).map(HttpStatusHolder::getHttpStatus)
.collect(Collectors.toSet());
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return cb.run(chain.filter(exchange).doOnSuccess(v -> {
if (statuses.contains(exchange.getResponse().getStatusCode())) {
HttpStatus status = exchange.getResponse().getStatusCode();
@@ -112,9 +109,8 @@ public abstract class SpringCloudCircuitBreakerFilterFactory extends
URI uri = exchange.getRequest().getURI();
// TODO: assume always?
boolean encoded = containsEncodedParts(uri);
URI requestUrl = UriComponentsBuilder.fromUri(uri).host(null)
.port(null).uri(config.getFallbackUri()).scheme(null)
.build(encoded).toUri();
URI requestUrl = UriComponentsBuilder.fromUri(uri).host(null).port(null)
.uri(config.getFallbackUri()).scheme(null).build(encoded).toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
addExceptionDetails(t, exchange);
@@ -123,18 +119,15 @@ public abstract class SpringCloudCircuitBreakerFilterFactory extends
// is to another route in the Gateway
removeAlreadyRouted(exchange);
ServerHttpRequest request = exchange.getRequest().mutate()
.uri(requestUrl).build();
return getDispatcherHandler()
.handle(exchange.mutate().request(request).build());
ServerHttpRequest request = exchange.getRequest().mutate().uri(requestUrl).build();
return getDispatcherHandler().handle(exchange.mutate().request(request).build());
}).onErrorResume(t -> handleErrorWithoutFallback(t));
}
@Override
public String toString() {
return filterToStringCreator(SpringCloudCircuitBreakerFilterFactory.this)
.append("name", config.getName())
.append("fallback", config.fallbackUri).toString();
.append("name", config.getName()).append("fallback", config.fallbackUri).toString();
}
};
}
@@ -142,8 +135,8 @@ public abstract class SpringCloudCircuitBreakerFilterFactory extends
protected abstract Mono<Void> handleErrorWithoutFallback(Throwable t);
private void addExceptionDetails(Throwable t, ServerWebExchange exchange) {
ofNullable(t).ifPresent(exception -> exchange.getAttributes()
.put(CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR, exception));
ofNullable(t).ifPresent(
exception -> exchange.getAttributes().put(CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR, exception));
}
@Override

View File

@@ -29,8 +29,7 @@ import org.springframework.web.server.ResponseStatusException;
/**
* @author Ryan Baxter
*/
public class SpringCloudCircuitBreakerResilience4JFilterFactory
extends SpringCloudCircuitBreakerFilterFactory {
public class SpringCloudCircuitBreakerResilience4JFilterFactory extends SpringCloudCircuitBreakerFilterFactory {
public SpringCloudCircuitBreakerResilience4JFilterFactory(
ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory,
@@ -41,8 +40,7 @@ public class SpringCloudCircuitBreakerResilience4JFilterFactory
@Override
protected Mono<Void> handleErrorWithoutFallback(Throwable t) {
if (java.util.concurrent.TimeoutException.class.isInstance(t)) {
return Mono.error(new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT,
t.getMessage(), t));
return Mono.error(new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT, t.getMessage(), t));
}
if (CallNotPermittedException.class.isInstance(t)) {
return Mono.error(new ServiceUnavailableException());

View File

@@ -59,27 +59,24 @@ public class StripPrefixGatewayFilterFactory
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
addOriginalRequestUrl(exchange, request.getURI());
String path = request.getURI().getRawPath();
String newPath = "/"
+ Arrays.stream(StringUtils.tokenizeToStringArray(path, "/"))
.skip(config.parts).collect(Collectors.joining("/"));
String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(path, "/")).skip(config.parts)
.collect(Collectors.joining("/"));
newPath += (newPath.length() > 1 && path.endsWith("/") ? "/" : "");
ServerHttpRequest newRequest = request.mutate().path(newPath).build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR,
newRequest.getURI());
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
return chain.filter(exchange.mutate().request(newRequest).build());
}
@Override
public String toString() {
return filterToStringCreator(StripPrefixGatewayFilterFactory.this)
.append("parts", config.getParts()).toString();
return filterToStringCreator(StripPrefixGatewayFilterFactory.this).append("parts", config.getParts())
.toString();
}
};
}

View File

@@ -40,8 +40,8 @@ public class CachedBodyOutputMessage implements ReactiveHttpOutputMessage {
private boolean cached = false;
private Flux<DataBuffer> body = Flux.error(new IllegalStateException(
"The body is not set. " + "Did handling complete with success?"));
private Flux<DataBuffer> body = Flux
.error(new IllegalStateException("The body is not set. " + "Did handling complete with success?"));
public CachedBodyOutputMessage(ServerWebExchange exchange, HttpHeaders httpHeaders) {
this.bufferFactory = exchange.getResponse().bufferFactory();
@@ -87,8 +87,7 @@ public class CachedBodyOutputMessage implements ReactiveHttpOutputMessage {
}
@Override
public Mono<Void> writeAndFlushWith(
Publisher<? extends Publisher<? extends DataBuffer>> body) {
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return writeWith(Flux.from(body).flatMap(p -> p));
}

View File

@@ -43,8 +43,8 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
/**
* GatewayFilter that modifies the request body.
*/
public class ModifyRequestBodyGatewayFilterFactory extends
AbstractGatewayFilterFactory<ModifyRequestBodyGatewayFilterFactory.Config> {
public class ModifyRequestBodyGatewayFilterFactory
extends AbstractGatewayFilterFactory<ModifyRequestBodyGatewayFilterFactory.Config> {
private final List<HttpMessageReader<?>> messageReaders;
@@ -53,8 +53,7 @@ public class ModifyRequestBodyGatewayFilterFactory extends
this.messageReaders = HandlerStrategies.withDefaults().messageReaders();
}
public ModifyRequestBodyGatewayFilterFactory(
List<HttpMessageReader<?>> messageReaders) {
public ModifyRequestBodyGatewayFilterFactory(List<HttpMessageReader<?>> messageReaders) {
super(Config.class);
this.messageReaders = messageReaders;
}
@@ -64,21 +63,16 @@ public class ModifyRequestBodyGatewayFilterFactory extends
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Class inClass = config.getInClass();
ServerRequest serverRequest = ServerRequest.create(exchange,
messageReaders);
ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);
// TODO: flux or mono
Mono<?> modifiedBody = serverRequest.bodyToMono(inClass)
.flatMap(originalBody -> config.getRewriteFunction()
.apply(exchange, originalBody))
.switchIfEmpty(Mono.defer(() -> (Mono) config.getRewriteFunction()
.apply(exchange, null)));
.flatMap(originalBody -> config.getRewriteFunction().apply(exchange, originalBody))
.switchIfEmpty(Mono.defer(() -> (Mono) config.getRewriteFunction().apply(exchange, null)));
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody,
config.getOutClass());
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, config.getOutClass());
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
@@ -91,35 +85,29 @@ public class ModifyRequestBodyGatewayFilterFactory extends
if (config.getContentType() != null) {
headers.set(HttpHeaders.CONTENT_TYPE, config.getContentType());
}
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(
exchange, headers);
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
return bodyInserter.insert(outputMessage, new BodyInserterContext())
// .log("modify_request", Level.INFO)
.then(Mono.defer(() -> {
ServerHttpRequest decorator = decorate(exchange, headers,
outputMessage);
return chain
.filter(exchange.mutate().request(decorator).build());
})).onErrorResume(
(Function<Throwable, Mono<Void>>) throwable -> release(
exchange, outputMessage, throwable));
ServerHttpRequest decorator = decorate(exchange, headers, outputMessage);
return chain.filter(exchange.mutate().request(decorator).build());
})).onErrorResume((Function<Throwable, Mono<Void>>) throwable -> release(exchange,
outputMessage, throwable));
}
@Override
public String toString() {
return filterToStringCreator(ModifyRequestBodyGatewayFilterFactory.this)
.append("Content type", config.getContentType())
.append("In class", config.getInClass())
.append("Content type", config.getContentType()).append("In class", config.getInClass())
.append("Out class", config.getOutClass()).toString();
}
};
}
protected Mono<Void> release(ServerWebExchange exchange,
CachedBodyOutputMessage outputMessage, Throwable throwable) {
protected Mono<Void> release(ServerWebExchange exchange, CachedBodyOutputMessage outputMessage,
Throwable throwable) {
if (outputMessage.isCached()) {
return outputMessage.getBody().map(DataBufferUtils::release)
.then(Mono.error(throwable));
return outputMessage.getBody().map(DataBufferUtils::release).then(Mono.error(throwable));
}
return Mono.error(throwable);
}

View File

@@ -52,8 +52,8 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.O
/**
* GatewayFilter that modifies the response body.
*/
public class ModifyResponseBodyGatewayFilterFactory extends
AbstractGatewayFilterFactory<ModifyResponseBodyGatewayFilterFactory.Config> {
public class ModifyResponseBodyGatewayFilterFactory
extends AbstractGatewayFilterFactory<ModifyResponseBodyGatewayFilterFactory.Config> {
private final Map<String, MessageBodyDecoder> messageBodyDecoders;
@@ -61,10 +61,8 @@ public class ModifyResponseBodyGatewayFilterFactory extends
private final List<HttpMessageReader<?>> messageReaders;
public ModifyResponseBodyGatewayFilterFactory(
List<HttpMessageReader<?>> messageReaders,
Set<MessageBodyDecoder> messageBodyDecoders,
Set<MessageBodyEncoder> messageBodyEncoders) {
public ModifyResponseBodyGatewayFilterFactory(List<HttpMessageReader<?>> messageReaders,
Set<MessageBodyDecoder> messageBodyDecoders, Set<MessageBodyEncoder> messageBodyEncoders) {
super(Config.class);
this.messageReaders = messageReaders;
this.messageBodyDecoders = messageBodyDecoders.stream()
@@ -75,8 +73,7 @@ public class ModifyResponseBodyGatewayFilterFactory extends
@Override
public GatewayFilter apply(Config config) {
ModifyResponseGatewayFilter gatewayFilter = new ModifyResponseGatewayFilter(
config);
ModifyResponseGatewayFilter gatewayFilter = new ModifyResponseGatewayFilter(config);
gatewayFilter.setFactory(this);
return gatewayFilter;
}
@@ -171,8 +168,7 @@ public class ModifyResponseBodyGatewayFilterFactory extends
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return chain.filter(exchange.mutate()
.response(new ModifiedServerHttpResponse(exchange, config)).build());
return chain.filter(exchange.mutate().response(new ModifiedServerHttpResponse(exchange, config)).build());
}
@Override
@@ -182,12 +178,9 @@ public class ModifyResponseBodyGatewayFilterFactory extends
@Override
public String toString() {
Object obj = (this.gatewayFilterFactory != null) ? this.gatewayFilterFactory
: this;
return filterToStringCreator(obj)
.append("New content type", config.getNewContentType())
.append("In class", config.getInClass())
.append("Out class", config.getOutClass()).toString();
Object obj = (this.gatewayFilterFactory != null) ? this.gatewayFilterFactory : this;
return filterToStringCreator(obj).append("New content type", config.getNewContentType())
.append("In class", config.getInClass()).append("Out class", config.getOutClass()).toString();
}
public void setFactory(GatewayFilterFactory<Config> gatewayFilterFactory) {
@@ -215,8 +208,7 @@ public class ModifyResponseBodyGatewayFilterFactory extends
Class inClass = config.getInClass();
Class outClass = config.getOutClass();
String originalResponseContentType = exchange
.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
HttpHeaders httpHeaders = new HttpHeaders();
// explicitly add it in this way instead of
// 'httpHeaders.setContentType(originalResponseContentType)'
@@ -228,62 +220,48 @@ public class ModifyResponseBodyGatewayFilterFactory extends
// TODO: flux or mono
Mono modifiedBody = extractBody(exchange, clientResponse, inClass)
.flatMap(originalBody -> config.getRewriteFunction().apply(exchange,
originalBody))
.switchIfEmpty(Mono.defer(() -> (Mono) config.getRewriteFunction()
.apply(exchange, null)));
.flatMap(originalBody -> config.getRewriteFunction().apply(exchange, originalBody))
.switchIfEmpty(Mono.defer(() -> (Mono) config.getRewriteFunction().apply(exchange, null)));
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody,
outClass);
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, outClass);
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange,
exchange.getResponse().getHeaders());
return bodyInserter.insert(outputMessage, new BodyInserterContext())
.then(Mono.defer(() -> {
Mono<DataBuffer> messageBody = writeBody(getDelegate(),
outputMessage, outClass);
HttpHeaders headers = getDelegate().getHeaders();
if (!headers.containsKey(HttpHeaders.TRANSFER_ENCODING)
|| headers.containsKey(HttpHeaders.CONTENT_LENGTH)) {
messageBody = messageBody.doOnNext(data -> headers
.setContentLength(data.readableByteCount()));
}
// TODO: fail if isStreamingMediaType?
return getDelegate().writeWith(messageBody);
}));
return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
Mono<DataBuffer> messageBody = writeBody(getDelegate(), outputMessage, outClass);
HttpHeaders headers = getDelegate().getHeaders();
if (!headers.containsKey(HttpHeaders.TRANSFER_ENCODING)
|| headers.containsKey(HttpHeaders.CONTENT_LENGTH)) {
messageBody = messageBody.doOnNext(data -> headers.setContentLength(data.readableByteCount()));
}
// TODO: fail if isStreamingMediaType?
return getDelegate().writeWith(messageBody);
}));
}
@Override
public Mono<Void> writeAndFlushWith(
Publisher<? extends Publisher<? extends DataBuffer>> body) {
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return writeWith(Flux.from(body).flatMapSequential(p -> p));
}
private ClientResponse prepareClientResponse(Publisher<? extends DataBuffer> body,
HttpHeaders httpHeaders) {
private ClientResponse prepareClientResponse(Publisher<? extends DataBuffer> body, HttpHeaders httpHeaders) {
ClientResponse.Builder builder;
builder = ClientResponse.create(exchange.getResponse().getStatusCode(),
messageReaders);
return builder.headers(headers -> headers.putAll(httpHeaders))
.body(Flux.from(body)).build();
builder = ClientResponse.create(exchange.getResponse().getStatusCode(), messageReaders);
return builder.headers(headers -> headers.putAll(httpHeaders)).body(Flux.from(body)).build();
}
private <T> Mono<T> extractBody(ServerWebExchange exchange,
ClientResponse clientResponse, Class<T> inClass) {
private <T> Mono<T> extractBody(ServerWebExchange exchange, ClientResponse clientResponse, Class<T> inClass) {
// if inClass is byte[] then just return body, otherwise check if
// decoding required
if (byte[].class.isAssignableFrom(inClass)) {
return clientResponse.bodyToMono(inClass);
}
List<String> encodingHeaders = exchange.getResponse().getHeaders()
.getOrEmpty(HttpHeaders.CONTENT_ENCODING);
List<String> encodingHeaders = exchange.getResponse().getHeaders().getOrEmpty(HttpHeaders.CONTENT_ENCODING);
for (String encoding : encodingHeaders) {
MessageBodyDecoder decoder = messageBodyDecoders.get(encoding);
if (decoder != null) {
return clientResponse.bodyToMono(byte[].class)
.publishOn(Schedulers.parallel()).map(decoder::decode)
.map(bytes -> exchange.getResponse().bufferFactory()
.wrap(bytes))
return clientResponse.bodyToMono(byte[].class).publishOn(Schedulers.parallel()).map(decoder::decode)
.map(bytes -> exchange.getResponse().bufferFactory().wrap(bytes))
.map(buffer -> prepareClientResponse(Mono.just(buffer),
exchange.getResponse().getHeaders()))
.flatMap(response -> response.bodyToMono(inClass));
@@ -293,15 +271,14 @@ public class ModifyResponseBodyGatewayFilterFactory extends
return clientResponse.bodyToMono(inClass);
}
private Mono<DataBuffer> writeBody(ServerHttpResponse httpResponse,
CachedBodyOutputMessage message, Class<?> outClass) {
private Mono<DataBuffer> writeBody(ServerHttpResponse httpResponse, CachedBodyOutputMessage message,
Class<?> outClass) {
Mono<DataBuffer> response = DataBufferUtils.join(message.getBody());
if (byte[].class.isAssignableFrom(outClass)) {
return response;
}
List<String> encodingHeaders = httpResponse.getHeaders()
.getOrEmpty(HttpHeaders.CONTENT_ENCODING);
List<String> encodingHeaders = httpResponse.getHeaders().getOrEmpty(HttpHeaders.CONTENT_ENCODING);
for (String encoding : encodingHeaders) {
MessageBodyEncoder encoder = messageBodyEncoders.get(encoding);
if (encoder != null) {

View File

@@ -28,7 +28,6 @@ import org.springframework.web.server.ServerWebExchange;
* @param <T> the type of the first argument to the function
* @param <R> the type of element signaled by the {@link Publisher}
*/
public interface RewriteFunction<T, R>
extends BiFunction<ServerWebExchange, T, Publisher<R>> {
public interface RewriteFunction<T, R> extends BiFunction<ServerWebExchange, T, Publisher<R>> {
}

View File

@@ -69,8 +69,7 @@ public class ForwardedHeadersFilter implements HttpHeadersFilter, Ordered {
}
@Nullable
/* for testing */ static LinkedCaseInsensitiveMap<String> splitIntoCaseInsensitiveMap(
String[] pairs) {
/* for testing */ static LinkedCaseInsensitiveMap<String> splitIntoCaseInsensitiveMap(String[] pairs) {
if (ObjectUtils.isEmpty(pairs)) {
return null;
}
@@ -98,8 +97,7 @@ public class ForwardedHeadersFilter implements HttpHeadersFilter, Ordered {
HttpHeaders updated = new HttpHeaders();
// copy all headers except Forwarded
original.entrySet().stream().filter(
entry -> !entry.getKey().toLowerCase().equalsIgnoreCase(FORWARDED_HEADER))
original.entrySet().stream().filter(entry -> !entry.getKey().toLowerCase().equalsIgnoreCase(FORWARDED_HEADER))
.forEach(entry -> updated.addAll(entry.getKey(), entry.getValue()));
List<Forwarded> forwardeds = parse(original.get(FORWARDED_HEADER));
@@ -111,8 +109,7 @@ public class ForwardedHeadersFilter implements HttpHeadersFilter, Ordered {
// TODO: add new forwarded
URI uri = request.getURI();
String host = original.getFirst(HttpHeaders.HOST);
Forwarded forwarded = new Forwarded().put("host", host).put("proto",
uri.getScheme());
Forwarded forwarded = new Forwarded().put("host", host).put("proto", uri.getScheme());
InetSocketAddress remoteAddress = request.getRemoteAddress();
if (remoteAddress != null) {

View File

@@ -23,23 +23,20 @@ import org.springframework.web.server.ServerWebExchange;
public interface HttpHeadersFilter {
static HttpHeaders filterRequest(List<HttpHeadersFilter> filters,
ServerWebExchange exchange) {
static HttpHeaders filterRequest(List<HttpHeadersFilter> filters, ServerWebExchange exchange) {
HttpHeaders headers = exchange.getRequest().getHeaders();
return filter(filters, headers, exchange, Type.REQUEST);
}
static HttpHeaders filter(List<HttpHeadersFilter> filters, HttpHeaders input,
ServerWebExchange exchange, Type type) {
static HttpHeaders filter(List<HttpHeadersFilter> filters, HttpHeaders input, ServerWebExchange exchange,
Type type) {
HttpHeaders response = input;
if (filters != null) {
HttpHeaders reduce = filters.stream()
.filter(headersFilter -> headersFilter.supports(type)).reduce(input,
(headers, filter) -> filter.filter(headers, exchange),
(httpHeaders, httpHeaders2) -> {
httpHeaders.addAll(httpHeaders2);
return httpHeaders;
});
HttpHeaders reduce = filters.stream().filter(headersFilter -> headersFilter.supports(type)).reduce(input,
(headers, filter) -> filter.filter(headers, exchange), (httpHeaders, httpHeaders2) -> {
httpHeaders.addAll(httpHeaders2);
return httpHeaders;
});
return reduce;
}

View File

@@ -32,9 +32,8 @@ public class RemoveHopByHopHeadersFilter implements HttpHeadersFilter, Ordered {
* Headers to remove as the result of applying the filter.
*/
public static final Set<String> HEADERS_REMOVED_ON_REQUEST = new HashSet<>(
Arrays.asList("connection", "keep-alive", "transfer-encoding", "te",
"trailer", "proxy-authorization", "proxy-authenticate",
"x-application-context", "upgrade"
Arrays.asList("connection", "keep-alive", "transfer-encoding", "te", "trailer", "proxy-authorization",
"proxy-authenticate", "x-application-context", "upgrade"
// these two are not listed in
// https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3
// "proxy-connection",
@@ -66,8 +65,7 @@ public class RemoveHopByHopHeadersFilter implements HttpHeadersFilter, Ordered {
public HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange) {
HttpHeaders filtered = new HttpHeaders();
input.entrySet().stream()
.filter(entry -> !this.headers.contains(entry.getKey().toLowerCase()))
input.entrySet().stream().filter(entry -> !this.headers.contains(entry.getKey().toLowerCase()))
.forEach(entry -> filtered.addAll(entry.getKey(), entry.getValue()));
return filtered;

View File

@@ -201,11 +201,9 @@ public class XForwardedHeadersFilter implements HttpHeadersFilter, Ordered {
HttpHeaders original = input;
HttpHeaders updated = new HttpHeaders();
original.entrySet().stream()
.forEach(entry -> updated.addAll(entry.getKey(), entry.getValue()));
original.entrySet().stream().forEach(entry -> updated.addAll(entry.getKey(), entry.getValue()));
if (isForEnabled() && request.getRemoteAddress() != null
&& request.getRemoteAddress().getAddress() != null) {
if (isForEnabled() && request.getRemoteAddress() != null && request.getRemoteAddress().getAddress() != null) {
String remoteAddr = request.getRemoteAddress().getAddress().getHostAddress();
write(updated, X_FORWARDED_FOR_HEADER, remoteAddr, isForAppend());
}
@@ -223,8 +221,7 @@ public class XForwardedHeadersFilter implements HttpHeadersFilter, Ordered {
// - see XForwardedHeadersFilterTests, so first get uris, then extract paths
// and remove one from another if it's the ending part.
LinkedHashSet<URI> originalUris = exchange
.getAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
LinkedHashSet<URI> originalUris = exchange.getAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
URI requestUri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
if (originalUris != null && requestUri != null) {
@@ -239,8 +236,7 @@ public class XForwardedHeadersFilter implements HttpHeadersFilter, Ordered {
String originalUriPath = stripTrailingSlash(originalUri);
String requestUriPath = stripTrailingSlash(requestUri);
updateRequest(updated, originalUri, originalUriPath,
requestUriPath);
updateRequest(updated, originalUri, originalUriPath, requestUriPath);
}
});
@@ -263,13 +259,11 @@ public class XForwardedHeadersFilter implements HttpHeadersFilter, Ordered {
return updated;
}
private void updateRequest(HttpHeaders updated, URI originalUri,
String originalUriPath, String requestUriPath) {
private void updateRequest(HttpHeaders updated, URI originalUri, String originalUriPath, String requestUriPath) {
String prefix;
if (requestUriPath != null && (originalUriPath.endsWith(requestUriPath))) {
prefix = substringBeforeLast(originalUriPath, requestUriPath);
if (prefix != null && prefix.length() > 0
&& prefix.length() <= originalUri.getPath().length()) {
if (prefix != null && prefix.length() > 0 && prefix.length() <= originalUri.getPath().length()) {
write(updated, X_FORWARDED_PREFIX_HEADER, prefix, isPrefixAppend());
}
}

View File

@@ -58,24 +58,20 @@ public abstract class AbstractRateLimiter<C> extends AbstractStatefulConfigurabl
C routeConfig = newConfig();
if (this.configurationService != null) {
this.configurationService.with(routeConfig)
.name(this.configurationPropertyName).normalizedProperties(args)
this.configurationService.with(routeConfig).name(this.configurationPropertyName).normalizedProperties(args)
.bind();
}
getConfig().put(routeId, routeConfig);
}
private boolean hasRelevantKey(Map<String, Object> args) {
return args.keySet().stream()
.anyMatch(key -> key.startsWith(configurationPropertyName + "."));
return args.keySet().stream().anyMatch(key -> key.startsWith(configurationPropertyName + "."));
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("configurationPropertyName", configurationPropertyName)
.append("config", getConfig()).append("configClass", getConfigClass())
.toString();
return new ToStringCreator(this).append("configurationPropertyName", configurationPropertyName)
.append("config", getConfig()).append("configClass", getConfigClass()).toString();
}
}

View File

@@ -52,8 +52,7 @@ import org.springframework.validation.annotation.Validated;
* @author Denis Cutic
*/
@ConfigurationProperties("spring.cloud.gateway.redis-rate-limiter")
public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Config>
implements ApplicationContextAware {
public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Config> implements ApplicationContextAware {
/**
* Redis Rate Limiter property name.
@@ -117,8 +116,8 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
/** The name of the header that returns the requested tokens configuration. */
private String requestedTokensHeader = REQUESTED_TOKENS_HEADER;
public RedisRateLimiter(ReactiveStringRedisTemplate redisTemplate,
RedisScript<List<Long>> script, ConfigurationService configurationService) {
public RedisRateLimiter(ReactiveStringRedisTemplate redisTemplate, RedisScript<List<Long>> script,
ConfigurationService configurationService) {
super(Config.class, CONFIGURATION_PROPERTY_NAME, configurationService);
this.redisTemplate = redisTemplate;
this.script = script;
@@ -133,8 +132,7 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
*/
public RedisRateLimiter(int defaultReplenishRate, int defaultBurstCapacity) {
super(Config.class, CONFIGURATION_PROPERTY_NAME, (ConfigurationService) null);
this.defaultConfig = new Config().setReplenishRate(defaultReplenishRate)
.setBurstCapacity(defaultBurstCapacity);
this.defaultConfig = new Config().setReplenishRate(defaultReplenishRate).setBurstCapacity(defaultBurstCapacity);
}
/**
@@ -144,8 +142,7 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
* algorithm.
* @param defaultRequestedTokens how many tokens are requested per request.
*/
public RedisRateLimiter(int defaultReplenishRate, int defaultBurstCapacity,
int defaultRequestedTokens) {
public RedisRateLimiter(int defaultReplenishRate, int defaultBurstCapacity, int defaultRequestedTokens) {
this(defaultReplenishRate, defaultBurstCapacity);
this.defaultConfig.setRequestedTokens(defaultRequestedTokens);
}
@@ -253,12 +250,10 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
List<String> keys = getKeys(id);
// The arguments to the LUA script. time() returns unixtime in seconds.
List<String> scriptArgs = Arrays.asList(replenishRate + "",
burstCapacity + "", Instant.now().getEpochSecond() + "",
requestedTokens + "");
List<String> scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "",
Instant.now().getEpochSecond() + "", requestedTokens + "");
// allowed, tokens_left = redis.eval(SCRIPT, keys, args)
Flux<List<Long>> flux = this.redisTemplate.execute(this.script, keys,
scriptArgs);
Flux<List<Long>> flux = this.redisTemplate.execute(this.script, keys, scriptArgs);
// .log("redisratelimiter", Level.FINER);
return flux.onErrorResume(throwable -> {
if (log.isDebugEnabled()) {
@@ -272,8 +267,7 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
boolean allowed = results.get(0) == 1L;
Long tokensLeft = results.get(1);
Response response = new Response(allowed,
getHeaders(routeConfig, tokensLeft));
Response response = new Response(allowed, getHeaders(routeConfig, tokensLeft));
if (log.isDebugEnabled()) {
log.debug("response: " + response);
@@ -300,8 +294,7 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
}
if (routeConfig == null) {
throw new IllegalArgumentException(
"No Configuration found for route " + routeId + " or defaultFilters");
throw new IllegalArgumentException("No Configuration found for route " + routeId + " or defaultFilters");
}
return routeConfig;
}
@@ -311,12 +304,9 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
Map<String, String> headers = new HashMap<>();
if (isIncludeHeaders()) {
headers.put(this.remainingHeader, tokensLeft.toString());
headers.put(this.replenishRateHeader,
String.valueOf(config.getReplenishRate()));
headers.put(this.burstCapacityHeader,
String.valueOf(config.getBurstCapacity()));
headers.put(this.requestedTokensHeader,
String.valueOf(config.getRequestedTokens()));
headers.put(this.replenishRateHeader, String.valueOf(config.getReplenishRate()));
headers.put(this.burstCapacityHeader, String.valueOf(config.getBurstCapacity()));
headers.put(this.requestedTokensHeader, String.valueOf(config.getRequestedTokens()));
}
return headers;
}
@@ -363,8 +353,7 @@ public class RedisRateLimiter extends AbstractRateLimiter<RedisRateLimiter.Confi
@Override
public String toString() {
return new ToStringCreator(this).append("replenishRate", replenishRate)
.append("burstCapacity", burstCapacity)
.append("requestedTokens", requestedTokens).toString();
.append("burstCapacity", burstCapacity).append("requestedTokens", requestedTokens).toString();
}

View File

@@ -47,8 +47,7 @@ public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {
return new OrAsyncPredicate<>(this, other);
}
static AsyncPredicate<ServerWebExchange> from(
Predicate<? super ServerWebExchange> predicate) {
static AsyncPredicate<ServerWebExchange> from(Predicate<? super ServerWebExchange> predicate) {
return new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate));
}
@@ -99,8 +98,7 @@ public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {
private final AsyncPredicate<? super T> right;
public AndAsyncPredicate(AsyncPredicate<? super T> left,
AsyncPredicate<? super T> right) {
public AndAsyncPredicate(AsyncPredicate<? super T> left, AsyncPredicate<? super T> right) {
Assert.notNull(left, "Left AsyncPredicate must not be null");
Assert.notNull(right, "Right AsyncPredicate must not be null");
this.left = left;
@@ -109,8 +107,7 @@ public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {
@Override
public Publisher<Boolean> apply(T t) {
return Mono.from(left.apply(t)).flatMap(
result -> !result ? Mono.just(false) : Mono.from(right.apply(t)));
return Mono.from(left.apply(t)).flatMap(result -> !result ? Mono.just(false) : Mono.from(right.apply(t)));
}
@Override
@@ -126,8 +123,7 @@ public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {
private final AsyncPredicate<? super T> right;
public OrAsyncPredicate(AsyncPredicate<? super T> left,
AsyncPredicate<? super T> right) {
public OrAsyncPredicate(AsyncPredicate<? super T> left, AsyncPredicate<? super T> right) {
Assert.notNull(left, "Left AsyncPredicate must not be null");
Assert.notNull(right, "Right AsyncPredicate must not be null");
this.left = left;
@@ -136,8 +132,7 @@ public interface AsyncPredicate<T> extends Function<T, Publisher<Boolean>> {
@Override
public Publisher<Boolean> apply(T t) {
return Mono.from(left.apply(t)).flatMap(
result -> result ? Mono.just(true) : Mono.from(right.apply(t)));
return Mono.from(left.apply(t)).flatMap(result -> result ? Mono.just(true) : Mono.from(right.apply(t)));
}
@Override

View File

@@ -113,8 +113,7 @@ public class FilteringWebHandler implements WebHandler {
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this,
this.index + 1);
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
return filter.filter(exchange, chain);
}
else {

View File

@@ -48,9 +48,8 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
private final ManagementPortType managementPortType;
public RoutePredicateHandlerMapping(FilteringWebHandler webHandler,
RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties,
Environment environment) {
public RoutePredicateHandlerMapping(FilteringWebHandler webHandler, RouteLocator routeLocator,
GlobalCorsProperties globalCorsProperties, Environment environment) {
this.webHandler = webHandler;
this.routeLocator = routeLocator;
@@ -65,10 +64,8 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
if (this.managementPort != null && this.managementPort < 0) {
return DISABLED;
}
return ((this.managementPort == null
|| (serverPort == null && this.managementPort.equals(8080))
|| (this.managementPort != 0 && this.managementPort.equals(serverPort)))
? SAME : DIFFERENT);
return ((this.managementPort == null || (serverPort == null && this.managementPort.equals(8080))
|| (this.managementPort != 0 && this.managementPort.equals(serverPort))) ? SAME : DIFFERENT);
}
private static Integer getPortProperty(Environment environment, String prefix) {
@@ -89,8 +86,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
.flatMap((Function<Route, Mono<?>>) r -> {
exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
if (logger.isDebugEnabled()) {
logger.debug(
"Mapping [" + getExchangeDesc(exchange) + "] to " + r);
logger.debug("Mapping [" + getExchangeDesc(exchange) + "] to " + r);
}
exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, r);
@@ -98,15 +94,13 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
}).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
exchange.getAttributes().remove(GATEWAY_PREDICATE_ROUTE_ATTR);
if (logger.isTraceEnabled()) {
logger.trace("No RouteDefinition found for ["
+ getExchangeDesc(exchange) + "]");
logger.trace("No RouteDefinition found for [" + getExchangeDesc(exchange) + "]");
}
})));
}
@Override
protected CorsConfiguration getCorsConfiguration(Object handler,
ServerWebExchange exchange) {
protected CorsConfiguration getCorsConfiguration(Object handler, ServerWebExchange exchange) {
// TODO: support cors configuration via properties on a route see gh-229
// see RequestMappingHandlerMapping.initCorsConfiguration()
// also see
@@ -135,9 +129,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
})
// instead of immediately stopping main flux due to error, log and
// swallow it
.doOnError(e -> logger.error(
"Error applying predicate for route: " + route.getId(),
e))
.doOnError(e -> logger.error("Error applying predicate for route: " + route.getId(), e))
.onErrorResume(e -> Mono.empty()))
// .defaultIfEmpty() put a static Route not found
// or .switchIfEmpty()

View File

@@ -28,8 +28,7 @@ import org.springframework.web.server.ServerWebExchange;
/**
* @author Spencer Gibb
*/
public class AfterRoutePredicateFactory
extends AbstractRoutePredicateFactory<AfterRoutePredicateFactory.Config> {
public class AfterRoutePredicateFactory extends AbstractRoutePredicateFactory<AfterRoutePredicateFactory.Config> {
/**
* DateTime key.

View File

@@ -26,8 +26,7 @@ import org.springframework.web.server.ServerWebExchange;
/**
* @author Spencer Gibb
*/
public class BeforeRoutePredicateFactory
extends AbstractRoutePredicateFactory<BeforeRoutePredicateFactory.Config> {
public class BeforeRoutePredicateFactory extends AbstractRoutePredicateFactory<BeforeRoutePredicateFactory.Config> {
/**
* DateTime key.

View File

@@ -30,8 +30,7 @@ import org.springframework.web.server.ServerWebExchange;
/**
* @author Spencer Gibb
*/
public class BetweenRoutePredicateFactory
extends AbstractRoutePredicateFactory<BetweenRoutePredicateFactory.Config> {
public class BetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<BetweenRoutePredicateFactory.Config> {
/**
* DateTime 1 key.
@@ -61,14 +60,12 @@ public class BetweenRoutePredicateFactory
@Override
public boolean test(ServerWebExchange serverWebExchange) {
final ZonedDateTime now = ZonedDateTime.now();
return now.isAfter(config.getDatetime1())
&& now.isBefore(config.getDatetime2());
return now.isAfter(config.getDatetime1()) && now.isBefore(config.getDatetime2());
}
@Override
public String toString() {
return String.format("Between: %s and %s", config.getDatetime1(),
config.getDatetime2());
return String.format("Between: %s and %s", config.getDatetime1(), config.getDatetime2());
}
};
}

View File

@@ -28,8 +28,7 @@ import org.springframework.web.server.ServerWebExchange;
* @see <a href="https://docs.cloudfoundry.org/services/route-services.html">Cloud Foundry
* Route Service documentation</a>
*/
public class CloudFoundryRouteServiceRoutePredicateFactory
extends AbstractRoutePredicateFactory<Object> {
public class CloudFoundryRouteServiceRoutePredicateFactory extends AbstractRoutePredicateFactory<Object> {
/**
* Forwarded URL header name.
@@ -54,8 +53,7 @@ public class CloudFoundryRouteServiceRoutePredicateFactory
@Override
public Predicate<ServerWebExchange> apply(Object unused) {
return headerPredicate(X_CF_FORWARDED_URL)
.and(headerPredicate(X_CF_PROXY_SIGNATURE))
return headerPredicate(X_CF_FORWARDED_URL).and(headerPredicate(X_CF_PROXY_SIGNATURE))
.and(headerPredicate(X_CF_PROXY_METADATA));
}

View File

@@ -29,8 +29,7 @@ import org.springframework.web.server.ServerWebExchange;
/**
* @author Spencer Gibb
*/
public class CookieRoutePredicateFactory
extends AbstractRoutePredicateFactory<CookieRoutePredicateFactory.Config> {
public class CookieRoutePredicateFactory extends AbstractRoutePredicateFactory<CookieRoutePredicateFactory.Config> {
/**
* Name key.
@@ -56,8 +55,7 @@ public class CookieRoutePredicateFactory
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
List<HttpCookie> cookies = exchange.getRequest().getCookies()
.get(config.name);
List<HttpCookie> cookies = exchange.getRequest().getCookies().get(config.name);
if (cookies == null) {
return false;
}
@@ -71,8 +69,7 @@ public class CookieRoutePredicateFactory
@Override
public String toString() {
return String.format("Cookie: name=%s regexp=%s", config.name,
config.regexp);
return String.format("Cookie: name=%s regexp=%s", config.name, config.regexp);
}
};
}

View File

@@ -30,8 +30,7 @@ import org.springframework.web.server.ServerWebExchange;
/**
* @author Spencer Gibb
*/
public class HeaderRoutePredicateFactory
extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {
public class HeaderRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {
/**
* Header key.
@@ -59,16 +58,15 @@ public class HeaderRoutePredicateFactory
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
List<String> values = exchange.getRequest().getHeaders()
.getOrDefault(config.header, Collections.emptyList());
List<String> values = exchange.getRequest().getHeaders().getOrDefault(config.header,
Collections.emptyList());
if (values.isEmpty()) {
return false;
}
// values is now guaranteed to not be empty
if (hasRegex) {
// check if a header value matches
return values.stream()
.anyMatch(value -> value.matches(config.regexp));
return values.stream().anyMatch(value -> value.matches(config.regexp));
}
// there is a value and since regexp is empty, we only check existence.
@@ -77,8 +75,7 @@ public class HeaderRoutePredicateFactory
@Override
public String toString() {
return String.format("Header: %s regexp=%s", config.header,
config.regexp);
return String.format("Header: %s regexp=%s", config.header, config.regexp);
}
};
}

View File

@@ -33,8 +33,7 @@ import org.springframework.web.server.ServerWebExchange;
/**
* @author Spencer Gibb
*/
public class HostRoutePredicateFactory
extends AbstractRoutePredicateFactory<HostRoutePredicateFactory.Config> {
public class HostRoutePredicateFactory extends AbstractRoutePredicateFactory<HostRoutePredicateFactory.Config> {
private PathMatcher pathMatcher = new AntPathMatcher(".");
@@ -66,8 +65,8 @@ public class HostRoutePredicateFactory
.filter(pattern -> pathMatcher.match(pattern, host)).findFirst();
if (optionalPattern.isPresent()) {
Map<String, String> variables = pathMatcher
.extractUriTemplateVariables(optionalPattern.get(), host);
Map<String, String> variables = pathMatcher.extractUriTemplateVariables(optionalPattern.get(),
host);
ServerWebExchangeUtils.putUriTemplateVariables(exchange, variables);
return true;
}

View File

@@ -30,8 +30,7 @@ import static java.util.Arrays.stream;
* @author Spencer Gibb
* @author Dennis Menge
*/
public class MethodRoutePredicateFactory
extends AbstractRoutePredicateFactory<MethodRoutePredicateFactory.Config> {
public class MethodRoutePredicateFactory extends AbstractRoutePredicateFactory<MethodRoutePredicateFactory.Config> {
/**
* Methods key.
@@ -58,8 +57,7 @@ public class MethodRoutePredicateFactory
@Override
public boolean test(ServerWebExchange exchange) {
HttpMethod requestMethod = exchange.getRequest().getMethod();
return stream(config.getMethods())
.anyMatch(httpMethod -> httpMethod == requestMethod);
return stream(config.getMethods()).anyMatch(httpMethod -> httpMethod == requestMethod);
}
@Override

View File

@@ -40,8 +40,7 @@ import static org.springframework.http.server.PathContainer.parsePath;
* @author Spencer Gibb
* @author Dhawal Kapil
*/
public class PathRoutePredicateFactory
extends AbstractRoutePredicateFactory<PathRoutePredicateFactory.Config> {
public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<PathRoutePredicateFactory.Config> {
private static final Log log = LogFactory.getLog(PathRoutePredicateFactory.class);
@@ -53,11 +52,10 @@ public class PathRoutePredicateFactory
super(Config.class);
}
private static void traceMatch(String prefix, Object desired, Object actual,
boolean match) {
private static void traceMatch(String prefix, Object desired, Object actual, boolean match) {
if (log.isTraceEnabled()) {
String message = String.format("%s \"%s\" %s against value \"%s\"", prefix,
desired, match ? "matches" : "does not match", actual);
String message = String.format("%s \"%s\" %s against value \"%s\"", prefix, desired,
match ? "matches" : "does not match", actual);
log.trace(message);
}
}
@@ -80,8 +78,7 @@ public class PathRoutePredicateFactory
public Predicate<ServerWebExchange> apply(Config config) {
final ArrayList<PathPattern> pathPatterns = new ArrayList<>();
synchronized (this.pathPatternParser) {
pathPatternParser
.setMatchOptionalTrailingSeparator(config.isMatchTrailingSlash());
pathPatternParser.setMatchOptionalTrailingSeparator(config.isMatchTrailingSlash());
config.getPatterns().forEach(pattern -> {
PathPattern pathPattern = this.pathPatternParser.parse(pattern);
pathPatterns.add(pathPattern);
@@ -90,8 +87,7 @@ public class PathRoutePredicateFactory
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
PathContainer path = parsePath(
exchange.getRequest().getURI().getRawPath());
PathContainer path = parsePath(exchange.getRequest().getURI().getRawPath());
Optional<PathPattern> optionalPathPattern = pathPatterns.stream()
.filter(pattern -> pattern.matches(path)).findFirst();
@@ -111,8 +107,8 @@ public class PathRoutePredicateFactory
@Override
public String toString() {
return String.format("Paths: %s, match trailing slash: %b",
config.getPatterns(), config.isMatchTrailingSlash());
return String.format("Paths: %s, match trailing slash: %b", config.getPatterns(),
config.isMatchTrailingSlash());
}
};
}
@@ -145,8 +141,7 @@ public class PathRoutePredicateFactory
* @deprecated use {@link #setMatchTrailingSlash(boolean)}
*/
@Deprecated
public Config setMatchOptionalTrailingSeparator(
boolean matchOptionalTrailingSeparator) {
public Config setMatchOptionalTrailingSeparator(boolean matchOptionalTrailingSeparator) {
setMatchTrailingSlash(matchOptionalTrailingSeparator);
return this;
}

View File

@@ -45,8 +45,8 @@ public class PredicateDefinition {
public PredicateDefinition(String text) {
int eqIdx = text.indexOf('=');
if (eqIdx <= 0) {
throw new ValidationException("Unable to parse PredicateDefinition text '"
+ text + "'" + ", must be of the form name=value");
throw new ValidationException(
"Unable to parse PredicateDefinition text '" + text + "'" + ", must be of the form name=value");
}
setName(text.substring(0, eqIdx));

View File

@@ -29,8 +29,7 @@ import org.springframework.web.server.ServerWebExchange;
/**
* @author Spencer Gibb
*/
public class QueryRoutePredicateFactory
extends AbstractRoutePredicateFactory<QueryRoutePredicateFactory.Config> {
public class QueryRoutePredicateFactory extends AbstractRoutePredicateFactory<QueryRoutePredicateFactory.Config> {
/**
* Param key.
@@ -58,12 +57,10 @@ public class QueryRoutePredicateFactory
public boolean test(ServerWebExchange exchange) {
if (!StringUtils.hasText(config.regexp)) {
// check existence of header
return exchange.getRequest().getQueryParams()
.containsKey(config.param);
return exchange.getRequest().getQueryParams().containsKey(config.param);
}
List<String> values = exchange.getRequest().getQueryParams()
.get(config.param);
List<String> values = exchange.getRequest().getQueryParams().get(config.param);
if (values == null) {
return false;
}
@@ -77,8 +74,7 @@ public class QueryRoutePredicateFactory
@Override
public String toString() {
return String.format("Query: param=%s regexp=%s", config.getParam(),
config.getRegexp());
return String.format("Query: param=%s regexp=%s", config.getParam(), config.getRegexp());
}
};
}

View File

@@ -37,8 +37,7 @@ import org.springframework.web.server.ServerWebExchange;
* The body is cached in memory so that possible subsequent calls to the predicate do not
* need to deserialize again.
*/
public class ReadBodyPredicateFactory
extends AbstractRoutePredicateFactory<ReadBodyPredicateFactory.Config> {
public class ReadBodyPredicateFactory extends AbstractRoutePredicateFactory<ReadBodyPredicateFactory.Config> {
protected static final Log log = LogFactory.getLog(ReadBodyPredicateFactory.class);
@@ -91,13 +90,10 @@ public class ReadBodyPredicateFactory
else {
return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange,
(serverHttpRequest) -> ServerRequest
.create(exchange.mutate().request(serverHttpRequest)
.build(), messageReaders)
.bodyToMono(inClass)
.doOnNext(objectValue -> exchange.getAttributes().put(
CACHE_REQUEST_BODY_OBJECT_KEY, objectValue))
.map(objectValue -> config.getPredicate()
.test(objectValue)));
.create(exchange.mutate().request(serverHttpRequest).build(), messageReaders)
.bodyToMono(inClass).doOnNext(objectValue -> exchange.getAttributes()
.put(CACHE_REQUEST_BODY_OBJECT_KEY, objectValue))
.map(objectValue -> config.getPredicate().test(objectValue)));
}
}
@@ -111,8 +107,7 @@ public class ReadBodyPredicateFactory
@Override
@SuppressWarnings("unchecked")
public Predicate<ServerWebExchange> apply(Config config) {
throw new UnsupportedOperationException(
"ReadBodyPredicateFactory is only async.");
throw new UnsupportedOperationException("ReadBodyPredicateFactory is only async.");
}
public static class Config {

View File

@@ -43,8 +43,7 @@ import static org.springframework.cloud.gateway.support.ShortcutConfigurable.Sho
public class RemoteAddrRoutePredicateFactory
extends AbstractRoutePredicateFactory<RemoteAddrRoutePredicateFactory.Config> {
private static final Log log = LogFactory
.getLog(RemoteAddrRoutePredicateFactory.class);
private static final Log log = LogFactory.getLog(RemoteAddrRoutePredicateFactory.class);
public RemoteAddrRoutePredicateFactory() {
super(Config.class);
@@ -76,15 +75,13 @@ public class RemoteAddrRoutePredicateFactory
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
InetSocketAddress remoteAddress = config.remoteAddressResolver
.resolve(exchange);
InetSocketAddress remoteAddress = config.remoteAddressResolver.resolve(exchange);
if (remoteAddress != null && remoteAddress.getAddress() != null) {
String hostAddress = remoteAddress.getAddress().getHostAddress();
String host = exchange.getRequest().getURI().getHost();
if (log.isDebugEnabled() && !hostAddress.equals(host)) {
log.debug("Remote addresses didn't match " + hostAddress + " != "
+ host);
log.debug("Remote addresses didn't match " + hostAddress + " != " + host);
}
for (IpSubnetFilterRule source : sources) {
@@ -113,8 +110,7 @@ public class RemoteAddrRoutePredicateFactory
String ipAddress = ipAddressCidrPrefix[0];
int cidrPrefix = Integer.parseInt(ipAddressCidrPrefix[1]);
sources.add(
new IpSubnetFilterRule(ipAddress, cidrPrefix, IpFilterRuleType.ACCEPT));
sources.add(new IpSubnetFilterRule(ipAddress, cidrPrefix, IpFilterRuleType.ACCEPT));
}
@Validated
@@ -141,8 +137,7 @@ public class RemoteAddrRoutePredicateFactory
return this;
}
public Config setRemoteAddressResolver(
RemoteAddressResolver remoteAddressResolver) {
public Config setRemoteAddressResolver(RemoteAddressResolver remoteAddressResolver) {
this.remoteAddressResolver = remoteAddressResolver;
return this;
}

View File

@@ -38,8 +38,7 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.W
* @author Spencer Gibb
*/
// TODO: make this a generic Choose out of group predicate?
public class WeightRoutePredicateFactory
extends AbstractRoutePredicateFactory<WeightConfig>
public class WeightRoutePredicateFactory extends AbstractRoutePredicateFactory<WeightConfig>
implements ApplicationEventPublisherAware {
/**
@@ -87,8 +86,7 @@ public class WeightRoutePredicateFactory
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
Map<String, String> weights = exchange.getAttributeOrDefault(WEIGHT_ATTR,
Collections.emptyMap());
Map<String, String> weights = exchange.getAttributeOrDefault(WEIGHT_ATTR, Collections.emptyMap());
String routeId = exchange.getAttribute(GATEWAY_PREDICATE_ROUTE_ATTR);
@@ -99,15 +97,14 @@ public class WeightRoutePredicateFactory
String chosenRoute = weights.get(group);
if (log.isTraceEnabled()) {
log.trace("in group weight: " + group + ", current route: "
+ routeId + ", chosen route: " + chosenRoute);
log.trace("in group weight: " + group + ", current route: " + routeId + ", chosen route: "
+ chosenRoute);
}
return routeId.equals(chosenRoute);
}
else if (log.isTraceEnabled()) {
log.trace("no weights found for group: " + group + ", current route: "
+ routeId);
log.trace("no weights found for group: " + group + ", current route: " + routeId);
}
return false;
@@ -115,8 +112,7 @@ public class WeightRoutePredicateFactory
@Override
public String toString() {
return String.format("Weight: %s %s", config.getGroup(),
config.getWeight());
return String.format("Weight: %s %s", config.getGroup(), config.getWeight());
}
};
}

View File

@@ -30,8 +30,7 @@ import org.springframework.context.ApplicationListener;
/**
* @author Spencer Gibb
*/
public class CachingRouteDefinitionLocator
implements RouteDefinitionLocator, ApplicationListener<RefreshRoutesEvent> {
public class CachingRouteDefinitionLocator implements RouteDefinitionLocator, ApplicationListener<RefreshRoutesEvent> {
private static final String CACHE_KEY = "routeDefs";
@@ -43,8 +42,7 @@ public class CachingRouteDefinitionLocator
public CachingRouteDefinitionLocator(RouteDefinitionLocator delegate) {
this.delegate = delegate;
routeDefinitions = CacheFlux.lookup(cache, CACHE_KEY, RouteDefinition.class)
.onCacheMissResume(this::fetch);
routeDefinitions = CacheFlux.lookup(cache, CACHE_KEY, RouteDefinition.class).onCacheMissResume(this::fetch);
}
private Flux<RouteDefinition> fetch() {
@@ -67,8 +65,7 @@ public class CachingRouteDefinitionLocator
@Override
public void onApplicationEvent(RefreshRoutesEvent event) {
fetch().materialize().collect(Collectors.toList())
.doOnNext(routes -> cache.put(CACHE_KEY, routes)).subscribe();
fetch().materialize().collect(Collectors.toList()).doOnNext(routes -> cache.put(CACHE_KEY, routes)).subscribe();
}
}

View File

@@ -37,8 +37,8 @@ import org.springframework.core.annotation.AnnotationAwareOrderComparator;
/**
* @author Spencer Gibb
*/
public class CachingRouteLocator implements Ordered, RouteLocator,
ApplicationListener<RefreshRoutesEvent>, ApplicationEventPublisherAware {
public class CachingRouteLocator
implements Ordered, RouteLocator, ApplicationListener<RefreshRoutesEvent>, ApplicationEventPublisherAware {
private static final Log log = LogFactory.getLog(CachingRouteLocator.class);
@@ -54,8 +54,7 @@ public class CachingRouteLocator implements Ordered, RouteLocator,
public CachingRouteLocator(RouteLocator delegate) {
this.delegate = delegate;
routes = CacheFlux.lookup(cache, CACHE_KEY, Route.class)
.onCacheMissResume(this::fetch);
routes = CacheFlux.lookup(cache, CACHE_KEY, Route.class).onCacheMissResume(this::fetch);
}
private Flux<Route> fetch() {
@@ -79,10 +78,9 @@ public class CachingRouteLocator implements Ordered, RouteLocator,
@Override
public void onApplicationEvent(RefreshRoutesEvent event) {
try {
fetch().collect(Collectors.toList()).subscribe(list -> Flux.fromIterable(list)
.materialize().collect(Collectors.toList()).subscribe(signals -> {
applicationEventPublisher
.publishEvent(new RefreshRoutesResultEvent(this));
fetch().collect(Collectors.toList()).subscribe(
list -> Flux.fromIterable(list).materialize().collect(Collectors.toList()).subscribe(signals -> {
applicationEventPublisher.publishEvent(new RefreshRoutesResultEvent(this));
cache.put(CACHE_KEY, signals);
}, throwable -> handleRefreshError(throwable)));
}
@@ -95,8 +93,7 @@ public class CachingRouteLocator implements Ordered, RouteLocator,
if (log.isErrorEnabled()) {
log.error("Refresh routes error !!!", throwable);
}
applicationEventPublisher
.publishEvent(new RefreshRoutesResultEvent(this, throwable));
applicationEventPublisher.publishEvent(new RefreshRoutesResultEvent(this, throwable));
}
@Override
@@ -105,8 +102,7 @@ public class CachingRouteLocator implements Ordered, RouteLocator,
}
@Override
public void setApplicationEventPublisher(
ApplicationEventPublisher applicationEventPublisher) {
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}

Some files were not shown because too many files have changed in this diff Show More