From 7d57ec259e5b229060405b7cb4dc569cf9b04238 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 21 Jan 2020 21:54:28 -0500 Subject: [PATCH] Removes maintenance mode bits of ribbon and hystrix --- pom.xml | 20 - spring-cloud-gateway-core/pom.xml | 10 - .../config/GatewayAutoConfiguration.java | 24 +- ...ystrixCircuitBreakerAutoConfiguration.java | 61 --- ...ayLoadBalancerClientAutoConfiguration.java | 54 --- ...NoLoadBalancerClientAutoConfiguration.java | 14 +- ...veLoadBalancerClientAutoConfiguration.java | 26 -- .../filter/LoadBalancerClientFilter.java | 115 ----- .../ReactiveLoadBalancerClientFilter.java | 5 +- .../FallbackHeadersGatewayFilterFactory.java | 75 ++-- .../factory/HystrixGatewayFilterFactory.java | 291 ------------ ...oudCircuitBreakerHystrixFilterFactory.java | 74 ---- .../route/builder/GatewayFilterSpec.java | 23 - .../gateway/support/ConfigurationUtils.java | 51 --- .../support/DefaultClientResponse.java | 262 ----------- .../gateway/support/DefaultServerRequest.java | 311 ------------- .../support/DefaultServerResponse.java | 126 ------ .../support/ServerWebExchangeUtils.java | 6 - .../main/resources/META-INF/spring.factories | 2 - ...dBalancerClientAutoConfigurationTests.java | 5 +- .../filter/LoadBalancerClientFilterTests.java | 418 ------------------ ...rixGatewayFilterFactoryPrincipalTests.java | 154 ------- .../HystrixGatewayFilterFactoryTests.java | 149 ------- .../filter/factory/HystrixTestConfig.java | 139 ------ ...yGatewayFilterFactoryIntegrationTests.java | 21 +- ...rcuitBreakerHystrixFilterFactoryTests.java | 82 ---- ...BreakerResilience4JFilterFactoryTests.java | 3 +- .../SpringCloudCircuitBreakerTestConfig.java | 19 +- .../ReadBodyPredicateFactoryTest.java | 23 +- .../cloud/gateway/test/AdhocTestSuite.java | 2 - .../gateway/test/BaseWebClientTests.java | 20 +- .../websocket/WebSocketIntegrationTests.java | 18 +- .../CustomBlockHoundIntegration.java | 7 - spring-cloud-gateway-sample/pom.xml | 4 - .../sample/GatewaySampleApplicationTests.java | 19 +- 35 files changed, 106 insertions(+), 2527 deletions(-) delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayHystrixCircuitBreakerAutoConfiguration.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayLoadBalancerClientAutoConfiguration.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilter.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactory.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerHystrixFilterFactory.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ConfigurationUtils.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultClientResponse.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultServerRequest.java delete mode 100644 spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultServerResponse.java delete mode 100644 spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilterTests.java delete mode 100644 spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactoryPrincipalTests.java delete mode 100644 spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactoryTests.java delete mode 100644 spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixTestConfig.java delete mode 100644 spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerHystrixFilterFactoryTests.java diff --git a/pom.xml b/pom.xml index e620e125..580f2d03 100644 --- a/pom.xml +++ b/pom.xml @@ -82,21 +82,6 @@ pom import - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - ${spring-cloud-netflix.version} - - - com.netflix.ribbon - ribbon-transport - - - io.reactivex - rxnetty - - - org.springframework.cloud spring-cloud-test-support @@ -108,11 +93,6 @@ spring-cloud-starter-netflix-eureka-client ${spring-cloud-netflix.version} - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - ${spring-cloud-netflix.version} - org.springframework.cloud spring-cloud-circuitbreaker-dependencies diff --git a/spring-cloud-gateway-core/pom.xml b/spring-cloud-gateway-core/pom.xml index e8046a5b..83b60d3e 100644 --- a/spring-cloud-gateway-core/pom.xml +++ b/spring-cloud-gateway-core/pom.xml @@ -38,16 +38,6 @@ spring-boot-configuration-processor true - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - true - - - org.springframework.cloud - spring-cloud-starter-netflix-hystrix - true - org.springframework.cloud spring-cloud-loadbalancer diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java index 00ce39cf..583ef7f4 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java @@ -19,7 +19,6 @@ package org.springframework.cloud.gateway.config; import java.security.cert.X509Certificate; import java.util.List; -import com.netflix.hystrix.HystrixObservableCommand; import io.netty.channel.ChannelOption; import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.util.InsecureTrustManagerFactory; @@ -29,7 +28,6 @@ import reactor.core.publisher.Flux; import reactor.netty.http.client.HttpClient; import reactor.netty.resources.ConnectionProvider; import reactor.netty.tcp.ProxyProvider; -import rx.RxReactiveStreams; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.ObjectProvider; @@ -66,9 +64,7 @@ import org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayF import org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory; -import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory; -import org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.MapRequestHeaderGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.PrefixPathGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory; @@ -160,7 +156,7 @@ import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool @EnableConfigurationProperties @AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class }) -@AutoConfigureAfter({ GatewayLoadBalancerClientAutoConfiguration.class, +@AutoConfigureAfter({ GatewayReactiveLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class }) @ConditionalOnClass(DispatcherHandler.class) public class GatewayAutoConfiguration { @@ -712,24 +708,6 @@ public class GatewayAutoConfiguration { } - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ HystrixObservableCommand.class, RxReactiveStreams.class }) - protected static class HystrixConfiguration { - - @Bean - public HystrixGatewayFilterFactory hystrixGatewayFilterFactory( - ObjectProvider dispatcherHandler) { - return new HystrixGatewayFilterFactory(dispatcherHandler); - } - - @Bean - @ConditionalOnMissingBean(FallbackHeadersGatewayFilterFactory.class) - public FallbackHeadersGatewayFilterFactory fallbackHeadersGatewayFilterFactory() { - return new FallbackHeadersGatewayFilterFactory(); - } - - } - @Configuration(proxyBeanMethods = false) @ConditionalOnClass(Health.class) protected static class GatewayActuatorConfiguration { diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayHystrixCircuitBreakerAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayHystrixCircuitBreakerAutoConfiguration.java deleted file mode 100644 index d4780c9e..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayHystrixCircuitBreakerAutoConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.config; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory; -import org.springframework.cloud.gateway.filter.factory.SpringCloudCircuitBreakerHystrixFilterFactory; -import org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerAutoConfiguration; -import org.springframework.cloud.netflix.hystrix.ReactiveHystrixCircuitBreakerAutoConfiguration; -import org.springframework.cloud.netflix.hystrix.ReactiveHystrixCircuitBreakerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.DispatcherHandler; - -/** - * @author Ryan Baxter - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true) -@AutoConfigureAfter({ ReactiveHystrixCircuitBreakerAutoConfiguration.class }) -@ConditionalOnClass({ DispatcherHandler.class, - HystrixCircuitBreakerAutoConfiguration.class, ReactiveCircuitBreakerFactory.class, - ReactiveHystrixCircuitBreakerFactory.class }) -public class GatewayHystrixCircuitBreakerAutoConfiguration { - - @Bean - @ConditionalOnBean(ReactiveHystrixCircuitBreakerFactory.class) - public SpringCloudCircuitBreakerHystrixFilterFactory springCloudCircuitBreakerHystrixFilterFactory( - ReactiveHystrixCircuitBreakerFactory reactiveCircuitBreakerFactory, - ObjectProvider dispatcherHandler) { - return new SpringCloudCircuitBreakerHystrixFilterFactory( - reactiveCircuitBreakerFactory, dispatcherHandler); - } - - @Bean - @ConditionalOnMissingBean(FallbackHeadersGatewayFilterFactory.class) - public FallbackHeadersGatewayFilterFactory fallbackHeadersGatewayFilterFactory() { - return new FallbackHeadersGatewayFilterFactory(); - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayLoadBalancerClientAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayLoadBalancerClientAutoConfiguration.java deleted file mode 100644 index 7567e812..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayLoadBalancerClientAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.config; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter; -import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter; -import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.DispatcherHandler; - -/** - * AutoConfiguration for {@link LoadBalancerClientFilter}. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ LoadBalancerClient.class, RibbonAutoConfiguration.class, - DispatcherHandler.class }) -@AutoConfigureAfter(RibbonAutoConfiguration.class) -@EnableConfigurationProperties(LoadBalancerProperties.class) -public class GatewayLoadBalancerClientAutoConfiguration { - - @Bean - @ConditionalOnBean(LoadBalancerClient.class) - @ConditionalOnMissingBean({ LoadBalancerClientFilter.class, - ReactiveLoadBalancerClientFilter.class }) - public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client, - LoadBalancerProperties properties) { - return new LoadBalancerClientFilter(client, properties); - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayNoLoadBalancerClientAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayNoLoadBalancerClientAutoConfiguration.java index b51db395..9efcf12e 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayNoLoadBalancerClientAutoConfiguration.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayNoLoadBalancerClientAutoConfiguration.java @@ -24,17 +24,17 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; +import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.cloud.gateway.filter.LoadBalancerClientFilter; +import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter; import org.springframework.cloud.gateway.support.NotFoundException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.web.server.ServerWebExchange; -import static org.springframework.cloud.gateway.filter.LoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER; +import static org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR; @@ -42,14 +42,14 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.G * @author Spencer Gibb */ @Configuration(proxyBeanMethods = false) -@ConditionalOnMissingClass("org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration") -@ConditionalOnMissingBean(LoadBalancerClient.class) +@ConditionalOnMissingClass("org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer") +@ConditionalOnMissingBean(ReactiveLoadBalancer.class) @EnableConfigurationProperties(LoadBalancerProperties.class) -@AutoConfigureAfter(GatewayLoadBalancerClientAutoConfiguration.class) +@AutoConfigureAfter(GatewayReactiveLoadBalancerClientAutoConfiguration.class) public class GatewayNoLoadBalancerClientAutoConfiguration { @Bean - @ConditionalOnMissingBean(LoadBalancerClientFilter.class) + @ConditionalOnMissingBean(ReactiveLoadBalancerClientFilter.class) public NoLoadBalancerClientFilter noLoadBalancerClientFilter( LoadBalancerProperties properties) { return new NoLoadBalancerClientFilter(properties.isUse404()); diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayReactiveLoadBalancerClientAutoConfiguration.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayReactiveLoadBalancerClientAutoConfiguration.java index 20d0bdfd..6b06bd24 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayReactiveLoadBalancerClientAutoConfiguration.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/config/GatewayReactiveLoadBalancerClientAutoConfiguration.java @@ -17,20 +17,15 @@ package org.springframework.cloud.gateway.config; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter; import org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.DispatcherHandler; @@ -43,7 +38,6 @@ import org.springframework.web.reactive.DispatcherHandler; @Configuration(proxyBeanMethods = false) @ConditionalOnClass({ ReactiveLoadBalancer.class, LoadBalancerAutoConfiguration.class, DispatcherHandler.class }) -@AutoConfigureBefore(GatewayLoadBalancerClientAutoConfiguration.class) @AutoConfigureAfter(LoadBalancerAutoConfiguration.class) @EnableConfigurationProperties(LoadBalancerProperties.class) public class GatewayReactiveLoadBalancerClientAutoConfiguration { @@ -51,29 +45,9 @@ public class GatewayReactiveLoadBalancerClientAutoConfiguration { @Bean @ConditionalOnBean(LoadBalancerClientFactory.class) @ConditionalOnMissingBean(ReactiveLoadBalancerClientFilter.class) - @Conditional(OnNoRibbonDefaultCondition.class) public ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter( LoadBalancerClientFactory clientFactory, LoadBalancerProperties properties) { return new ReactiveLoadBalancerClientFilter(clientFactory, properties); } - private static final class OnNoRibbonDefaultCondition extends AnyNestedCondition { - - private OnNoRibbonDefaultCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnProperty(value = "spring.cloud.loadbalancer.ribbon.enabled", - havingValue = "false") - static class RibbonNotEnabled { - - } - - @ConditionalOnMissingClass("org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient") - static class RibbonLoadBalancerNotPresent { - - } - - } - } diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilter.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilter.java deleted file mode 100644 index 6391f27f..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilter.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.filter; - -import java.net.URI; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.gateway.config.LoadBalancerProperties; -import org.springframework.cloud.gateway.support.DelegatingServiceInstance; -import org.springframework.cloud.gateway.support.NotFoundException; -import org.springframework.core.Ordered; -import org.springframework.web.server.ServerWebExchange; - -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl; - -/** - * @deprecated in favour of {@link ReactiveLoadBalancerClientFilter} - * @author Spencer Gibb - * @author Tim Ysewyn - */ -@Deprecated -public class LoadBalancerClientFilter implements GlobalFilter, Ordered { - - /** - * Filter order for {@link LoadBalancerClientFilter}. - */ - public static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10100; - - private static final Log log = LogFactory.getLog(LoadBalancerClientFilter.class); - - protected final LoadBalancerClient loadBalancer; - - private LoadBalancerProperties properties; - - public LoadBalancerClientFilter(LoadBalancerClient loadBalancer, - LoadBalancerProperties properties) { - this.loadBalancer = loadBalancer; - this.properties = properties; - } - - @Override - public int getOrder() { - return LOAD_BALANCER_CLIENT_FILTER_ORDER; - } - - @Override - @SuppressWarnings("Duplicates") - public Mono 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))) { - return chain.filter(exchange); - } - // preserve the original url - addOriginalRequestUrl(exchange, url); - - if (log.isTraceEnabled()) { - log.trace("LoadBalancerClientFilter url before: " + url); - } - - final ServiceInstance instance = choose(exchange); - - if (instance == null) { - throw NotFoundException.create(properties.isUse404(), - "Unable to find instance for " + url.getHost()); - } - - URI uri = exchange.getRequest().getURI(); - - // if the `lb:` mechanism was used, use `` as the default, - // if the loadbalancer doesn't provide one. - String overrideScheme = instance.isSecure() ? "https" : "http"; - if (schemePrefix != null) { - overrideScheme = url.getScheme(); - } - - URI requestUrl = loadBalancer.reconstructURI( - new DelegatingServiceInstance(instance, overrideScheme), uri); - - if (log.isTraceEnabled()) { - log.trace("LoadBalancerClientFilter url chosen: " + requestUrl); - } - - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl); - return chain.filter(exchange); - } - - protected ServiceInstance choose(ServerWebExchange exchange) { - return loadBalancer.choose( - ((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost()); - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilter.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilter.java index 7b462653..850969f1 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilter.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/ReactiveLoadBalancerClientFilter.java @@ -52,7 +52,10 @@ public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered { private static final Log log = LogFactory .getLog(ReactiveLoadBalancerClientFilter.class); - private static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150; + /** + * Order of filter. + */ + public static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10150; private final LoadBalancerClientFactory clientFactory; diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/FallbackHeadersGatewayFilterFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/FallbackHeadersGatewayFilterFactory.java index 9a18076a..371ab6df 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/FallbackHeadersGatewayFilterFactory.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/FallbackHeadersGatewayFilterFactory.java @@ -16,6 +16,7 @@ package org.springframework.cloud.gateway.filter.factory; +import java.util.ArrayList; import java.util.List; import org.springframework.cloud.gateway.filter.GatewayFilter; @@ -23,10 +24,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.web.server.ServerWebExchange; import static java.util.Collections.singletonList; -import static java.util.Optional.ofNullable; -import static org.apache.commons.lang.exception.ExceptionUtils.getRootCause; import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR; /** * @author Olga Maciaszek-Sharma @@ -47,41 +45,50 @@ public class FallbackHeadersGatewayFilterFactory @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { - ServerWebExchange filteredExchange = ofNullable(ofNullable( - (Throwable) exchange.getAttribute(HYSTRIX_EXECUTION_EXCEPTION_ATTR)) - .orElseGet(() -> exchange.getAttribute( - CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR))) - .map(executionException -> { - ServerHttpRequest.Builder requestBuilder = exchange - .getRequest().mutate(); - requestBuilder.header( - config.executionExceptionTypeHeaderName, - executionException.getClass() - .getName()); - requestBuilder.header( - config.executionExceptionMessageHeaderName, - executionException.getMessage()); - ofNullable( - getRootCause(executionException)) - .ifPresent(rootCause -> { - requestBuilder.header( - config.rootCauseExceptionTypeHeaderName, - rootCause - .getClass() - .getName()); - requestBuilder.header( - config.rootCauseExceptionMessageHeaderName, - rootCause - .getMessage()); - }); - return exchange.mutate() - .request(requestBuilder.build()) - .build(); - }).orElse(exchange); + Throwable exception = exchange + .getAttribute(CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR); + ServerWebExchange filteredExchange; + if (exception == null) { + filteredExchange = exchange; + } + else { + filteredExchange = addFallbackHeaders(config, exchange, exception); + } return chain.filter(filteredExchange); }; } + 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()); + Throwable rootCause = getRootCause(executionException); + if (rootCause != null) { + requestBuilder.header(config.rootCauseExceptionTypeHeaderName, + rootCause.getClass().getName()); + requestBuilder.header(config.rootCauseExceptionMessageHeaderName, + rootCause.getMessage()); + } + return exchange.mutate().request(requestBuilder.build()).build(); + } + + private static Throwable getRootCause(final Throwable throwable) { + final List list = getThrowableList(throwable); + return list.isEmpty() ? null : list.get(list.size() - 1); + } + + private static List getThrowableList(Throwable throwable) { + final List list = new ArrayList<>(); + while (throwable != null && !list.contains(throwable)) { + list.add(throwable); + throwable = throwable.getCause(); + } + return list; + } + public static class Config { private static final String EXECUTION_EXCEPTION_TYPE = "Execution-Exception-Type"; diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactory.java deleted file mode 100644 index f91f8073..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactory.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.filter.factory; - -import java.net.URI; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; - -import com.netflix.hystrix.HystrixCommandGroupKey; -import com.netflix.hystrix.HystrixCommandKey; -import com.netflix.hystrix.HystrixObservableCommand; -import com.netflix.hystrix.HystrixObservableCommand.Setter; -import com.netflix.hystrix.exception.HystrixRuntimeException; -import reactor.core.publisher.Mono; -import reactor.util.context.Context; -import rx.Observable; -import rx.RxReactiveStreams; -import rx.Subscription; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.cloud.gateway.filter.GatewayFilter; -import org.springframework.cloud.gateway.filter.GatewayFilterChain; -import org.springframework.cloud.gateway.support.ServiceUnavailableException; -import org.springframework.cloud.gateway.support.TimeoutException; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.reactive.DispatcherHandler; -import org.springframework.web.server.ResponseStatusException; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.util.UriComponentsBuilder; - -import static java.util.Collections.singletonList; -import static java.util.Optional.ofNullable; -import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.containsEncodedParts; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.removeAlreadyRouted; - -/** - * Depends on `spring-cloud-starter-netflix-hystrix`, - * {@see https://cloud.spring.io/spring-cloud-netflix/}. - * - * @author Spencer Gibb - * @author Michele Mancioppi - * @author Olga Maciaszek-Sharma - */ -public class HystrixGatewayFilterFactory - extends AbstractGatewayFilterFactory { - - private final ObjectProvider dispatcherHandlerProvider; - - // do not use this dispatcherHandler directly, use getDispatcherHandler() instead. - private volatile DispatcherHandler dispatcherHandler; - - public HystrixGatewayFilterFactory( - ObjectProvider dispatcherHandlerProvider) { - super(Config.class); - this.dispatcherHandlerProvider = dispatcherHandlerProvider; - } - - private DispatcherHandler getDispatcherHandler() { - if (dispatcherHandler == null) { - dispatcherHandler = dispatcherHandlerProvider.getIfAvailable(); - } - - return dispatcherHandler; - } - - @Override - public List shortcutFieldOrder() { - return singletonList(NAME_KEY); - } - - @Override - // TODO: make Config implement HasRouteId and remove this method. - public GatewayFilter apply(String routeId, Consumer consumer) { - Config config = newConfig(); - consumer.accept(config); - - if (StringUtils.isEmpty(config.getName()) && !StringUtils.isEmpty(routeId)) { - config.setName(routeId); - } - - return apply(config); - } - - /** - * Create a {@link Setter} based on incoming request attribute.
- * This could be useful for example to create a Setter with {@link HystrixCommandKey} - * being set as the target service's host:port, as obtained from - * {@link ServerWebExchange#getRequest()} to do per service instance level circuit - * breaking. - */ - protected Setter createCommandSetter(Config config, ServerWebExchange exchange) { - return config.setter; - } - - @Override - public GatewayFilter apply(Config config) { - // TODO: if no name is supplied, generate one from command id (useful for default - // filter) - if (config.setter == null) { - Assert.notNull(config.name, - "A name must be supplied for the Hystrix Command Key"); - HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory - .asKey(getClass().getSimpleName()); - HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey(config.name); - - config.setter = Setter.withGroupKey(groupKey).andCommandKey(commandKey); - } - - return new GatewayFilter() { - @Override - public Mono filter(ServerWebExchange exchange, - GatewayFilterChain chain) { - return Mono.deferWithContext(context -> { - RouteHystrixCommand command = new RouteHystrixCommand( - createCommandSetter(config, exchange), config.fallbackUri, - exchange, chain, context); - - return Mono.create(s -> { - Subscription sub = command.toObservable().subscribe(s::success, - s::error, s::success); - s.onCancel(sub::unsubscribe); - }).onErrorResume((Function>) throwable -> { - if (throwable instanceof HystrixRuntimeException) { - HystrixRuntimeException e = (HystrixRuntimeException) throwable; - HystrixRuntimeException.FailureType failureType = e - .getFailureType(); - - switch (failureType) { - case TIMEOUT: - return Mono.error(new TimeoutException()); - case SHORTCIRCUIT: - return Mono.error(new ServiceUnavailableException()); - case COMMAND_EXCEPTION: { - Throwable cause = e.getCause(); - - /* - * We forsake here the null check for cause as - * HystrixRuntimeException will always have a cause if the - * failure type is COMMAND_EXCEPTION. - */ - if (cause instanceof ResponseStatusException - || AnnotatedElementUtils.findMergedAnnotation( - cause.getClass(), - ResponseStatus.class) != null) { - return Mono.error(cause); - } - } - default: - break; - } - } - return Mono.error(throwable); - }).then(); - }); - } - - @Override - public String toString() { - return filterToStringCreator(HystrixGatewayFilterFactory.this) - .append("name", config.getName()) - .append("fallback", config.fallbackUri).toString(); - } - }; - } - - public static class Config { - - private String name; - - private Setter setter; - - private URI fallbackUri; - - public String getName() { - return name; - } - - public Config setName(String name) { - this.name = name; - return this; - } - - public Config setFallbackUri(String fallbackUri) { - if (fallbackUri != null) { - setFallbackUri(URI.create(fallbackUri)); - } - return this; - } - - public URI getFallbackUri() { - return fallbackUri; - } - - public void setFallbackUri(URI fallbackUri) { - if (fallbackUri != null && !"forward".equals(fallbackUri.getScheme())) { - throw new IllegalArgumentException( - "Hystrix Filter currently only supports 'forward' URIs, found " - + fallbackUri); - } - this.fallbackUri = fallbackUri; - } - - public Config setSetter(Setter setter) { - this.setter = setter; - return this; - } - - } - - // TODO: replace with HystrixMonoCommand that we write - private class RouteHystrixCommand extends HystrixObservableCommand { - - private final URI fallbackUri; - - private final ServerWebExchange exchange; - - private final GatewayFilterChain chain; - - private final Context context; - - RouteHystrixCommand(Setter setter, URI fallbackUri, ServerWebExchange exchange, - GatewayFilterChain chain, Context context) { - super(setter); - this.fallbackUri = fallbackUri; - this.exchange = exchange; - this.chain = chain; - this.context = context; - } - - @Override - protected Observable construct() { - return RxReactiveStreams - .toObservable(this.chain.filter(exchange).subscriberContext(context)); - } - - @Override - protected Observable resumeWithFallback() { - if (this.fallbackUri == null) { - return super.resumeWithFallback(); - } - - // TODO: copied from RouteToRequestUrlFilter - URI uri = exchange.getRequest().getURI(); - // TODO: assume always? - boolean encoded = containsEncodedParts(uri); - URI requestUrl = UriComponentsBuilder.fromUri(uri).host(null).port(null) - .uri(this.fallbackUri).scheme(null).build(encoded).toUri(); - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl); - addExceptionDetails(); - - ServerHttpRequest request = this.exchange.getRequest().mutate() - .uri(requestUrl).build(); - ServerWebExchange mutated = exchange.mutate().request(request).build(); - // Before we continue on remove the already routed attribute since the - // fallback may go back through the route handler if the fallback - // is to another route in the Gateway - removeAlreadyRouted(mutated); - return RxReactiveStreams.toObservable(getDispatcherHandler().handle(mutated)); - } - - private void addExceptionDetails() { - Throwable executionException = getExecutionException(); - ofNullable(executionException).ifPresent(exception -> exchange.getAttributes() - .put(HYSTRIX_EXECUTION_EXCEPTION_ATTR, exception)); - } - - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerHystrixFilterFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerHystrixFilterFactory.java deleted file mode 100644 index fd026ed8..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerHystrixFilterFactory.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.filter.factory; - -import com.netflix.hystrix.exception.HystrixRuntimeException; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.cloud.client.circuitbreaker.ReactiveCircuitBreakerFactory; -import org.springframework.cloud.gateway.support.ServiceUnavailableException; -import org.springframework.cloud.gateway.support.TimeoutException; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.reactive.DispatcherHandler; -import org.springframework.web.server.ResponseStatusException; - -/** - * @author Ryan Baxter - */ -public class SpringCloudCircuitBreakerHystrixFilterFactory - extends SpringCloudCircuitBreakerFilterFactory { - - public SpringCloudCircuitBreakerHystrixFilterFactory( - ReactiveCircuitBreakerFactory reactiveCircuitBreakerFactory, - ObjectProvider dispatcherHandlerProvider) { - super(reactiveCircuitBreakerFactory, dispatcherHandlerProvider); - } - - @Override - protected Mono handleErrorWithoutFallback(Throwable throwable) { - if (throwable instanceof HystrixRuntimeException) { - HystrixRuntimeException e = (HystrixRuntimeException) throwable; - HystrixRuntimeException.FailureType failureType = e.getFailureType(); - - switch (failureType) { - case TIMEOUT: - return Mono.error(new TimeoutException()); - case SHORTCIRCUIT: - return Mono.error(new ServiceUnavailableException()); - case COMMAND_EXCEPTION: { - Throwable cause = e.getCause(); - - /* - * We forsake here the null check for cause as HystrixRuntimeException - * will always have a cause if the failure type is COMMAND_EXCEPTION. - */ - if (cause instanceof ResponseStatusException - || AnnotatedElementUtils.findMergedAnnotation(cause.getClass(), - ResponseStatus.class) != null) { - return Mono.error(cause); - } - } - default: - break; - } - } - return Mono.error(throwable); - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java index df8aca99..a6bdfbbb 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/route/builder/GatewayFilterSpec.java @@ -42,7 +42,6 @@ import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGateway import org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.DedupeResponseHeaderGatewayFilterFactory.Strategy; import org.springframework.cloud.gateway.filter.factory.FallbackHeadersGatewayFilterFactory; -import org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.MapRequestHeaderGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.PrefixPathGatewayFilterFactory; import org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory; @@ -74,7 +73,6 @@ import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter; import org.springframework.cloud.gateway.route.Route; import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; -import org.springframework.util.StringUtils; import org.springframework.util.unit.DataSize; import org.springframework.web.server.ServerWebExchange; @@ -199,27 +197,6 @@ public class GatewayFilterSpec extends UriSpec { c -> c.setStrategy(Strategy.valueOf(strategy)).setName(headerName))); } - /** - * Wraps the route in a Hystrix command. Depends on @{code - * org.springframework.cloud::spring-cloud-starter-netflix-hystrix} being on the - * classpath, {@see https://cloud.spring.io/spring-cloud-netflix/} - * @param configConsumer a {@link Consumer} which provides configuration for the - * Hystrix command - * @return a {@link GatewayFilterSpec} that can be used to apply additional filters - */ - public GatewayFilterSpec hystrix( - Consumer configConsumer) { - HystrixGatewayFilterFactory factory; - try { - factory = getBean(HystrixGatewayFilterFactory.class); - } - catch (NoSuchBeanDefinitionException e) { - throw new NoSuchBeanDefinitionException(HystrixGatewayFilterFactory.class, - "This is probably because Hystrix is missing from the classpath, which can be resolved by adding dependency on 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'"); - } - return filter(factory.apply(this.routeBuilder.getId(), configConsumer)); - } - public GatewayFilterSpec circuitBreaker( Consumer configConsumer) { SpringCloudCircuitBreakerFilterFactory filterFactory; diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ConfigurationUtils.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ConfigurationUtils.java deleted file mode 100644 index 621cf998..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ConfigurationUtils.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.support; - -import java.util.Map; - -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.core.convert.ConversionService; -import org.springframework.validation.Validator; - -@Deprecated -public abstract class ConfigurationUtils { - - @Deprecated - public static void bind(Object o, Map properties, - String configurationPropertyName, String bindingName, Validator validator) { - bind(o, properties, configurationPropertyName, bindingName, validator, null); - } - - @Deprecated - public static void bind(Object o, Map properties, - String configurationPropertyName, String bindingName, Validator validator, - ConversionService conversionService) { - Object toBind = getTargetObject(o); - Bindable bindable = Bindable.ofInstance(toBind); - ConfigurationService.bindOrCreate(bindable, properties, - configurationPropertyName/* , bindingName */, validator, - conversionService); - } - - @Deprecated - @SuppressWarnings("unchecked") - public static T getTargetObject(Object candidate) { - return ConfigurationService.getTargetObject(candidate); - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultClientResponse.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultClientResponse.java deleted file mode 100644 index c215e9d2..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultClientResponse.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.support; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.OptionalLong; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.io.buffer.DataBufferUtils; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseCookie; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.reactive.ClientHttpResponse; -import org.springframework.http.codec.HttpMessageReader; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.util.MultiValueMap; -import org.springframework.web.reactive.function.BodyExtractor; -import org.springframework.web.reactive.function.BodyExtractors; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.ExchangeStrategies; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -/** - * Default implementation of {@link ClientResponse}. - * - * @author Arjen Poutsma - * @author Brian Clozel - * @since 5.0 - * @deprecated Will be removed in future release. - */ -@Deprecated -public class DefaultClientResponse implements ClientResponse { - - private final ClientHttpResponse response; - - private final Headers headers; - - private final ExchangeStrategies strategies; - - public DefaultClientResponse(ClientHttpResponse response, - ExchangeStrategies strategies) { - this.response = response; - this.strategies = strategies; - this.headers = new DefaultHeaders(); - } - - @Override - public ExchangeStrategies strategies() { - return this.strategies; - } - - @Override - public HttpStatus statusCode() { - return this.response.getStatusCode(); - } - - @Override - public int rawStatusCode() { - return this.response.getRawStatusCode(); - } - - @Override - public Headers headers() { - return this.headers; - } - - @Override - public MultiValueMap cookies() { - return this.response.getCookies(); - } - - @Override - public T body(BodyExtractor extractor) { - return extractor.extract(this.response, new BodyExtractor.Context() { - @Override - public List> messageReaders() { - return strategies.messageReaders(); - } - - @Override - public Optional serverResponse() { - return Optional.empty(); - } - - @Override - public Map hints() { - return Collections.emptyMap(); - } - }); - } - - @Override - public Mono bodyToMono(Class elementClass) { - if (Void.class.isAssignableFrom(elementClass)) { - return consumeAndCancel(); - } - else { - return body(BodyExtractors.toMono(elementClass)); - } - } - - @Override - public Mono releaseBody() { - return body(BodyExtractors.toDataBuffers()).map(DataBufferUtils::release).then(); - } - - @Override - public Mono> toBodilessEntity() { - return releaseBody().then(toEntityInternal(Mono.empty())); - } - - @Override - public Mono createException() { - throw new UnsupportedOperationException(); - } - - @SuppressWarnings("unchecked") - private Mono consumeAndCancel() { - return (Mono) this.response.getBody().map(buffer -> { - DataBufferUtils.release(buffer); - throw new ReadCancellationException(); - }).onErrorResume(ReadCancellationException.class, ex -> Mono.empty()).then(); - } - - @Override - public Mono bodyToMono(ParameterizedTypeReference typeReference) { - if (Void.class.isAssignableFrom(typeReference.getType().getClass())) { - return consumeAndCancel(); - } - else { - return body(BodyExtractors.toMono(typeReference)); - } - } - - @Override - public Flux bodyToFlux(Class elementClass) { - if (Void.class.isAssignableFrom(elementClass)) { - return Flux.from(consumeAndCancel()); - } - else { - return body(BodyExtractors.toFlux(elementClass)); - } - } - - @Override - public Flux bodyToFlux(ParameterizedTypeReference typeReference) { - if (Void.class.isAssignableFrom(typeReference.getType().getClass())) { - return Flux.from(consumeAndCancel()); - } - else { - return body(BodyExtractors.toFlux(typeReference)); - } - } - - @Override - public Mono> toEntity(Class bodyType) { - if (Void.class.isAssignableFrom(bodyType)) { - return toEntityInternal(consumeAndCancel()); - } - else { - return toEntityInternal(bodyToMono(bodyType)); - } - } - - @Override - public Mono> toEntity( - ParameterizedTypeReference typeReference) { - if (Void.class.isAssignableFrom(typeReference.getType().getClass())) { - return toEntityInternal(consumeAndCancel()); - } - else { - return toEntityInternal(bodyToMono(typeReference)); - } - } - - private Mono> toEntityInternal(Mono bodyMono) { - HttpHeaders headers = headers().asHttpHeaders(); - HttpStatus statusCode = statusCode(); - return bodyMono.map(body -> new ResponseEntity<>(body, headers, statusCode)) - .switchIfEmpty(Mono.defer( - () -> Mono.just(new ResponseEntity<>(headers, statusCode)))); - } - - @Override - public Mono>> toEntityList(Class responseType) { - return toEntityListInternal(bodyToFlux(responseType)); - } - - @Override - public Mono>> toEntityList( - ParameterizedTypeReference typeReference) { - return toEntityListInternal(bodyToFlux(typeReference)); - } - - private Mono>> toEntityListInternal(Flux bodyFlux) { - HttpHeaders headers = headers().asHttpHeaders(); - HttpStatus statusCode = statusCode(); - return bodyFlux.collectList() - .map(body -> new ResponseEntity<>(body, headers, statusCode)); - } - - @SuppressWarnings("serial") - private static class ReadCancellationException extends RuntimeException { - - } - - private class DefaultHeaders implements Headers { - - private HttpHeaders delegate() { - return response.getHeaders(); - } - - @Override - public OptionalLong contentLength() { - return toOptionalLong(delegate().getContentLength()); - } - - @Override - public Optional contentType() { - return Optional.ofNullable(delegate().getContentType()); - } - - @Override - public List header(String headerName) { - List headerValues = delegate().get(headerName); - return (headerValues != null ? headerValues : Collections.emptyList()); - } - - @Override - public HttpHeaders asHttpHeaders() { - return HttpHeaders.readOnlyHttpHeaders(delegate()); - } - - private OptionalLong toOptionalLong(long value) { - return (value != -1 ? OptionalLong.of(value) : OptionalLong.empty()); - } - - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultServerRequest.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultServerRequest.java deleted file mode 100644 index 22bd0c3d..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultServerRequest.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.support; - -import java.net.InetSocketAddress; -import java.net.URI; -import java.nio.charset.Charset; -import java.security.Principal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; -import java.util.OptionalLong; -import java.util.function.Function; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpCookie; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRange; -import org.springframework.http.HttpRequest; -import org.springframework.http.MediaType; -import org.springframework.http.codec.HttpMessageReader; -import org.springframework.http.codec.multipart.Part; -import org.springframework.http.server.PathContainer; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.util.MultiValueMap; -import org.springframework.web.reactive.function.BodyExtractor; -import org.springframework.web.reactive.function.BodyExtractors; -import org.springframework.web.reactive.function.UnsupportedMediaTypeException; -import org.springframework.web.reactive.function.server.HandlerStrategies; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.UnsupportedMediaTypeStatusException; -import org.springframework.web.server.WebSession; -import org.springframework.web.util.UriBuilder; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * {@code ServerRequest} implementation based on a {@link ServerWebExchange}. - * - * @author Arjen Poutsma - * @since 5.0 - * @deprecated Will be removed in a future release. - */ -@Deprecated -public class DefaultServerRequest implements ServerRequest { - - private static final Function ERROR_MAPPER = ex -> (ex - .getContentType() != null - ? new UnsupportedMediaTypeStatusException(ex.getContentType(), - ex.getSupportedMediaTypes()) - : new UnsupportedMediaTypeStatusException(ex.getMessage())); - - private final ServerWebExchange exchange; - - private final Headers headers; - - private final List> messageReaders; - - public DefaultServerRequest(ServerWebExchange exchange) { - this(exchange, HandlerStrategies.withDefaults().messageReaders()); - } - - public DefaultServerRequest(ServerWebExchange exchange, - List> messageReaders) { - this.exchange = exchange; - this.messageReaders = Collections - .unmodifiableList(new ArrayList<>(messageReaders)); - this.headers = new DefaultHeaders(); - } - - @Override - public String methodName() { - return request().getMethodValue(); - } - - @Override - public URI uri() { - return request().getURI(); - } - - @Override - public UriBuilder uriBuilder() { - return UriComponentsBuilder.fromHttpRequest(new ServerRequestAdapter()); - } - - @Override - public PathContainer pathContainer() { - return request().getPath(); - } - - @Override - public Headers headers() { - return this.headers; - } - - @Override - public MultiValueMap cookies() { - return request().getCookies(); - } - - @Override - public T body(BodyExtractor extractor) { - return body(extractor, Collections.emptyMap()); - } - - @Override - public Optional remoteAddress() { - return Optional.of(request().getRemoteAddress()); - } - - @Override - public List> messageReaders() { - return this.messageReaders; - } - - @Override - public T body(BodyExtractor extractor, - Map hints) { - return extractor.extract(request(), new BodyExtractor.Context() { - @Override - public List> messageReaders() { - return messageReaders; - } - - @Override - public Optional serverResponse() { - return Optional.of(exchange().getResponse()); - } - - @Override - public Map hints() { - return hints; - } - }); - } - - @Override - public Mono bodyToMono(Class elementClass) { - Mono mono = body(BodyExtractors.toMono(elementClass)); - return mono.onErrorMap(UnsupportedMediaTypeException.class, ERROR_MAPPER); - } - - @Override - public Mono bodyToMono(ParameterizedTypeReference typeReference) { - Mono mono = body(BodyExtractors.toMono(typeReference)); - return mono.onErrorMap(UnsupportedMediaTypeException.class, ERROR_MAPPER); - } - - @Override - public Flux bodyToFlux(Class elementClass) { - Flux flux = body(BodyExtractors.toFlux(elementClass)); - return flux.onErrorMap(UnsupportedMediaTypeException.class, ERROR_MAPPER); - } - - @Override - public Flux bodyToFlux(ParameterizedTypeReference typeReference) { - Flux flux = body(BodyExtractors.toFlux(typeReference)); - return flux.onErrorMap(UnsupportedMediaTypeException.class, ERROR_MAPPER); - } - - @Override - public Map attributes() { - return this.exchange.getAttributes(); - } - - @Override - public MultiValueMap queryParams() { - return request().getQueryParams(); - } - - @Override - public Map pathVariables() { - return this.exchange.getAttributeOrDefault( - RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE, Collections.emptyMap()); - } - - @Override - public Mono session() { - return this.exchange.getSession(); - } - - @Override - public Mono principal() { - return this.exchange.getPrincipal(); - } - - @Override - public Mono> formData() { - return this.exchange.getFormData(); - } - - @Override - public Mono> multipartData() { - return this.exchange.getMultipartData(); - } - - private ServerHttpRequest request() { - return this.exchange.getRequest(); - } - - public ServerWebExchange exchange() { - return this.exchange; - } - - @Override - public String toString() { - return String.format("%s %s", method(), path()); - } - - private class DefaultHeaders implements Headers { - - private HttpHeaders delegate() { - return request().getHeaders(); - } - - @Override - public List accept() { - return delegate().getAccept(); - } - - @Override - public List acceptCharset() { - return delegate().getAcceptCharset(); - } - - @Override - public List acceptLanguage() { - return delegate().getAcceptLanguage(); - } - - @Override - public OptionalLong contentLength() { - long value = delegate().getContentLength(); - return (value != -1 ? OptionalLong.of(value) : OptionalLong.empty()); - } - - @Override - public Optional contentType() { - return Optional.ofNullable(delegate().getContentType()); - } - - @Override - public InetSocketAddress host() { - return delegate().getHost(); - } - - @Override - public List range() { - return delegate().getRange(); - } - - @Override - public List header(String headerName) { - List headerValues = delegate().get(headerName); - return (headerValues != null ? headerValues : Collections.emptyList()); - } - - @Override - public HttpHeaders asHttpHeaders() { - return HttpHeaders.readOnlyHttpHeaders(delegate()); - } - - @Override - public String toString() { - return delegate().toString(); - } - - } - - private final class ServerRequestAdapter implements HttpRequest { - - @Override - public String getMethodValue() { - return methodName(); - } - - @Override - public URI getURI() { - return uri(); - } - - @Override - public HttpHeaders getHeaders() { - return request().getHeaders(); - } - - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultServerResponse.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultServerResponse.java deleted file mode 100644 index d9f175ad..00000000 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/DefaultServerResponse.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.support; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import reactor.core.publisher.Mono; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseCookie; -import org.springframework.http.codec.HttpMessageWriter; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.util.Assert; -import org.springframework.util.MultiValueMap; -import org.springframework.web.reactive.function.BodyInserter; -import org.springframework.web.reactive.function.server.HandlerStrategies; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.reactive.result.view.ViewResolver; -import org.springframework.web.server.ServerWebExchange; - -@Deprecated -public class DefaultServerResponse implements ServerResponse { - - private final ServerWebExchange exchange; - - private final BodyInserter inserter; - - private final Map hints; - - public DefaultServerResponse(ServerWebExchange exchange, - BodyInserter body, Map hints) { - this.exchange = exchange; - Assert.notNull(exchange, "ServerWebExchange must not be null"); - Assert.notNull(body, "BodyInserter must not be null"); - this.inserter = body; - this.hints = hints; - } - - private ServerHttpResponse response() { - return exchange.getResponse(); - } - - @Override - public final HttpStatus statusCode() { - // TODO: non standard status code - return HttpStatus.valueOf(response().getStatusCode().value()); - } - - @Override - public int rawStatusCode() { - return response().getStatusCode().value(); - } - - @Override - public final HttpHeaders headers() { - return response().getHeaders(); - } - - @Override - public MultiValueMap cookies() { - return response().getCookies(); - } - - @Override - public final Mono writeTo(ServerWebExchange exchange, Context context) { - return this.inserter.insert(exchange.getResponse(), new BodyInserter.Context() { - @Override - public List> messageWriters() { - return context.messageWriters(); - } - - @Override - public Optional serverRequest() { - return Optional.of(exchange.getRequest()); - } - - @Override - public Map hints() { - return hints; - } - }); - } - - public static class HandlerStrategiesResponseContext - implements ServerResponse.Context { - - private HandlerStrategies strategies = HandlerStrategies.withDefaults(); - - public HandlerStrategiesResponseContext() { - } - - public HandlerStrategiesResponseContext(HandlerStrategies strategies) { - this.strategies = strategies; - } - - @Override - public List> messageWriters() { - return this.strategies.messageWriters(); - } - - @Override - public List viewResolvers() { - return this.strategies.viewResolvers(); - } - - } - -} diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java index ca90c619..678591ff 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java @@ -122,12 +122,6 @@ public final class ServerWebExchangeUtils { */ public static final String ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR = "original_response_content_type"; - /** - * Hystrix execution exception attribute name. - */ - public static final String HYSTRIX_EXECUTION_EXCEPTION_ATTR = qualify( - "hystrixExecutionException"); - /** * CircuitBreaker execution exception attribute name. */ diff --git a/spring-cloud-gateway-core/src/main/resources/META-INF/spring.factories b/spring-cloud-gateway-core/src/main/resources/META-INF/spring.factories index 5019e783..989a1afb 100644 --- a/spring-cloud-gateway-core/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-gateway-core/src/main/resources/META-INF/spring.factories @@ -2,9 +2,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration,\ org.springframework.cloud.gateway.config.GatewayAutoConfiguration,\ -org.springframework.cloud.gateway.config.GatewayHystrixCircuitBreakerAutoConfiguration,\ org.springframework.cloud.gateway.config.GatewayResilience4JCircuitBreakerAutoConfiguration,\ -org.springframework.cloud.gateway.config.GatewayLoadBalancerClientAutoConfiguration,\ org.springframework.cloud.gateway.config.GatewayNoLoadBalancerClientAutoConfiguration,\ org.springframework.cloud.gateway.config.GatewayMetricsAutoConfiguration,\ org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration,\ diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/config/GatewayNoLoadBalancerClientAutoConfigurationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/config/GatewayNoLoadBalancerClientAutoConfigurationTests.java index 7500b225..956c3dcc 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/config/GatewayNoLoadBalancerClientAutoConfigurationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/config/GatewayNoLoadBalancerClientAutoConfigurationTests.java @@ -36,8 +36,7 @@ import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.SocketUtils; @RunWith(ModifiedClassPathRunner.class) -@ClassPathExclusions({ "spring-cloud-netflix-ribbon-*.jar", - "spring-cloud-loadbalancer-*.jar" }) +@ClassPathExclusions({ "spring-cloud-loadbalancer-*.jar" }) public class GatewayNoLoadBalancerClientAutoConfigurationTests { private static int port; @@ -65,7 +64,7 @@ public class GatewayNoLoadBalancerClientAutoConfigurationTests { public static class Config { @Bean - public RouteLocator hystrixRouteLocator(RouteLocatorBuilder builder) { + public RouteLocator routeLocator(RouteLocatorBuilder builder) { return builder.routes() .route("lb_fail", r -> r.host("**.lbfail.org").uri("lb://fail")) .build(); diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilterTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilterTests.java deleted file mode 100644 index cd50fb3b..00000000 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/LoadBalancerClientFilterTests.java +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright 2017-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.filter; - -import java.net.URI; -import java.util.LinkedHashSet; - -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.gateway.config.LoadBalancerProperties; -import org.springframework.cloud.gateway.support.NotFoundException; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext; -import org.springframework.cloud.netflix.ribbon.SpringClientFactory; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.mock.http.server.reactive.MockServerHttpRequest; -import org.springframework.mock.web.server.MockServerWebExchange; -import org.springframework.util.StringUtils; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR; - -/** - * @author Spencer Gibb - * @author Tim Ysewyn - */ -@RunWith(MockitoJUnitRunner.class) -public class LoadBalancerClientFilterTests { - - private ServerWebExchange exchange; - - private LoadBalancerProperties properties; - - @Mock - private GatewayFilterChain chain; - - @Mock - private LoadBalancerClient loadBalancerClient; - - private LoadBalancerClientFilter loadBalancerClientFilter; - - @Before - public void setup() { - properties = new LoadBalancerProperties(); - loadBalancerClientFilter = new LoadBalancerClientFilter(loadBalancerClient, - properties); - exchange = MockServerWebExchange - .from(MockServerHttpRequest.get("loadbalancerclient.org").build()); - } - - @Test - public void shouldNotFilterWhenGatewayRequestUrlIsMissing() { - loadBalancerClientFilter.filter(exchange, chain); - - verify(chain).filter(exchange); - verifyNoMoreInteractions(chain); - verifyNoInteractions(loadBalancerClient); - } - - @Test - public void shouldNotFilterWhenGatewayRequestUrlSchemeIsNotLb() { - URI uri = UriComponentsBuilder.fromUriString("http://myservice").build().toUri(); - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri); - - loadBalancerClientFilter.filter(exchange, chain); - - verify(chain).filter(exchange); - verifyNoMoreInteractions(chain); - verifyNoInteractions(loadBalancerClient); - } - - @Test - public void shouldThrowExceptionWhenNoServiceInstanceIsFound() { - URI uri = UriComponentsBuilder.fromUriString("lb://myservice").build().toUri(); - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri); - - try { - loadBalancerClientFilter.filter(exchange, chain); - } - catch (NotFoundException e) { - assertThat(e.getStatus()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE); - } - catch (Exception e) { - throw e; - } - } - - @Test - public void shouldThrow4O4ExceptionWhenNoServiceInstanceIsFound() { - URI uri = UriComponentsBuilder.fromUriString("lb://myservice").build().toUri(); - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri); - properties.setUse404(true); - try { - loadBalancerClientFilter.filter(exchange, chain); - } - catch (NotFoundException e) { - assertThat(e.getStatus()).isEqualTo(HttpStatus.NOT_FOUND); - } - catch (Exception e) { - throw e; - } - } - - @Test - public void shouldFilter() { - URI url = UriComponentsBuilder.fromUriString("lb://myservice").build().toUri(); - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, url); - - ServiceInstance serviceInstance = new DefaultServiceInstance("myservice1", - "myservice", "localhost", 8080, true); - when(loadBalancerClient.choose("myservice")).thenReturn(serviceInstance); - - URI requestUrl = UriComponentsBuilder.fromUriString("https://localhost:8080") - .build().toUri(); - when(loadBalancerClient.reconstructURI(any(ServiceInstance.class), - any(URI.class))).thenReturn(requestUrl); - - loadBalancerClientFilter.filter(exchange, chain); - - LinkedHashSet attribute = exchange - .getAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR); - assertThat(attribute).contains(url); - - verify(loadBalancerClient).choose("myservice"); - - ArgumentCaptor urlArgumentCaptor = ArgumentCaptor.forClass(URI.class); - verify(loadBalancerClient).reconstructURI(any(), urlArgumentCaptor.capture()); - - URI uri = urlArgumentCaptor.getValue(); - assertThat(uri).isNotNull(); - assertThat(uri.toString()).isEqualTo("loadbalancerclient.org"); - - verifyNoMoreInteractions(loadBalancerClient); - - assertThat((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)) - .isEqualTo(requestUrl); - - verify(chain).filter(exchange); - verifyNoMoreInteractions(chain); - } - - @Test - public void instanceOverrideNonSecureScheme() { - MockServerHttpRequest request = MockServerHttpRequest.get("https://localhost") - .build(); - - URI lbUri = URI.create("lb://service1"); - ServerWebExchange webExchange = testFilter(request, lbUri); - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("http").hasHost("service1-host1"); - } - - @Test - public void instanceOverrideSecureScheme() { - MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost") - .build(); - - URI lbUri = URI.create("lb://service1"); - ServerWebExchange webExchange = testFilter(request, lbUri, 443); - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("https").hasHost("service1-host1"); - } - - @Test - public void instanceOverrideSecureSchemePrefix() { - MockServerHttpRequest request = MockServerHttpRequest.get("https://localhost") - .build(); - - URI lbUri = URI.create("http://service1"); - ServerWebExchange exchange = MockServerWebExchange.from(request); - exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, "lb"); - ServerWebExchange webExchange = testFilter(exchange, lbUri, 443); - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("http").hasHost("service1-host1"); - } - - @Test - public void instanceOverrideNonSecureSchemePrefix() { - MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost") - .build(); - - URI lbUri = URI.create("https://service1"); - ServerWebExchange exchange = MockServerWebExchange.from(request); - exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, "lb"); - ServerWebExchange webExchange = testFilter(exchange, lbUri, 8081); - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("https").hasHost("service1-host1"); - } - - @Test - public void happyPath() { - MockServerHttpRequest request = MockServerHttpRequest - .get("http://localhost/get?a=b").build(); - - URI lbUri = URI.create("lb://service1?a=b"); - ServerWebExchange webExchange = testFilter(request, lbUri); - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("http").hasHost("service1-host1").hasParameter("a", - "b"); - } - - @Test - public void noQueryParams() { - MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost/get") - .build(); - - ServerWebExchange webExchange = testFilter(request, URI.create("lb://service1")); - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("http").hasHost("service1-host1"); - } - - @Test - public void encodedParameters() { - URI url = UriComponentsBuilder.fromUriString("http://localhost/get?a=b&c=d[]") - .buildAndExpand().encode().toUri(); - - MockServerHttpRequest request = MockServerHttpRequest.method(HttpMethod.GET, url) - .build(); - - URI lbUrl = UriComponentsBuilder.fromUriString("lb://service1?a=b&c=d[]") - .buildAndExpand().encode().toUri(); - - // prove that it is encoded - assertThat(lbUrl.getRawQuery()).isEqualTo("a=b&c=d%5B%5D"); - - assertThat(lbUrl).hasParameter("c", "d[]"); - - ServerWebExchange webExchange = testFilter(request, lbUrl); - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("http").hasHost("service1-host1").hasParameter("a", "b") - .hasParameter("c", "d[]"); - - // prove that it is not double encoded - assertThat(uri.getRawQuery()).isEqualTo("a=b&c=d%5B%5D"); - } - - @Test - public void unencodedParameters() { - URI url = URI.create("http://localhost/get?a=b&c=d[]"); - - MockServerHttpRequest request = MockServerHttpRequest.method(HttpMethod.GET, url) - .build(); - - URI lbUrl = URI.create("lb://service1?a=b&c=d[]"); - - // prove that it is unencoded - assertThat(lbUrl.getRawQuery()).isEqualTo("a=b&c=d[]"); - - ServerWebExchange webExchange = testFilter(request, lbUrl); - - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("http").hasHost("service1-host1").hasParameter("a", "b") - .hasParameter("c", "d[]"); - - // prove that it is NOT encoded - assertThat(uri.getRawQuery()).isEqualTo("a=b&c=d[]"); - } - - @Test - public void happyPathWithAttributeRatherThanScheme() { - MockServerHttpRequest request = MockServerHttpRequest - .get("ws://localhost/get?a=b").build(); - - URI lbUri = URI.create("ws://service1?a=b"); - - exchange = MockServerWebExchange.from(request); - exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, "lb"); - - ServerWebExchange webExchange = testFilter(exchange, lbUri, 8081); - URI uri = webExchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); - assertThat(uri).hasScheme("ws").hasHost("service1-host1").hasParameter("a", "b"); - } - - @Test - public void shouldNotFilterWhenGatewaySchemePrefixAttrIsNotLb() { - URI uri = UriComponentsBuilder.fromUriString("http://myservice").build().toUri(); - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri); - exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, "xx"); - - loadBalancerClientFilter.filter(exchange, chain); - - verify(chain).filter(exchange); - verifyNoMoreInteractions(chain); - verifyNoInteractions(loadBalancerClient); - } - - @Test - public void shouldSelectSpecifiedServer() { - URI uri1 = UriComponentsBuilder.fromUriString("lb://myservice").port(11111) - .build().toUri(); - URI uri2 = UriComponentsBuilder.fromUriString("lb://myservice").port(22222) - .build().toUri(); - - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - ILoadBalancer loadBalancer = mock(ILoadBalancer.class); - when(clientFactory.getLoadBalancerContext("myservice")) - .thenReturn(new RibbonLoadBalancerContext(loadBalancer)); - when(clientFactory.getLoadBalancer("myservice")).thenReturn(loadBalancer); - - when(loadBalancer.chooseServer("11111")) - .thenReturn(new Server("myservice-host1", 8081)); - when(loadBalancer.chooseServer("22222")) - .thenReturn(new Server("myservice-host2", 8081)); - - LoadBalancerClient loadBalancerClient = new RibbonLoadBalancerClient( - clientFactory) { - private String loadBalancerKey; - - public ServiceInstance choose(String serviceId) { - String[] strings = serviceId.split("<<>>"); - loadBalancerKey = strings[1]; - return super.choose(strings[0], loadBalancerKey); - } - - protected Server getServer(ILoadBalancer loadBalancer) { - return loadBalancer == null ? null - : loadBalancer.chooseServer(StringUtils.isEmpty(loadBalancerKey) - ? "default" : loadBalancerKey); - } - }; - - LoadBalancerClientFilter loadBalancerClientFilter = new LoadBalancerClientFilter( - loadBalancerClient, properties) { - protected ServiceInstance choose(ServerWebExchange exchange) { - URI attribute = (URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR); - return loadBalancer - .choose(attribute.getHost() + "<<>>" + attribute.getPort()); - } - }; - - MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost/get") - .build(); - ServerWebExchange exchange = MockServerWebExchange.from(request); - - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri1); - loadBalancerClientFilter.filter(exchange, chain); - assertThat( - ((URI) exchange.getAttributes().get(GATEWAY_REQUEST_URL_ATTR)).getHost()) - .isEqualTo("myservice-host1"); - - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri2); - loadBalancerClientFilter.filter(exchange, chain); - assertThat( - ((URI) exchange.getAttributes().get(GATEWAY_REQUEST_URL_ATTR)).getHost()) - .isEqualTo("myservice-host2"); - } - - private ServerWebExchange testFilter(MockServerHttpRequest request, URI uri) { - return testFilter(MockServerWebExchange.from(request), uri, 8081); - } - - private ServerWebExchange testFilter(MockServerHttpRequest request, URI uri, - int port) { - return testFilter(MockServerWebExchange.from(request), uri, port); - } - - private ServerWebExchange testFilter(ServerWebExchange exchange, URI uri, int port) { - exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri); - - ArgumentCaptor captor = ArgumentCaptor - .forClass(ServerWebExchange.class); - when(chain.filter(captor.capture())).thenReturn(Mono.empty()); - - SpringClientFactory clientFactory = mock(SpringClientFactory.class); - ILoadBalancer loadBalancer = mock(ILoadBalancer.class); - - when(clientFactory.getLoadBalancerContext("service1")) - .thenReturn(new RibbonLoadBalancerContext(loadBalancer)); - when(clientFactory.getLoadBalancer("service1")).thenReturn(loadBalancer); - when(loadBalancer.chooseServer(any())) - .thenReturn(new Server("service1-host1", port)); - - RibbonLoadBalancerClient client = new RibbonLoadBalancerClient(clientFactory); - - LoadBalancerClientFilter filter = new LoadBalancerClientFilter(client, - properties); - filter.filter(exchange, chain); - - return captor.getValue(); - } - -} diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactoryPrincipalTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactoryPrincipalTests.java deleted file mode 100644 index 2d808de7..00000000 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactoryPrincipalTests.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.filter.factory; - -import java.security.Principal; -import java.util.Collections; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Test; -import org.junit.runner.RunWith; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.gateway.filter.GatewayFilter; -import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; -import org.springframework.cloud.gateway.filter.ratelimit.PrincipalNameKeyResolver; -import org.springframework.cloud.gateway.route.RouteLocator; -import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; -import org.springframework.cloud.gateway.test.BaseWebClientTests; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.context.annotation.Bean; -import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.web.server.SecurityWebFilterChain; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, properties = "debug=true") -@DirtiesContext -public class HystrixGatewayFilterFactoryPrincipalTests extends BaseWebClientTests { - - @Autowired - private TestPrincipalGatewayFilterFactory testFilterFactory; - - @Test - public void hystrixPrincipalNotLost() { - testClient.get().uri("/hystrixprincipal").headers(httpHeaders -> { - httpHeaders.setBasicAuth("user", "password"); - httpHeaders.set("Host", "www.hystrixsecurity.org"); - }).exchange().expectStatus().isOk().expectBody().jsonPath("$.principal") - .isEqualTo("user"); - assertThat(testFilterFactory.resolvedPrincipal).isEqualTo("user"); - } - - @RestController - @SpringBootConfiguration - @EnableAutoConfiguration - @RibbonClients({ - @RibbonClient(name = "testservice", configuration = TestRibbonConfig.class) }) - public static class TestConfig { - - @Value("${test.uri}") - private String uri; - - @RequestMapping("/httpbin/hystrixprincipal") - public Mono> hystrixPrincipal(Mono principal) { - return principal.map(Principal::getName).defaultIfEmpty("Unknown") - .map(s -> Collections.singletonMap("principal", s)); - } - - @Bean - public RouteLocator hystrixRouteLocator(RouteLocatorBuilder builder, - TestPrincipalGatewayFilterFactory filterFactory) { - return builder.routes() - .route("hystrix_security", r -> r.host("**.hystrixsecurity.org") - .filters(f -> f.prefixPath("/httpbin") - .hystrix(config -> config.setName("securitycmd")) - .filter(filterFactory.apply(""))) - .uri(uri)) - .build(); - } - - @Bean - public TestPrincipalGatewayFilterFactory testPrincipalGatewayFilterFactory() { - return new TestPrincipalGatewayFilterFactory(); - } - - @Bean - public RecursiveHttpbinFilter recursiveHttpbinFilter() { - return new RecursiveHttpbinFilter(); - } - - @Bean - SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) { - return http.httpBasic().and().authorizeExchange() - .pathMatchers("/hystrixprincipal").authenticated().anyExchange() - .permitAll().and().build(); - } - - @Bean - @SuppressWarnings("deprecation") - public MapReactiveUserDetailsService reactiveUserDetailsService() { - UserDetails user = User.withDefaultPasswordEncoder().username("user") - .password("password").roles("USER").build(); - return new MapReactiveUserDetailsService(user); - } - - } - - public static class TestPrincipalGatewayFilterFactory - extends AbstractGatewayFilterFactory { - - private final Log log = LogFactory - .getLog(TestPrincipalGatewayFilterFactory.class); - - private KeyResolver keyResolver = new PrincipalNameKeyResolver(); - - private String resolvedPrincipal; - - public TestPrincipalGatewayFilterFactory() { - super(Object.class); - } - - @Override - public GatewayFilter apply(Object config) { - return (exchange, chain) -> keyResolver.resolve(exchange) - .defaultIfEmpty("Empty Principal").flatMap(name -> { - resolvedPrincipal = name; - return chain.filter(exchange); - }); - } - - } - -} diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactoryTests.java deleted file mode 100644 index fc9696da..00000000 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixGatewayFilterFactoryTests.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.filter.factory; - -import com.netflix.config.ConfigurationManager; -import com.netflix.hystrix.Hystrix; -import com.netflix.hystrix.metric.consumer.HealthCountsStream; -import org.hamcrest.Matchers; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.gateway.filter.GatewayFilter; -import org.springframework.cloud.gateway.test.BaseWebClientTests; -import org.springframework.http.HttpStatus; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.core.StringContains.containsString; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.gateway.filter.factory.ExceptionFallbackHandler.RETRIEVED_EXCEPTION; -import static org.springframework.http.MediaType.APPLICATION_JSON; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, properties = "debug=true") -@ContextConfiguration(classes = HystrixTestConfig.class) -@DirtiesContext -public class HystrixGatewayFilterFactoryTests extends BaseWebClientTests { - - @Test - public void hystrixFilterWorks() { - testClient.get().uri("/get").header("Host", "www.hystrixsuccess.org").exchange() - .expectStatus().isOk().expectHeader() - .valueEquals(ROUTE_ID_HEADER, "hystrix_success_test"); - } - - @Test - public void hystrixFilterTimesout() { - testClient.get().uri("/delay/3").header("Host", "www.hystrixfailure.org") - .exchange().expectStatus().isEqualTo(HttpStatus.GATEWAY_TIMEOUT) - .expectBody().jsonPath("$.status") - .isEqualTo(String.valueOf(HttpStatus.GATEWAY_TIMEOUT.value())); - } - - @Test - public void hystrixFilterServiceUnavailable() { - HealthCountsStream.reset(); - Hystrix.reset(); - ConfigurationManager.getConfigInstance() - .setProperty("hystrix.command.failcmd.circuitBreaker.forceOpen", true); - - testClient.get().uri("/delay/3").header("Host", "www.hystrixfailure.org") - .exchange().expectStatus().isEqualTo(HttpStatus.SERVICE_UNAVAILABLE); - - HealthCountsStream.reset(); - Hystrix.reset(); - ConfigurationManager.getConfigInstance() - .setProperty("hystrix.command.failcmd.circuitBreaker.forceOpen", false); - } - - /* - * Tests that timeouts bubbling from the underpinning WebClient are treated the same - * as Hystrix timeouts in terms of outside response. (Internally, timeouts from the - * WebClient are seen as command failures and trigger the opening of circuit breakers - * the same way timeouts do; it may be confusing in terms of the Hystrix metrics - * though) - */ - @Test - public void hystrixTimeoutFromWebClient() { - testClient.get().uri("/delay/10").header("Host", "www.hystrixresponsestall.org") - .exchange().expectStatus().isEqualTo(HttpStatus.GATEWAY_TIMEOUT); - } - - @Test - public void hystrixFilterFallback() { - testClient.get().uri("/delay/3?a=b").header("Host", "www.hystrixfallback.org") - .exchange().expectStatus().isOk().expectBody() - .json("{\"from\":\"fallbackcontroller\"}"); - } - - @Test - public void hystrixFilterExceptionFallback() { - testClient.get().uri("/delay/3") - .header("Host", "www.hystrixexceptionfallback.org").exchange() - .expectStatus().isOk().expectHeader() - .value(RETRIEVED_EXCEPTION, containsString("HystrixTimeoutException")); - } - - @Test - public void hystrixFilterWorksJavaDsl() { - testClient.get().uri("/get").header("Host", "www.hystrixjava.org").exchange() - .expectStatus().isOk().expectHeader() - .valueEquals(ROUTE_ID_HEADER, "hystrix_java"); - } - - @Test - public void hystrixFilterFallbackJavaDsl() { - testClient.get().uri("/delay/3").header("Host", "www.hystrixjava.org").exchange() - .expectStatus().isOk().expectBody() - .json("{\"from\":\"fallbackcontroller2\"}"); - } - - @Test - public void hystrixFilterConnectFailure() { - testClient.get().uri("/delay/3").header("Host", "www.hystrixconnectfail.org") - .exchange().expectStatus().is5xxServerError(); - } - - @Test - public void hystrixFilterErrorPage() { - testClient.get().uri("/delay/3").header("Host", "www.hystrixconnectfail.org") - .accept(APPLICATION_JSON).exchange().expectStatus().is5xxServerError() - .expectBody().jsonPath("$.status") - .value(Matchers.greaterThanOrEqualTo(500)).jsonPath("$.message") - .isNotEmpty().jsonPath("$.error").isNotEmpty(); - } - - @Test - public void toStringFormat() { - HystrixGatewayFilterFactory.Config config = new HystrixGatewayFilterFactory.Config() - .setName("myname").setFallbackUri("forward:/myfallback"); - GatewayFilter filter = new HystrixGatewayFilterFactory(null).apply(config); - assertThat(filter.toString()).contains("myname").contains("forward:/myfallback"); - } - - @Test - public void filterFallbackForward() { - testClient.get().uri("/delay/3?a=c").header("Host", "www.hystrixforward.org") - .exchange().expectStatus().isOk().expectBody() - .json("{\"from\":\"hystrixfallbackcontroller3\"}"); - } - -} diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixTestConfig.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixTestConfig.java deleted file mode 100644 index 3b804319..00000000 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixTestConfig.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.filter.factory; - -import java.util.Collections; -import java.util.Map; - -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.gateway.route.RouteLocator; -import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; -import org.springframework.cloud.gateway.test.BaseWebClientTests; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; - -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.HYSTRIX_EXECUTION_EXCEPTION_ATTR; -import static org.springframework.web.reactive.function.server.RequestPredicates.GET; -import static org.springframework.web.reactive.function.server.RouterFunctions.route; - -@EnableAutoConfiguration -@SpringBootConfiguration -@Import(BaseWebClientTests.DefaultTestConfig.class) -@RestController -@RibbonClient(name = "badservice", configuration = TestBadRibbonConfig.class) -public class HystrixTestConfig { - - @Value("${test.uri}") - private String uri; - - @RequestMapping("/fallbackcontroller") - public Map fallbackcontroller(@RequestParam("a") String a) { - return Collections.singletonMap("from", "fallbackcontroller"); - } - - @RequestMapping("/fallbackcontroller2") - public Map fallbackcontroller2() { - return Collections.singletonMap("from", "fallbackcontroller2"); - } - - @RequestMapping("/hystrixFallbackController3") - public Map fallbackcontroller3() { - return Collections.singletonMap("from", "hystrixfallbackcontroller3"); - } - - @Bean - public RouteLocator hystrixRouteLocator(RouteLocatorBuilder builder) { - return builder.routes().route("hystrix_java", r -> r.host("**.hystrixjava.org") - .filters(f -> f.prefixPath("/httpbin").hystrix( - config -> config.setFallbackUri("forward:/fallbackcontroller2"))) - .uri(uri)) - .route("hystrix_fallback_forward", r -> r.host("**.hystrixforward.org") - .filters(f -> f.hystrix( - config -> config.setFallbackUri("forward:/fallback"))) - .uri(uri)) - .route("hystrix_fallback_controller_3", r -> r.path("/fallback") - .filters(f -> f.setPath("/hystrixFallbackController3")).uri(uri)) - .route("hystrix_connection_failure", - r -> r.host("**.hystrixconnectfail.org") - .filters(f -> f.prefixPath("/httpbin").hystrix(config -> { - })).uri("lb://badservice")) - /* - * This is a route encapsulated in a hystrix command that is ready to wait - * for a response far longer than the underpinning WebClient would. - */ - .route("hystrix_response_stall", - r -> r.host("**.hystrixresponsestall.org") - .filters(f -> f.prefixPath("/httpbin").hystrix( - config -> config.setName("stalling-command"))) - .uri(uri)) - .build(); - } - - @Bean - ExceptionFallbackHandler exceptionFallbackHandler() { - return new ExceptionFallbackHandler(); - } - - @Bean - RouterFunction routerFunction( - ExceptionFallbackHandler exceptionFallbackHandler) { - return route(GET("/exceptionFallback"), - exceptionFallbackHandler::retrieveExceptionInfo); - } - -} - -class ExceptionFallbackHandler { - - static final String RETRIEVED_EXCEPTION = "Retrieved-Exception"; - - Mono retrieveExceptionInfo(ServerRequest serverRequest) { - String exceptionName = serverRequest.attribute(HYSTRIX_EXECUTION_EXCEPTION_ATTR) - .map(exception -> exception.getClass().getName()).orElse(""); - return ServerResponse.ok().header(RETRIEVED_EXCEPTION, exceptionName).build(); - } - -} - -@Configuration(proxyBeanMethods = false) -class TestBadRibbonConfig { - - @LocalServerPort - protected int port = 0; - - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("https", "localhost", this.port)); - } - -} diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java index 98c006b5..1744e9ca 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/RetryGatewayFilterFactoryIntegrationTests.java @@ -22,8 +22,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hamcrest.CoreMatchers; @@ -43,8 +41,6 @@ import org.springframework.cloud.gateway.filter.factory.RetryGatewayFilterFactor import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.cloud.gateway.test.BaseWebClientTests; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; @@ -177,7 +173,8 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest @EnableAutoConfiguration @SpringBootConfiguration @Import(DefaultTestConfig.class) - @RibbonClient(name = "badservice2", configuration = TestBadRibbonConfig.class) + // @RibbonClient(name = "badservice2", configuration = + // TestBadLoadBalancerConfig.class) public static class TestConfig { Log log = LogFactory.getLog(getClass()); @@ -269,17 +266,17 @@ public class RetryGatewayFilterFactoryIntegrationTests extends BaseWebClientTest } - protected static class TestBadRibbonConfig { + protected static class TestBadLoadBalancerConfig { @LocalServerPort protected int port = 0; - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>( - new Server("https", "localhost.domain.doesnot.exist", this.port), - new Server("localhost", this.port)); - } + // @Bean + // public ServerList serverList() { + // return new StaticServerList<>( + // new Server("https", "localhost.domain.doesnot.exist", this.port), + // new Server("localhost", this.port)); + // } } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerHystrixFilterFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerHystrixFilterFactoryTests.java deleted file mode 100644 index 57d85714..00000000 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerHystrixFilterFactoryTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.gateway.filter.factory; - -import com.netflix.config.ConfigurationManager; -import com.netflix.hystrix.Hystrix; -import com.netflix.hystrix.metric.consumer.HealthCountsStream; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.gateway.filter.GatewayFilter; -import org.springframework.cloud.netflix.hystrix.ReactiveHystrixCircuitBreakerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.core.StringContains.containsString; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.gateway.filter.factory.ExceptionFallbackHandler.RETRIEVED_EXCEPTION; - -/** - * @author Ryan Baxter - */ -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = RANDOM_PORT, properties = { "debug=true", - "spring.cloud.circuitbreaker.resilience4j.enabled=false" }) -@ContextConfiguration(classes = SpringCloudCircuitBreakerTestConfig.class) -@DirtiesContext -public class SpringCloudCircuitBreakerHystrixFilterFactoryTests - extends SpringCloudCircuitBreakerFilterFactoryTests { - - @Test - public void hystrixFilterServiceUnavailable() { - HealthCountsStream.reset(); - Hystrix.reset(); - ConfigurationManager.getConfigInstance() - .setProperty("hystrix.command.failcmd.circuitBreaker.forceOpen", true); - - testClient.get().uri("/delay/3").header("Host", "www.sccbfailure.org").exchange() - .expectStatus().isEqualTo(HttpStatus.SERVICE_UNAVAILABLE); - - HealthCountsStream.reset(); - Hystrix.reset(); - ConfigurationManager.getConfigInstance() - .setProperty("hystrix.command.failcmd.circuitBreaker.forceOpen", false); - } - - @Test - public void hystrixFilterExceptionFallback() { - testClient.get().uri("/delay/3") - .header("Host", "www.circuitbreakerexceptionfallback.org").exchange() - .expectStatus().isOk().expectHeader() - .value(RETRIEVED_EXCEPTION, containsString("HystrixTimeoutException")); - } - - @Test - public void toStringFormat() { - SpringCloudCircuitBreakerFilterFactory.Config config = new SpringCloudCircuitBreakerFilterFactory.Config() - .setName("myname").setFallbackUri("forward:/myfallback"); - GatewayFilter filter = new SpringCloudCircuitBreakerHystrixFilterFactory( - new ReactiveHystrixCircuitBreakerFactory(), null).apply(config); - assertThat(filter.toString()).contains("myname").contains("forward:/myfallback"); - } - -} diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerResilience4JFilterFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerResilience4JFilterFactoryTests.java index 75b36da5..1753682d 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerResilience4JFilterFactoryTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerResilience4JFilterFactoryTests.java @@ -39,7 +39,6 @@ import org.springframework.web.bind.annotation.RestController; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.core.StringContains.containsString; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; -import static org.springframework.cloud.gateway.filter.factory.ExceptionFallbackHandler.RETRIEVED_EXCEPTION; /** * @author Ryan Baxter @@ -53,6 +52,8 @@ import static org.springframework.cloud.gateway.filter.factory.ExceptionFallback public class SpringCloudCircuitBreakerResilience4JFilterFactoryTests extends SpringCloudCircuitBreakerFilterFactoryTests { + private static final String RETRIEVED_EXCEPTION = "Retrieved-Exception"; + @Autowired private Resilience4JCircuitBreakerFactory factory; diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerTestConfig.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerTestConfig.java index 070ab1f7..8f480634 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerTestConfig.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/SpringCloudCircuitBreakerTestConfig.java @@ -27,7 +27,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.cloud.gateway.test.BaseWebClientTests; -import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.web.bind.annotation.RequestMapping; @@ -48,7 +47,7 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r @SpringBootConfiguration @Import(BaseWebClientTests.DefaultTestConfig.class) @RestController -@RibbonClient(name = "badservice", configuration = TestBadRibbonConfig.class) +// @RibbonClient(name = "badservice", configuration = TestBadLoadBalancerConfig.class) public class SpringCloudCircuitBreakerTestConfig { @Value("${test.uri}") @@ -113,17 +112,17 @@ public class SpringCloudCircuitBreakerTestConfig { exceptionFallbackHandler::retrieveExceptionInfo); } -} + private static class CircuitBreakerExceptionFallbackHandler { -class CircuitBreakerExceptionFallbackHandler { + static final String RETRIEVED_EXCEPTION = "Retrieved-Exception"; - static final String RETRIEVED_EXCEPTION = "Retrieved-Exception"; + Mono retrieveExceptionInfo(ServerRequest serverRequest) { + String exceptionName = serverRequest + .attribute(CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR) + .map(exception -> exception.getClass().getName()).orElse(""); + return ServerResponse.ok().header(RETRIEVED_EXCEPTION, exceptionName).build(); + } - Mono retrieveExceptionInfo(ServerRequest serverRequest) { - String exceptionName = serverRequest - .attribute(CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR) - .map(exception -> exception.getClass().getName()).orElse(""); - return ServerResponse.ok().header(RETRIEVED_EXCEPTION, exceptionName).build(); } } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/ReadBodyPredicateFactoryTest.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/ReadBodyPredicateFactoryTest.java index f7317c2d..dc2a57dd 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/ReadBodyPredicateFactoryTest.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/handler/predicate/ReadBodyPredicateFactoryTest.java @@ -18,8 +18,6 @@ package org.springframework.cloud.gateway.handler.predicate; import java.util.function.Predicate; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; import org.junit.Test; import org.junit.runner.RunWith; @@ -33,9 +31,6 @@ import org.springframework.cloud.gateway.handler.predicate.ReadBodyPredicateFact import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.cloud.gateway.test.PermitAllSecurityConfiguration; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.http.HttpMethod; @@ -90,10 +85,10 @@ public class ReadBodyPredicateFactoryTest { @EnableAutoConfiguration @SpringBootConfiguration - @RibbonClients({ - @RibbonClient(name = "message", configuration = TestRibbonConfig.class), - @RibbonClient(name = "messageChannel", - configuration = TestRibbonConfig.class) }) + // @RibbonClients({ + // @RibbonClient(name = "message", configuration = TestLoadBalancerConfig.class), + // @RibbonClient(name = "messageChannel", + // configuration = TestLoadBalancerConfig.class) }) @Import(PermitAllSecurityConfiguration.class) @RestController public static class TestConfig { @@ -129,15 +124,15 @@ public class ReadBodyPredicateFactoryTest { } - protected static class TestRibbonConfig { + protected static class TestLoadBalancerConfig { @LocalServerPort protected int port = 0; - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } + // @Bean + // public ServerList serverList() { + // return new StaticServerList<>(new Server("localhost", this.port)); + // } } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/AdhocTestSuite.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/AdhocTestSuite.java index 69df0044..d3ee5678 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/AdhocTestSuite.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/AdhocTestSuite.java @@ -56,7 +56,6 @@ import static org.junit.Assume.assumeThat; org.springframework.cloud.gateway.handler.predicate.CloudFoundryRouteServiceRoutePredicateFactoryTest.class, org.springframework.cloud.gateway.handler.RoutePredicateHandlerMappingTests.class, org.springframework.cloud.gateway.filter.factory.RewriteResponseHeaderGatewayFilterFactoryTests.class, - org.springframework.cloud.gateway.filter.factory.HystrixGatewayFilterFactoryTests.class, org.springframework.cloud.gateway.filter.factory.SecureHeadersGatewayFilterFactoryTests.class, org.springframework.cloud.gateway.filter.factory.RedirectToGatewayFilterFactoryTests.class, org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactoryTests.class, @@ -96,7 +95,6 @@ import static org.junit.Assume.assumeThat; org.springframework.cloud.gateway.filter.ratelimit.PrincipalNameKeyResolverIntegrationTests.class, org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiterConfigTests.class, org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiterTests.class, - org.springframework.cloud.gateway.filter.LoadBalancerClientFilterTests.class, org.springframework.cloud.gateway.filter.NettyRoutingFilterIntegrationTests.class, GatewayMetricsFilterTests.class, org.springframework.cloud.gateway.filter.ForwardRoutingFilterTests.class, diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/BaseWebClientTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/BaseWebClientTests.java index 9ecf5386..db1f77a1 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/BaseWebClientTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/BaseWebClientTests.java @@ -18,8 +18,6 @@ package org.springframework.cloud.gateway.test; import java.time.Duration; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Before; @@ -31,9 +29,6 @@ import org.springframework.boot.web.server.LocalServerPort; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.route.Route; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.RibbonClients; -import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -81,8 +76,9 @@ public class BaseWebClientTests { } @Configuration(proxyBeanMethods = false) - @RibbonClients({ - @RibbonClient(name = "testservice", configuration = TestRibbonConfig.class) }) + // @RibbonClients({ + // @RibbonClient(name = "testservice", configuration = TestLoadBalancerConfig.class) + // }) @Import(PermitAllSecurityConfiguration.class) public static class DefaultTestConfig { @@ -141,15 +137,15 @@ public class BaseWebClientTests { } - protected static class TestRibbonConfig { + protected static class TestLoadBalancerConfig { @LocalServerPort protected int port = 0; - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } + // @Bean + // public ServerList serverList() { + // return new StaticServerList<>(new Server("localhost", this.port)); + // } } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/websocket/WebSocketIntegrationTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/websocket/WebSocketIntegrationTests.java index 5dcf2ed3..4cd3eef7 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/websocket/WebSocketIntegrationTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/test/websocket/WebSocketIntegrationTests.java @@ -25,8 +25,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.After; @@ -47,8 +45,6 @@ import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.cloud.gateway.test.PermitAllSecurityConfiguration; import org.springframework.cloud.gateway.test.support.HttpServer; import org.springframework.cloud.gateway.test.support.ReactorHttpServer; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.Lifecycle; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -361,8 +357,8 @@ public class WebSocketIntegrationTests { @Configuration(proxyBeanMethods = false) @EnableAutoConfiguration @Import(PermitAllSecurityConfiguration.class) - @RibbonClient(name = "wsservice", - configuration = LocalRibbonClientConfiguration.class) + // @RibbonClient(name = "wsservice", + // configuration = LocalLoadBalancerClientConfiguration.class) protected static class GatewayConfig { @Bean @@ -374,15 +370,15 @@ public class WebSocketIntegrationTests { } - public static class LocalRibbonClientConfiguration { + public static class LocalLoadBalancerClientConfiguration { @Value("${ws.server.port}") private int wsPort; - @Bean - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.wsPort)); - } + // @Bean + // public ServerList serverList() { + // return new StaticServerList<>(new Server("localhost", this.wsPort)); + // } } diff --git a/spring-cloud-gateway-core/src/test/java/reactor/blockhound/integration/CustomBlockHoundIntegration.java b/spring-cloud-gateway-core/src/test/java/reactor/blockhound/integration/CustomBlockHoundIntegration.java index 5a71910b..fd0b1de5 100644 --- a/spring-cloud-gateway-core/src/test/java/reactor/blockhound/integration/CustomBlockHoundIntegration.java +++ b/spring-cloud-gateway-core/src/test/java/reactor/blockhound/integration/CustomBlockHoundIntegration.java @@ -81,13 +81,6 @@ public class CustomBlockHoundIntegration implements BlockHoundIntegration { builder.allowBlockingCallsInside("io.netty.handler.ssl.SslContext", "newClientContextInternal"); - // Uses - // org.springframework.cloud.commons.httpclient.DefaultApacheHttpClientConnectionManagerFactory#newConnectionManager - // Uses javax.net.ssl.SSLContext#init - builder.allowBlockingCallsInside( - "org.springframework.cloud.netflix.ribbon.SpringClientFactory", - "getContext"); - // Uses org.springframework.security.crypto.bcrypt.BCrypt#gensalt // Uses java.security.SecureRandom#nextBytes builder.allowBlockingCallsInside( diff --git a/spring-cloud-gateway-sample/pom.xml b/spring-cloud-gateway-sample/pom.xml index e92af527..a28697cf 100644 --- a/spring-cloud-gateway-sample/pom.xml +++ b/spring-cloud-gateway-sample/pom.xml @@ -33,10 +33,6 @@ org.springframework.cloud spring-cloud-starter-gateway - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - org.isomorphism token-bucket diff --git a/spring-cloud-gateway-sample/src/test/java/org/springframework/cloud/gateway/sample/GatewaySampleApplicationTests.java b/spring-cloud-gateway-sample/src/test/java/org/springframework/cloud/gateway/sample/GatewaySampleApplicationTests.java index 1b0127b8..04983cef 100644 --- a/spring-cloud-gateway-sample/src/test/java/org/springframework/cloud/gateway/sample/GatewaySampleApplicationTests.java +++ b/spring-cloud-gateway-sample/src/test/java/org/springframework/cloud/gateway/sample/GatewaySampleApplicationTests.java @@ -22,8 +22,6 @@ import java.util.Map; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -34,12 +32,9 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.cloud.gateway.test.HttpBinCompatibleController; -import org.springframework.cloud.netflix.ribbon.RibbonClient; -import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.SocketUtils; @@ -180,7 +175,7 @@ public class GatewaySampleApplicationTests { @Configuration(proxyBeanMethods = false) @EnableAutoConfiguration - @RibbonClient(name = "httpbin", configuration = RibbonConfig.class) + //@RibbonClient(name = "httpbin", configuration = LoadBalancerConfig.class) @Import(GatewaySampleApplication.class) protected static class TestConfig { @@ -191,16 +186,16 @@ public class GatewaySampleApplicationTests { } - protected static class RibbonConfig { + protected static class LoadBalancerConfig { @LocalServerPort int port; - @Bean - @Primary - public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", port)); - } + //@Bean + //@Primary + //public ServerList serverList() { + // return new StaticServerList<>(new Server("localhost", port)); + //} }