Cleanup deprecations and warnings

This commit is contained in:
spencergibb
2022-03-09 16:51:47 -05:00
parent b1c34a1521
commit 4154176b99
19 changed files with 170 additions and 152 deletions

View File

@@ -415,7 +415,7 @@ public class ProxyExchange<T> {
}
private String forwarded(URI uri, String hostHeader) {
if (!StringUtils.isEmpty(hostHeader)) {
if (StringUtils.hasText(hostHeader)) {
return "host=" + hostHeader;
}
if ("http".equals(uri.getScheme())) {
@@ -570,7 +570,7 @@ class ServletOutputToInputConverter extends HttpServletResponseWrapper {
@Override
public void write(int b) throws IOException {
builder.append(new Character((char) b));
builder.append(Character.valueOf((char) b));
}
@Override

View File

@@ -74,61 +74,61 @@ public class ProductionConfigurationTests {
private int port;
@Before
public void init() throws Exception {
application.setHome(new URI("http://localhost:" + port));
public void init() {
application.setHome(URI.create("http://localhost:" + port));
rest.getRestTemplate().setRequestFactory(new SimpleClientHttpRequestFactory());
}
@Test
public void get() throws Exception {
public void get() {
assertThat(rest.getForObject("/proxy/0", Foo.class).getName()).isEqualTo("bye");
}
@Test
public void path() throws Exception {
public void path() {
assertThat(rest.getForObject("/proxy/path/1", Foo.class).getName()).isEqualTo("foo");
}
@Test
public void resource() throws Exception {
public void resource() {
assertThat(rest.getForObject("/proxy/html/test.html", String.class)).contains("<body>Test");
}
@Test
public void resourceWithNoType() throws Exception {
public void resourceWithNoType() {
assertThat(rest.getForObject("/proxy/typeless/test.html", String.class)).contains("<body>Test");
}
@Test
public void missing() throws Exception {
public void missing() {
assertThat(rest.getForEntity("/proxy/missing/0", Foo.class).getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
}
@Test
public void uri() throws Exception {
public void uri() {
assertThat(rest.getForObject("/proxy/0", Foo.class).getName()).isEqualTo("bye");
}
@Test
public void post() throws Exception {
public void post() {
assertThat(rest.postForObject("/proxy/0", Collections.singletonMap("name", "foo"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foo");
}
@Test
public void forward() throws Exception {
public void forward() {
assertThat(rest.getForObject("/forward/foos/0", Foo.class).getName()).isEqualTo("bye");
}
@Test
public void forwardHeader() throws Exception {
public void forwardHeader() {
ResponseEntity<Foo> result = rest.getForEntity("/forward/special/foos/0", Foo.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody().getName()).isEqualTo("FOO");
}
@Test
public void postForwardHeader() throws Exception {
public void postForwardHeader() {
ResponseEntity<List<Bar>> result = rest.exchange(
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/forward/special/bars"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
@@ -139,7 +139,7 @@ public class ProductionConfigurationTests {
}
@Test
public void postForwardBody() throws Exception {
public void postForwardBody() {
ResponseEntity<String> result = rest
.exchange(
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/forward/body/bars"))
@@ -150,7 +150,7 @@ public class ProductionConfigurationTests {
}
@Test
public void postForwardForgetBody() throws Exception {
public void postForwardForgetBody() {
ResponseEntity<String> result = rest.exchange(
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/forward/forget/bars"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
@@ -160,7 +160,7 @@ public class ProductionConfigurationTests {
}
@Test
public void postForwardBodyFoo() throws Exception {
public void postForwardBodyFoo() {
ResponseEntity<List<Bar>> result = rest.exchange(
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/forward/body/bars"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
@@ -171,7 +171,7 @@ public class ProductionConfigurationTests {
}
@Test
public void list() throws Exception {
public void list() {
assertThat(rest.exchange(
RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy"))
.body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
@@ -180,13 +180,13 @@ public class ProductionConfigurationTests {
}
@Test
public void bodyless() throws Exception {
public void bodyless() {
assertThat(rest.postForObject("/proxy/0", Collections.singletonMap("name", "foo"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foo");
}
@Test
public void entity() throws Exception {
public void entity() {
assertThat(
rest.exchange(RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/entity"))
.body(Collections.singletonMap("name", "foo")), new ParameterizedTypeReference<List<Bar>>() {
@@ -194,7 +194,7 @@ public class ProductionConfigurationTests {
}
@Test
public void entityWithType() throws Exception {
public void entityWithType() {
assertThat(
rest.exchange(RequestEntity.post(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/type"))
.body(Collections.singletonMap("name", "foo")), new ParameterizedTypeReference<List<Bar>>() {
@@ -202,45 +202,45 @@ public class ProductionConfigurationTests {
}
@Test
public void single() throws Exception {
public void single() {
assertThat(rest.postForObject("/proxy/single", Collections.singletonMap("name", "foobar"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foobar");
}
@Test
public void converter() throws Exception {
public void converter() {
assertThat(
rest.postForObject("/proxy/converter", Collections.singletonMap("name", "foobar"), Bar.class).getName())
.isEqualTo("host=localhost:" + port + ";foobar");
}
@Test
public void noBody() throws Exception {
public void noBody() {
Foo foo = rest.postForObject("/proxy/no-body", null, Foo.class);
assertThat(foo.getName()).isEqualTo("hello");
}
@Test
public void deleteWithoutBody() throws Exception {
public void deleteWithoutBody() {
ResponseEntity<Void> deleteResponse = rest.exchange("/proxy/{id}/no-body", HttpMethod.DELETE, null, Void.TYPE,
Collections.singletonMap("id", "123"));
assertThat(deleteResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@Test
public void deleteWithBody() throws Exception {
public void deleteWithBody() {
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"));
assertThat(deleteResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(deleteResponse.getBody().get("deleted")).isEqualToComparingFieldByField(foo);
assertThat(deleteResponse.getBody().get("deleted")).usingRecursiveComparison().isEqualTo(foo);
}
@Test
@SuppressWarnings({ "Duplicates", "unchecked" })
public void testSensitiveHeadersOverride() throws Exception {
public void testSensitiveHeadersOverride() {
RequestEntity<Void> request = RequestEntity
.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/headers")).header("foo", "bar")
.header("abc", "xyz").header("cookie", "monster").build();
@@ -252,7 +252,7 @@ public class ProductionConfigurationTests {
@Test
@SuppressWarnings({ "Duplicates", "unchecked" })
public void testSensitiveHeadersDefault() throws Exception {
public void testSensitiveHeadersDefault() {
Map<String, List<String>> headers = rest.exchange(RequestEntity
.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/sensitive-headers-default"))
.header("cookie", "monster").build(), Map.class).getBody();
@@ -262,7 +262,7 @@ public class ProductionConfigurationTests {
@Test
@SuppressWarnings({ "Duplicates", "unchecked" })
public void headers() throws Exception {
public void headers() {
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)
@@ -275,7 +275,7 @@ public class ProductionConfigurationTests {
}
@Test
public void forwardedHeaderUsesHost() throws Exception {
public void forwardedHeaderUsesHost() {
Map<String, List<String>> headers = rest
.exchange(RequestEntity.get(rest.getRestTemplate().getUriTemplateHandler().expand("/proxy/headers"))
.header("host", "foo:1234").build(), Map.class)
@@ -306,97 +306,93 @@ public class ProductionConfigurationTests {
}
@GetMapping("/proxy/{id}")
public ResponseEntity<?> proxyFoos(@PathVariable Integer id, ProxyExchange<?> proxy) throws Exception {
public ResponseEntity<?> proxyFoos(@PathVariable Integer id, ProxyExchange<?> proxy) {
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) {
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) {
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) {
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) {
return proxy.uri(home.toString() + "/missing/" + id).get();
}
@GetMapping("/proxy")
public ResponseEntity<?> proxyUri(ProxyExchange<?> proxy) throws Exception {
public ResponseEntity<?> proxyUri(ProxyExchange<?> proxy) {
return proxy.uri(home.toString() + "/foos").get();
}
@PostMapping("/proxy/{id}")
public ResponseEntity<?> proxyBars(@PathVariable Integer id, @RequestBody Map<String, Object> body,
ProxyExchange<List<Object>> proxy) throws Exception {
ProxyExchange<List<Object>> proxy) {
body.put("id", id);
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) {
return proxy.uri(home.toString() + "/bars").post();
}
@PostMapping("/proxy/entity")
public ResponseEntity<?> explicitEntity(@RequestBody Foo foo, ProxyExchange<?> proxy) throws Exception {
public ResponseEntity<?> explicitEntity(@RequestBody Foo foo, ProxyExchange<?> proxy) {
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 {
ProxyExchange<List<Bar>> proxy) {
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 {
public ResponseEntity<?> implicitEntity(@RequestBody Foo foo, ProxyExchange<List<Object>> proxy) {
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) {
return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
.post(response -> ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders())
.body(response.getBody().iterator().next()));
}
@PostMapping("/proxy/no-body")
public ResponseEntity<Foo> noBody(ProxyExchange<Foo> proxy) throws Exception {
public ResponseEntity<Foo> noBody(ProxyExchange<Foo> proxy) {
return proxy.uri(home.toString() + "/foos").post();
}
@DeleteMapping("/proxy/{id}/no-body")
public ResponseEntity<?> deleteWithoutBody(@PathVariable Integer id, ProxyExchange<?> proxy)
throws Exception {
public ResponseEntity<?> deleteWithoutBody(@PathVariable Integer id, ProxyExchange<?> proxy) {
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 {
ProxyExchange<?> proxy) {
return proxy.uri(home.toString() + "/foos/" + id).body(foo).delete(response -> ResponseEntity
.status(response.getStatusCode()).headers(response.getHeaders()).body(response.getBody()));
}
@GetMapping("/forward/**")
public void forward(ProxyExchange<?> proxy) throws Exception {
public void forward(ProxyExchange<?> proxy) {
String path = proxy.path("/forward");
if (path.startsWith("/special")) {
proxy.header("X-Custom", "FOO");
@@ -406,7 +402,7 @@ public class ProductionConfigurationTests {
}
@PostMapping("/forward/**")
public void postForward(ProxyExchange<?> proxy) throws Exception {
public void postForward(ProxyExchange<?> proxy) {
String path = proxy.path("/forward");
if (path.startsWith("/special")) {
proxy.header("X-Custom", "FOO");
@@ -416,13 +412,14 @@ public class ProductionConfigurationTests {
}
@PostMapping("/forward/body/**")
public void postForwardBody(@RequestBody byte[] body, ProxyExchange<?> proxy) throws Exception {
public void postForwardBody(@RequestBody byte[] body, ProxyExchange<?> proxy) {
String path = proxy.path("/forward/body");
proxy.body(body).forward(path);
}
@SuppressWarnings("unused")
@PostMapping("/forward/forget/**")
public void postForwardForgetBody(@RequestBody byte[] body, ProxyExchange<?> proxy) throws Exception {
public void postForwardForgetBody(@RequestBody byte[] body, ProxyExchange<?> proxy) {
String path = proxy.path("/forward/forget");
proxy.forward(path);
}

View File

@@ -58,6 +58,7 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR
return HttpMethod.valueOf(httpRequest.getMethod());
}
@Deprecated
@Override
public String getMethodValue() {
return httpRequest.getMethod();

View File

@@ -59,7 +59,7 @@ public class GatewayProperties {
private List<FilterDefinition> defaultFilters = new ArrayList<>();
private List<MediaType> streamingMediaTypes = Arrays.asList(MediaType.TEXT_EVENT_STREAM,
MediaType.APPLICATION_STREAM_JSON, new MediaType("application", "grpc"),
new MediaType("application", "stream+json"), new MediaType("application", "grpc"),
new MediaType("application", "grpc+protobuf"), new MediaType("application", "grpc+json"));
/**

View File

@@ -48,12 +48,7 @@ public class LoadBalancerServiceInstanceCookieFilter implements GlobalFilter, Or
private ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerClientFactory;
/**
* @deprecated in favour of
* {@link LoadBalancerServiceInstanceCookieFilter#LoadBalancerServiceInstanceCookieFilter(ReactiveLoadBalancer.Factory)}
*/
@Deprecated
public LoadBalancerServiceInstanceCookieFilter(LoadBalancerProperties loadBalancerProperties) {
LoadBalancerServiceInstanceCookieFilter(LoadBalancerProperties loadBalancerProperties) {
this.loadBalancerProperties = loadBalancerProperties;
}

View File

@@ -119,7 +119,7 @@ public class NettyRoutingFilter implements GlobalFilter, Ordered {
ServerHttpRequest request = exchange.getRequest();
final HttpMethod method = HttpMethod.valueOf(request.getMethodValue());
final HttpMethod method = HttpMethod.valueOf(request.getMethod().name());
final String url = requestUrl.toASCIIString();
HttpHeaders filtered = filterRequest(getHeadersFilters(), exchange);

View File

@@ -189,7 +189,7 @@ public abstract class SpringCloudCircuitBreakerFilterFactory
}
public String getId() {
if (StringUtils.isEmpty(name) && !StringUtils.isEmpty(routeId)) {
if (!StringUtils.hasText(name) && StringUtils.hasText(routeId)) {
return routeId;
}
return name;

View File

@@ -151,7 +151,7 @@ public class PredicateSpec extends UriSpec {
*/
public BooleanSpec method(String... methods) {
return asyncPredicate(getBean(MethodRoutePredicateFactory.class).applyAsync(c -> {
HttpMethod[] httpMethods = stream(methods).map(HttpMethod::resolve).toArray(HttpMethod[]::new);
HttpMethod[] httpMethods = stream(methods).map(HttpMethod::valueOf).toArray(HttpMethod[]::new);
c.setMethods(httpMethods);
}));
}

View File

@@ -24,6 +24,7 @@ import org.springframework.core.style.DefaultValueStyler;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.ClassUtils;
@SuppressWarnings("rawtypes")
public class GatewayToStringStyler extends DefaultToStringStyler {
private static final GatewayToStringStyler FILTER_INSTANCE = new GatewayToStringStyler(GatewayFilterFactory.class,

View File

@@ -33,7 +33,7 @@ public class GatewayHttpTagsProvider implements GatewayTagsProvider {
String status = "CUSTOM";
String httpStatusCodeStr = "NA";
String httpMethod = exchange.getRequest().getMethodValue();
String httpMethod = exchange.getRequest().getMethod().name();
// a non standard HTTPS status could be used. Let's be defensive here
// it needs to be checked for first, otherwise the delegate response

View File

@@ -16,7 +16,7 @@
package org.springframework.cloud.gateway.cors;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
@@ -31,9 +31,9 @@ import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.web.reactive.function.client.ClientResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -46,30 +46,29 @@ public class SimpleUrlHandlerCorsTests extends BaseWebClientTests {
@Test
public void testPreFlightCorsRequestNotHandledByGW() {
ClientResponse clientResponse = webClient.options().uri("/abc/123/function").header("Origin", "domain.com")
.header("Access-Control-Request-Method", "GET").exchange().block();
HttpHeaders asHttpHeaders = clientResponse.headers().asHttpHeaders();
Mono<String> bodyToMono = clientResponse.bodyToMono(String.class);
ResponseEntity<String> response = webClient.options().uri("/abc/123/function").header("Origin", "domain.com")
.header("Access-Control-Request-Method", "GET").retrieve().toEntity(String.class).block();
HttpHeaders asHttpHeaders = response.getHeaders();
// pre-flight request shouldn't return the response body
assertThat(bodyToMono.block()).isNull();
assertThat(response.getBody()).isNull();
assertThat(asHttpHeaders.getAccessControlAllowOrigin())
.as("Missing header value in response: " + HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN).isEqualTo("*");
assertThat(asHttpHeaders.getAccessControlAllowMethods())
.as("Missing header value in response: " + HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS)
.isEqualTo(Arrays.asList(new HttpMethod[] { HttpMethod.GET }));
assertThat(clientResponse.statusCode()).as("Pre Flight call failed.").isEqualTo(HttpStatus.OK);
.isEqualTo(List.of(HttpMethod.GET));
assertThat(response.getStatusCode()).as("Pre Flight call failed.").isEqualTo(HttpStatus.OK);
}
@Test
public void testCorsRequestNotHandledByGW() {
ClientResponse clientResponse = webClient.get().uri("/abc/123/function").header("Origin", "domain.com")
.header(HttpHeaders.HOST, "www.path.org").exchange().block();
HttpHeaders asHttpHeaders = clientResponse.headers().asHttpHeaders();
Mono<String> bodyToMono = clientResponse.bodyToMono(String.class);
assertThat(bodyToMono.block()).isNotNull();
ResponseEntity<String> responseEntity = webClient.get().uri("/abc/123/function").header("Origin", "domain.com")
.header(HttpHeaders.HOST, "www.path.org").retrieve().onStatus(HttpStatus::isError, t -> Mono.empty())
.toEntity(String.class).block();
HttpHeaders asHttpHeaders = responseEntity.getHeaders();
assertThat(responseEntity.getBody()).isNotNull();
assertThat(asHttpHeaders.getAccessControlAllowOrigin())
.as("Missing header value in response: " + HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN).isEqualTo("*");
assertThat(clientResponse.statusCode()).as("CORS request failed.").isEqualTo(HttpStatus.NOT_FOUND);
assertThat(responseEntity.getStatusCode()).as("CORS request failed.").isEqualTo(HttpStatus.NOT_FOUND);
}
@EnableAutoConfiguration

View File

@@ -268,8 +268,7 @@ class ReactiveLoadBalancerClientFilterTests {
ServiceInstanceListSuppliers.toProvider("service1"), "service1", -1);
when(clientFactory.getInstance("service1", ReactorServiceInstanceLoadBalancer.class)).thenReturn(loadBalancer);
properties.setUse404(true);
ReactiveLoadBalancerClientFilter filter = new ReactiveLoadBalancerClientFilter(clientFactory, properties,
loadBalancerProperties);
ReactiveLoadBalancerClientFilter filter = new ReactiveLoadBalancerClientFilter(clientFactory, properties);
when(chain.filter(exchange)).thenReturn(Mono.empty());
try {
filter.filter(exchange, chain).block();
@@ -442,8 +441,7 @@ class ReactiveLoadBalancerClientFilterTests {
"service1", -1);
when(clientFactory.getInstance("service1", ReactorServiceInstanceLoadBalancer.class)).thenReturn(loadBalancer);
ReactiveLoadBalancerClientFilter filter = new ReactiveLoadBalancerClientFilter(clientFactory, properties,
loadBalancerProperties);
ReactiveLoadBalancerClientFilter filter = new ReactiveLoadBalancerClientFilter(clientFactory, properties);
filter.filter(exchange, chain).block();
return captor.getValue();

View File

@@ -127,7 +127,7 @@ public class CacheRequestBodyGatewayFilterFactoryTests extends BaseWebClientTest
private String bodyExcepted;
AssertCachedRequestBodyGatewayFilter(String body) {
this.exceptNullBody = StringUtils.isEmpty(body);
this.exceptNullBody = !StringUtils.hasText(body);
this.bodyExcepted = body;
}

View File

@@ -188,6 +188,7 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest
}
@Test
@SuppressWarnings("unchecked")
public void toStringFormat() {
RetryConfig config = new RetryConfig();
config.setRetries(4);

View File

@@ -28,6 +28,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.web.reactive.function.client.ClientResponse;
@@ -73,13 +74,13 @@ public class SecureHeadersGatewayFilterFactoryTests extends BaseWebClientTests {
@Test
public void addsSecureHeadersAfterResponseIsReceived() {
Mono<ClientResponse> result = webClient.patch().uri("/headers").header("Host", "www.secureheaders.org")
.contentType(MediaType.APPLICATION_JSON).bodyValue("{ \"X-Frame-Options\": \"sameorigin\" }")
.exchange();
Mono<ResponseEntity<String>> responseEntity = webClient.patch().uri("/headers")
.header("Host", "www.secureheaders.org").contentType(MediaType.APPLICATION_JSON)
.bodyValue("{ \"X-Frame-Options\": \"sameorigin\" }").retrieve().toEntity(String.class);
StepVerifier.create(result).consumeNextWith(response -> {
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.headers().header(X_FRAME_OPTIONS_HEADER)).containsOnly("sameorigin");
StepVerifier.create(responseEntity).consumeNextWith(response -> {
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getHeaders().get(X_FRAME_OPTIONS_HEADER)).containsOnly("sameorigin");
}).expectComplete().verify(DURATION);
}

View File

@@ -16,6 +16,8 @@
package org.springframework.cloud.gateway.filter.factory;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.timelimiter.TimeLimiterRegistry;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -81,7 +83,9 @@ public class SpringCloudCircuitBreakerResilience4JFilterFactoryTests
SpringCloudCircuitBreakerFilterFactory.Config config = new SpringCloudCircuitBreakerFilterFactory.Config()
.setName("myname").setFallbackUri("forward:/myfallback");
GatewayFilter filter = new SpringCloudCircuitBreakerResilience4JFilterFactory(
new ReactiveResilience4JCircuitBreakerFactory(), null).apply(config);
new ReactiveResilience4JCircuitBreakerFactory(CircuitBreakerRegistry.ofDefaults(),
TimeLimiterRegistry.ofDefaults()),
null).apply(config);
assertThat(filter.toString()).contains("myname").contains("forward:/myfallback");
}

View File

@@ -29,13 +29,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoProcessor;
import reactor.core.publisher.ReplayProcessor;
import reactor.core.publisher.Sinks;
import org.springframework.beans.factory.annotation.Value;
@@ -59,6 +57,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.DispatcherHandler;
@@ -76,6 +75,7 @@ import org.springframework.web.reactive.socket.server.WebSocketService;
import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService;
import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter;
import org.springframework.web.reactive.socket.server.upgrade.ReactorNettyRequestUpgradeStrategy;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import static org.assertj.core.api.Assertions.assertThat;
@@ -91,6 +91,8 @@ import static org.springframework.cloud.gateway.filter.WebsocketRoutingFilter.SE
@DisabledIfEnvironmentVariable(named = "GITHUB_ACTIONS", matches = "true")
public class WebSocketIntegrationTests {
private static final Duration TIMEOUT = Duration.ofMillis(5000);
private static final Log logger = LogFactory.getLog(WebSocketIntegrationTests.class);
protected int serverPort;
@@ -105,13 +107,6 @@ public class WebSocketIntegrationTests {
private static final Sinks.One<CloseStatus> serverCloseStatusSink = Sinks.one();
private static Mono<Void> doSend(WebSocketSession session, Publisher<WebSocketMessage> output) {
return session.send(output);
// workaround for suspected RxNetty WebSocket client issue
// https://github.com/ReactiveX/RxNetty/issues/560
// return session.send(Mono.delay(Duration.ofMillis(100)).thenMany(output));
}
@BeforeEach
public void setup() throws Exception {
this.client = new ReactorNettyWebSocketClient();
@@ -166,38 +161,29 @@ public class WebSocketIntegrationTests {
public void echo() throws Exception {
int count = 100;
Flux<String> input = Flux.range(1, count).map(index -> "msg-" + index);
ReplayProcessor<Object> output = ReplayProcessor.create(count);
client.execute(getUrl("/echo"), session -> {
logger.debug("Starting to send messages");
return session.send(input.doOnNext(s -> logger.debug("outbound " + s)).map(s -> session.textMessage(s)))
.thenMany(session.receive().take(count).map(WebSocketMessage::getPayloadAsText))
.subscribeWith(output).doOnNext(s -> logger.debug("inbound " + s)).then()
.doOnSuccess(aVoid -> logger.debug("Done with success"))
.doOnError(ex -> logger.debug("Done with " + (ex != null ? ex.getMessage() : "error")));
}).block(Duration.ofMillis(5000));
assertThat(output.collectList().block(Duration.ofMillis(5000)))
.isEqualTo(input.collectList().block(Duration.ofMillis(5000)));
AtomicReference<List<String>> actualRef = new AtomicReference<>();
this.client.execute(getUrl("/echo"),
session -> session.send(input.map(session::textMessage))
.thenMany(session.receive().take(count).map(WebSocketMessage::getPayloadAsText)).collectList()
.doOnNext(actualRef::set).then())
.block(TIMEOUT);
assertThat(actualRef.get()).isNotNull();
assertThat(actualRef.get()).isEqualTo(input.collectList().block());
}
@Test
public void echoForHttp() throws Exception {
int count = 100;
Flux<String> input = Flux.range(1, count).map(index -> "msg-" + index);
ReplayProcessor<Object> output = ReplayProcessor.create(count);
client.execute(getHttpUrl("/echoForHttp"), session -> {
AtomicReference<List<String>> actualRef = new AtomicReference<>();
this.client.execute(getHttpUrl("/echoForHttp"), session -> {
logger.debug("Starting to send messages");
return session.send(input.doOnNext(s -> logger.debug("outbound " + s)).map(s -> session.textMessage(s)))
.thenMany(session.receive().take(count).map(WebSocketMessage::getPayloadAsText))
.subscribeWith(output).doOnNext(s -> logger.debug("inbound " + s)).then()
.doOnSuccess(aVoid -> logger.debug("Done with success"))
.doOnError(ex -> logger.debug("Done with " + (ex != null ? ex.getMessage() : "error")));
}).block(Duration.ofMillis(5000));
assertThat(output.collectList().block(Duration.ofMillis(5000)))
.isEqualTo(input.collectList().block(Duration.ofMillis(5000)));
return session.send(input.doOnNext(s -> logger.debug("outbound " + s)).map(session::textMessage))
.thenMany(session.receive().take(count).map(WebSocketMessage::getPayloadAsText)).collectList()
.doOnNext(actualRef::set).then();
}).block(TIMEOUT);
assertThat(actualRef.get()).isNotNull();
assertThat(actualRef.get()).isEqualTo(input.collectList().block());
}
@Test
@@ -205,9 +191,9 @@ public class WebSocketIntegrationTests {
String protocol = "echo-v1";
String protocol2 = "echo-v2";
AtomicReference<HandshakeInfo> infoRef = new AtomicReference<>();
MonoProcessor<Object> output = MonoProcessor.create();
AtomicReference<Object> protocolRef = new AtomicReference<>();
client.execute(getUrl("/sub-protocol"), new WebSocketHandler() {
this.client.execute(getUrl("/sub-protocol"), new WebSocketHandler() {
@Override
public List<String> getSubProtocols() {
return Arrays.asList(protocol, protocol2);
@@ -216,30 +202,29 @@ public class WebSocketIntegrationTests {
@Override
public Mono<Void> handle(WebSocketSession session) {
infoRef.set(session.getHandshakeInfo());
return session.receive().map(WebSocketMessage::getPayloadAsText).subscribeWith(output).then();
return session.receive().map(WebSocketMessage::getPayloadAsText).doOnNext(protocolRef::set)
.doOnError(protocolRef::set).then();
}
}).block(Duration.ofMillis(5000));
}).block(TIMEOUT);
HandshakeInfo info = infoRef.get();
assertThat(info.getHeaders().getFirst("Upgrade")).isEqualToIgnoringCase("websocket");
assertThat(info.getHeaders().getFirst("Sec-WebSocket-Protocol")).isEqualTo(protocol);
assertThat(info.getSubProtocol()).as("Wrong protocol accepted").isEqualTo(protocol);
assertThat(output.block(Duration.ofSeconds(5))).as("Wrong protocol detected on the server side")
.isEqualTo(protocol);
assertThat(protocolRef.get()).as("Wrong protocol detected on the server side").isEqualTo(protocol);
}
@Test
public void customHeader() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.add("my-header", "my-value");
MonoProcessor<Object> output = MonoProcessor.create();
AtomicReference<Object> headerRef = new AtomicReference<>();
client.execute(getUrl("/custom-header"), headers,
session -> session.receive().map(WebSocketMessage::getPayloadAsText).subscribeWith(output).then())
.block(Duration.ofMillis(5000));
this.client.execute(getUrl("/custom-header"), headers, session -> session.receive()
.map(WebSocketMessage::getPayloadAsText).doOnNext(headerRef::set).doOnError(headerRef::set).then())
.block(TIMEOUT);
assertThat(output.block(Duration.ofMillis(5000))).isEqualTo("my-header:my-value");
assertThat(headerRef.get()).isEqualTo("my-header:my-value");
}
@Test
@@ -264,6 +249,20 @@ public class WebSocketIntegrationTests {
.isEqualTo(CloseStatus.create(4999, "client-close"));
}
@Disabled
@Test
void cookie() throws Exception {
AtomicReference<String> cookie = new AtomicReference<>();
AtomicReference<Object> receivedCookieRef = new AtomicReference<>();
this.client.execute(getUrl("/cookie"), session -> {
cookie.set(session.getHandshakeInfo().getHeaders().getFirst("Set-Cookie"));
return session.receive().map(WebSocketMessage::getPayloadAsText).doOnNext(receivedCookieRef::set)
.doOnError(receivedCookieRef::set).then();
}).block(TIMEOUT);
assertThat(receivedCookieRef.get()).isEqualTo("cookie");
assertThat(cookie.get()).isEqualTo("project=spring");
}
@Configuration(proxyBeanMethods = false)
static class WebSocketTestConfig {
@@ -295,12 +294,23 @@ public class WebSocketIntegrationTests {
map.put("/custom-header", new CustomHeaderHandler());
map.put("/server-close", new ServerClosingHandler());
map.put("/client-close", new ClientClosingHandler());
map.put("/cookie", new CookieHandler());
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setUrlMap(map);
return mapping;
}
@Bean
public WebFilter cookieWebFilter() {
return (exchange, chain) -> {
if (exchange.getRequest().getPath().value().startsWith("/cookie")) {
exchange.getResponse().addCookie(ResponseCookie.from("project", "spring").build());
}
return chain.filter(exchange);
};
}
}
private static class EchoWebSocketHandler implements WebSocketHandler {
@@ -328,8 +338,8 @@ public class WebSocketIntegrationTests {
}
List<String> protocols = session.getHandshakeInfo().getHeaders().get(SEC_WEBSOCKET_PROTOCOL);
assertThat(protocols).contains("echo-v1,echo-v2");
WebSocketMessage message = session.textMessage(protocol);
return doSend(session, Mono.just(message));
WebSocketMessage message = session.textMessage(protocol != null ? protocol : "none");
return session.send(Mono.just(message));
}
}
@@ -344,7 +354,7 @@ public class WebSocketIntegrationTests {
}
String payload = "my-header:" + headers.getFirst("my-header");
WebSocketMessage message = session.textMessage(payload);
return doSend(session, Mono.just(message));
return session.send(Mono.just(message));
}
}
@@ -367,6 +377,16 @@ public class WebSocketIntegrationTests {
}
private static class CookieHandler implements WebSocketHandler {
@Override
public Mono<Void> handle(WebSocketSession session) {
WebSocketMessage message = session.textMessage("cookie");
return session.send(Mono.just(message));
}
}
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import(PermitAllSecurityConfiguration.class)

View File

@@ -33,6 +33,7 @@ import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.RequestEntity.BodyBuilder;
import org.springframework.http.ResponseEntity;
@@ -43,7 +44,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec;
import org.springframework.web.server.ServerWebExchange;
@@ -360,25 +360,26 @@ public class ProxyExchange<T> {
Type type = this.responseType;
RequestBodySpec builder = rest.method(requestEntity.getMethod()).uri(requestEntity.getUrl())
.headers(headers -> addHeaders(headers, requestEntity.getHeaders()));
Mono<ClientResponse> result;
WebClient.ResponseSpec result;
if (requestEntity.getBody() instanceof Publisher) {
@SuppressWarnings("unchecked")
Publisher<Object> publisher = (Publisher<Object>) requestEntity.getBody();
result = builder.body(publisher, Object.class).exchange();
result = builder.body(publisher, Object.class).retrieve();
}
else if (requestEntity.getBody() != null) {
result = builder.body(BodyInserters.fromValue(requestEntity.getBody())).exchange();
result = builder.body(BodyInserters.fromValue(requestEntity.getBody())).retrieve();
}
else {
if (hasBody) {
result = builder.headers(headers -> addHeaders(headers, exchange.getRequest().getHeaders()))
.body(exchange.getRequest().getBody(), DataBuffer.class).exchange();
.body(exchange.getRequest().getBody(), DataBuffer.class).retrieve();
}
else {
result = builder.headers(headers -> addHeaders(headers, exchange.getRequest().getHeaders())).exchange();
result = builder.headers(headers -> addHeaders(headers, exchange.getRequest().getHeaders())).retrieve();
}
}
return result.flatMap(response -> response.toEntity(ParameterizedTypeReference.forType(type)));
return result.onStatus(HttpStatus::isError, t -> Mono.empty())
.toEntity(ParameterizedTypeReference.forType(type));
}
private void addHeaders(HttpHeaders headers, HttpHeaders toAdd) {
@@ -436,7 +437,7 @@ public class ProxyExchange<T> {
}
private String forwarded(URI uri, String hostHeader) {
if (!StringUtils.isEmpty(hostHeader)) {
if (StringUtils.hasText(hostHeader)) {
return "host=" + hostHeader;
}
if ("http".equals(uri.getScheme())) {

View File

@@ -238,7 +238,7 @@ public class ProductionConfigurationTests {
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")).usingRecursiveComparison().isEqualTo(foo);
}
@SpringBootApplication