From 6bb58302206a2eb501de8962128007c07b81e67a Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Thu, 18 Jan 2018 13:40:43 -0500 Subject: [PATCH] Remove deprecated ZuulFallbackProvider in favor of FallbackProvider. Add route parameter to fallbackResponse. Fixes #2655 (#2664) --- .../main/asciidoc/spring-cloud-netflix.adoc | 92 ++++--------------- .../RibbonCommandFactoryConfiguration.java | 8 +- .../zuul/filters/route/FallbackProvider.java | 17 +++- .../route/RestClientRibbonCommand.java | 4 +- .../route/RestClientRibbonCommandFactory.java | 6 +- .../filters/route/ZuulFallbackProvider.java | 42 --------- .../route/apache/HttpClientRibbonCommand.java | 6 +- .../HttpClientRibbonCommandFactory.java | 8 +- .../route/okhttp/OkHttpRibbonCommand.java | 6 +- .../okhttp/OkHttpRibbonCommandFactory.java | 8 +- .../route/support/AbstractRibbonCommand.java | 22 ++--- .../support/AbstractRibbonCommandFactory.java | 14 +-- .../HttpClientRibbonCommandFactoryTest.java | 4 +- ...tpClientRibbonCommandIntegrationTests.java | 4 +- .../OkHttpRibbonCommandFactoryTest.java | 4 +- .../OkHttpRibbonCommandIntegrationTests.java | 4 +- ...stClientRibbonCommandIntegrationTests.java | 6 +- ...onCommandCauseFallbackPropagationTest.java | 69 +++++--------- .../support/RibbonCommandFallbackTests.java | 15 +-- .../route/support/ZuulProxyTestBase.java | 10 +- 20 files changed, 118 insertions(+), 231 deletions(-) delete mode 100644 spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/ZuulFallbackProvider.java diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 1a51e062..f24d3b6b 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -1943,39 +1943,47 @@ possible filters that are enabled. If you want to disable one, simply set === Providing Hystrix Fallbacks For Routes When a circuit for a given route in Zuul is tripped you can provide a fallback response -by creating a bean of type `ZuulFallbackProvider`. Within this bean you need to specify +by creating a bean of type `FallbackProvider`. Within this bean you need to specify the route ID the fallback is for and provide a `ClientHttpResponse` to return -as a fallback. Here is a very simple `ZuulFallbackProvider` implementation. +as a fallback. Here is a very simple `FallbackProvider` implementation. [source,java] ---- -class MyFallbackProvider implements ZuulFallbackProvider { +class MyFallbackProvider implements FallbackProvider { + @Override public String getRoute() { return "customers"; } @Override - public ClientHttpResponse fallbackResponse() { + public ClientHttpResponse fallbackResponse(String route, final Throwable cause) { + if (cause instanceof HystrixTimeoutException) { + return response(HttpStatus.GATEWAY_TIMEOUT); + } else { + return response(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + private ClientHttpResponse response(final HttpStatus status) { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { - return HttpStatus.OK; + return status; } @Override public int getRawStatusCode() throws IOException { - return 200; + return status.value(); } @Override public String getStatusText() throws IOException { - return "OK"; + return status.getReasonPhrase(); } @Override public void close() { - } @Override @@ -2004,18 +2012,18 @@ zuul: ---- If you would like to provide a default fallback for all routes than you can create a bean of -type `ZuulFallbackProvider` and have the `getRoute` method return `*` or `null`. +type `FallbackProvider` and have the `getRoute` method return `*` or `null`. [source,java] ---- -class MyFallbackProvider implements ZuulFallbackProvider { +class MyFallbackProvider implements FallbackProvider { @Override public String getRoute() { return "*"; } @Override - public ClientHttpResponse fallbackResponse() { + public ClientHttpResponse fallbackResponse(String route, Throwable throwable) { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { @@ -2053,68 +2061,6 @@ class MyFallbackProvider implements ZuulFallbackProvider { } ---- -If you would like to choose the response based on the cause of the failure use `FallbackProvider` which will replace `ZuulFallbackProvder` in future versions. - -[source,java] ----- -class MyFallbackProvider implements FallbackProvider { - - @Override - public String getRoute() { - return "*"; - } - - @Override - public ClientHttpResponse fallbackResponse(final Throwable cause) { - if (cause instanceof HystrixTimeoutException) { - return response(HttpStatus.GATEWAY_TIMEOUT); - } else { - return fallbackResponse(); - } - } - - @Override - public ClientHttpResponse fallbackResponse() { - return response(HttpStatus.INTERNAL_SERVER_ERROR); - } - - private ClientHttpResponse response(final HttpStatus status) { - return new ClientHttpResponse() { - @Override - public HttpStatus getStatusCode() throws IOException { - return status; - } - - @Override - public int getRawStatusCode() throws IOException { - return status.value(); - } - - @Override - public String getStatusText() throws IOException { - return status.getReasonPhrase(); - } - - @Override - public void close() { - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream("fallback".getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - return headers; - } - }; - } -} ----- - === Zuul Timeouts If you want to configure the socket timeouts and read timeouts for requests proxied through diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java index da5fb6ee..b44f6f81 100644 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java +++ b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/RibbonCommandFactoryConfiguration.java @@ -31,9 +31,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; import org.springframework.cloud.netflix.zuul.filters.route.okhttp.OkHttpRibbonCommandFactory; import org.springframework.context.annotation.Bean; @@ -51,7 +51,7 @@ public class RibbonCommandFactoryConfiguration { protected static class RestClientRibbonConfiguration { @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); + private Set zuulFallbackProviders = Collections.emptySet(); @Bean @ConditionalOnMissingBean @@ -68,7 +68,7 @@ public class RibbonCommandFactoryConfiguration { protected static class OkHttpRibbonConfiguration { @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); + private Set zuulFallbackProviders = Collections.emptySet(); @Bean @ConditionalOnMissingBean @@ -84,7 +84,7 @@ public class RibbonCommandFactoryConfiguration { protected static class HttpClientRibbonConfiguration { @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); + private Set zuulFallbackProviders = Collections.emptySet(); @Bean @ConditionalOnMissingBean diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java index 3f3d80df..38047924 100644 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java +++ b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/FallbackProvider.java @@ -19,18 +19,25 @@ package org.springframework.cloud.netflix.zuul.filters.route; import org.springframework.http.client.ClientHttpResponse; /** - * Extension of {@link ZuulFallbackProvider} which adds possibility to choose proper response - * based on the exception which caused the main method to fail. + * Provides fallback when a failure occurs on a route. * + * @author Ryan Baxter * @author Dominik Mostek */ -public interface FallbackProvider extends ZuulFallbackProvider { +public interface FallbackProvider { + + /** + * The route this fallback will be used for. + * @return The route the fallback will be used for. + */ + public String getRoute(); /** * Provides a fallback response based on the cause of the failed execution. * - * @param cause cause of the main method failure + * @param route The route the fallback is for + * @param cause cause of the main method failure, may be null * @return the fallback response */ - ClientHttpResponse fallbackResponse(Throwable cause); + ClientHttpResponse fallbackResponse(String route, Throwable cause); } diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java index 1fd147ce..72f5dff0 100644 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java +++ b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.java @@ -48,13 +48,13 @@ public class RestClientRibbonCommand extends AbstractRibbonCommandemptySet()); + this(clientFactory, new ZuulProperties(), Collections.emptySet()); } public RestClientRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties, - Set zuulFallbackProviders) { + Set zuulFallbackProviders) { super(zuulFallbackProviders); this.clientFactory = clientFactory; this.zuulProperties = zuulProperties; @@ -54,7 +54,7 @@ public class RestClientRibbonCommandFactory extends AbstractRibbonCommandFactory @SuppressWarnings("deprecation") public RestClientRibbonCommand create(RibbonCommandContext context) { String serviceId = context.getServiceId(); - ZuulFallbackProvider fallbackProvider = getFallbackProvider(serviceId); + FallbackProvider fallbackProvider = getFallbackProvider(serviceId); RestClient restClient = this.clientFactory.getClient(serviceId, RestClient.class); return new RestClientRibbonCommand(context.getServiceId(), restClient, context, diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/ZuulFallbackProvider.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/ZuulFallbackProvider.java deleted file mode 100644 index 479655f0..00000000 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/ZuulFallbackProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * * Copyright 2013-2016 the original author or authors. - * * - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * - */ - -package org.springframework.cloud.netflix.zuul.filters.route; - -import org.springframework.http.client.ClientHttpResponse; - -/** - * Provides fallback when a failure occurs on a route. - * @author Ryan Baxter - * @deprecated Use {@link FallbackProvider} - */ -@Deprecated -public interface ZuulFallbackProvider { - - /** - * The route this fallback will be used for. - * @return The route the fallback will be used for. - */ - public String getRoute(); - - /** - * Provides a fallback response. - * @return The fallback response. - */ - public ClientHttpResponse fallbackResponse(); -} diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java index 07be384b..ca24c4ee 100644 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java +++ b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommand.java @@ -22,7 +22,7 @@ import org.springframework.cloud.netflix.ribbon.apache.RibbonApacheHttpResponse; import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand; import com.netflix.client.config.IClientConfig; @@ -43,7 +43,7 @@ public class HttpClientRibbonCommand extends AbstractRibbonCommandemptySet()); + this(clientFactory, zuulProperties, Collections.emptySet()); } public HttpClientRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties, - Set fallbackProviders) { + Set fallbackProviders) { super(fallbackProviders); this.clientFactory = clientFactory; this.zuulProperties = zuulProperties; @@ -49,7 +49,7 @@ public class HttpClientRibbonCommandFactory extends AbstractRibbonCommandFactory @Override public HttpClientRibbonCommand create(final RibbonCommandContext context) { - ZuulFallbackProvider zuulFallbackProvider = getFallbackProvider(context.getServiceId()); + FallbackProvider zuulFallbackProvider = getFallbackProvider(context.getServiceId()); final String serviceId = context.getServiceId(); final RibbonLoadBalancingHttpClient client = this.clientFactory.getClient( serviceId, RibbonLoadBalancingHttpClient.class); diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java index 89389401..2434fafb 100644 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java +++ b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommand.java @@ -22,7 +22,7 @@ import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonRequest; import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonResponse; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand; import com.netflix.client.config.IClientConfig; @@ -43,7 +43,7 @@ public class OkHttpRibbonCommand extends AbstractRibbonCommandemptySet()); + this(clientFactory, zuulProperties, Collections.emptySet()); } public OkHttpRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties, - Set zuulFallbackProviders) { + Set zuulFallbackProviders) { super(zuulFallbackProviders); this.clientFactory = clientFactory; this.zuulProperties = zuulProperties; @@ -50,7 +50,7 @@ public class OkHttpRibbonCommandFactory extends AbstractRibbonCommandFactory { @Override public OkHttpRibbonCommand create(final RibbonCommandContext context) { final String serviceId = context.getServiceId(); - ZuulFallbackProvider fallbackProvider = getFallbackProvider(serviceId); + FallbackProvider fallbackProvider = getFallbackProvider(serviceId); final OkHttpLoadBalancingClient client = this.clientFactory.getClient( serviceId, OkHttpLoadBalancingClient.class); client.setLoadBalancer(this.clientFactory.getLoadBalancer(serviceId)); diff --git a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java index b2ae4923..01e23553 100644 --- a/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java +++ b/spring-cloud-netflix-zuul/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java @@ -22,7 +22,6 @@ import org.springframework.cloud.netflix.ribbon.RibbonHttpResponse; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand; import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.http.client.ClientHttpResponse; import com.netflix.client.AbstractLoadBalancerAwareClient; @@ -48,7 +47,7 @@ public abstract class AbstractRibbonCommand fallbackProviderCache; - private ZuulFallbackProvider defaultFallbackProvider = null; + private Map fallbackProviderCache; + private FallbackProvider defaultFallbackProvider = null; - public AbstractRibbonCommandFactory(Set fallbackProviders){ + public AbstractRibbonCommandFactory(Set fallbackProviders){ this.fallbackProviderCache = new HashMap<>(); - for(ZuulFallbackProvider provider : fallbackProviders) { + for(FallbackProvider provider : fallbackProviders) { String route = provider.getRoute(); if("*".equals(route) || route == null) { defaultFallbackProvider = provider; @@ -44,8 +44,8 @@ public abstract class AbstractRibbonCommandFactory implements RibbonCommandFacto } } - protected ZuulFallbackProvider getFallbackProvider(String route) { - ZuulFallbackProvider provider = fallbackProviderCache.get(route); + protected FallbackProvider getFallbackProvider(String route) { + FallbackProvider provider = fallbackProviderCache.get(route); if(provider == null) { provider = defaultFallbackProvider; } diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java index e15648b1..65646bfd 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandFactoryTest.java @@ -7,7 +7,7 @@ import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import com.netflix.client.config.DefaultClientConfigImpl; import com.netflix.client.config.IClientConfig; @@ -36,7 +36,7 @@ public class HttpClientRibbonCommandFactoryTest { doReturn(loadBalancingHttpClient).when(this.springClientFactory).getClient(anyString(), eq(RibbonLoadBalancingHttpClient.class)); doReturn(clientConfig).when(this.springClientFactory).getClientConfig(anyString()); - this.ribbonCommandFactory = new HttpClientRibbonCommandFactory(springClientFactory, zuulProperties, new HashSet()); + this.ribbonCommandFactory = new HttpClientRibbonCommandFactory(springClientFactory, zuulProperties, new HashSet()); } @Test diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java index 3c4cd303..3a31a6bc 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonCommandIntegrationTests.java @@ -47,8 +47,8 @@ import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -162,7 +162,7 @@ public class HttpClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); + private Set zuulFallbackProviders = Collections.emptySet(); @RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH) public String patch(@PathVariable final String id, diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java index 6f3612be..a6288a18 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandFactoryTest.java @@ -7,7 +7,7 @@ import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import com.netflix.client.config.DefaultClientConfigImpl; import com.netflix.client.config.IClientConfig; @@ -36,7 +36,7 @@ public class OkHttpRibbonCommandFactoryTest { doReturn(loadBalancingHttpClient).when(this.springClientFactory).getClient(anyString(), eq(OkHttpLoadBalancingClient.class)); doReturn(clientConfig).when(this.springClientFactory).getClientConfig(anyString()); - commandFactory = new OkHttpRibbonCommandFactory(springClientFactory, zuulProperties, new HashSet()); + commandFactory = new OkHttpRibbonCommandFactory(springClientFactory, zuulProperties, new HashSet()); } @Test diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java index 5911f994..ea531470 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java @@ -38,8 +38,8 @@ import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -113,7 +113,7 @@ public class OkHttpRibbonCommandIntegrationTests extends ZuulProxyTestBase { static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); + private Set zuulFallbackProviders = Collections.emptySet(); @Bean public RibbonCommandFactory ribbonCommandFactory( diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java index dcf90922..320fc3d2 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java @@ -52,11 +52,11 @@ import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommand; import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory; import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.support.NoEncodingFormHttpMessageConverter; import org.springframework.cloud.netflix.zuul.filters.route.support.ZuulProxyTestBase; import org.springframework.context.annotation.Bean; @@ -291,7 +291,7 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { @Autowired(required = false) - private Set fallbackProviders = Collections.emptySet(); + private Set fallbackProviders = Collections.emptySet(); @RequestMapping("/trailing-slash") public String trailingSlash(HttpServletRequest request) { @@ -360,7 +360,7 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { private SpringClientFactory clientFactory; public MyRibbonCommandFactory(SpringClientFactory clientFactory, - Set fallbackProviders) { + Set fallbackProviders) { super(clientFactory, new ZuulProperties(), fallbackProviders); this.clientFactory = clientFactory; } diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java index f7d62131..9ef46f59 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandCauseFallbackPropagationTest.java @@ -32,29 +32,40 @@ import com.netflix.client.http.HttpResponse; import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.exception.HystrixTimeoutException; +import org.junit.Before; import org.junit.Test; +import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpResponse; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; /** * @author Dominik Mostek */ public class RibbonCommandCauseFallbackPropagationTest { + private RibbonCommandContext context; + + @Before + public void setup() { + context = mock(RibbonCommandContext.class); + doReturn("fooRoute").when(context).getServiceId(); + } + @Test public void providerIsCalledInCaseOfException() throws Exception { - TestZuulFallbackProviderWithoutCause provider = new TestZuulFallbackProviderWithoutCause( - HttpStatus.INTERNAL_SERVER_ERROR); + FallbackProvider provider = new TestFallbackProvider(getClientHttpResponse( + HttpStatus.INTERNAL_SERVER_ERROR)); RuntimeException exception = new RuntimeException("Failed!"); TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider); + provider, context); ClientHttpResponse response = testCommand.execute(); @@ -68,7 +79,7 @@ public class RibbonCommandCauseFallbackPropagationTest { .withResponse(HttpStatus.NOT_FOUND); RuntimeException exception = new RuntimeException("Failed!"); TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider); + provider, context); ClientHttpResponse response = testCommand.execute(); @@ -86,7 +97,7 @@ public class RibbonCommandCauseFallbackPropagationTest { .withResponse(HttpStatus.BAD_GATEWAY); final RuntimeException exception = new RuntimeException("Failed!"); TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider) { + provider, context) { @Override public Throwable getFailedExecutionException() { return null; @@ -110,7 +121,7 @@ public class RibbonCommandCauseFallbackPropagationTest { .withResponse(HttpStatus.CONFLICT); RuntimeException exception = new RuntimeException("Failed!"); TestRibbonCommand testCommand = new TestRibbonCommand(new TestClient(exception), - provider, 1) { + provider, 1, context) { @Override protected ClientRequest createRequest() throws Exception { Thread.sleep(5); @@ -132,23 +143,23 @@ public class RibbonCommandCauseFallbackPropagationTest { public TestRibbonCommand( AbstractLoadBalancerAwareClient client, - ZuulFallbackProvider fallbackProvider) { - this(client, new ZuulProperties(), fallbackProvider); + FallbackProvider fallbackProvider, RibbonCommandContext context) { + this(client, new ZuulProperties(), fallbackProvider, context); } public TestRibbonCommand( AbstractLoadBalancerAwareClient client, - ZuulProperties zuulProperties, ZuulFallbackProvider fallbackProvider) { - super("testCommand" + UUID.randomUUID(), client, null, zuulProperties, + ZuulProperties zuulProperties, FallbackProvider fallbackProvider, RibbonCommandContext context) { + super("testCommand" + UUID.randomUUID(), client, context, zuulProperties, fallbackProvider); } public TestRibbonCommand( AbstractLoadBalancerAwareClient client, - ZuulFallbackProvider fallbackProvider, int timeout) { + FallbackProvider fallbackProvider, int timeout, RibbonCommandContext context) { // different name is used because of properties caching super(getSetter("testCommand" + UUID.randomUUID(), new ZuulProperties()) - .andCommandPropertiesDefaults(defauts(timeout)), client, null, + .andCommandPropertiesDefaults(defauts(timeout)), client, context, fallbackProvider, null); } @@ -204,7 +215,7 @@ public class RibbonCommandCauseFallbackPropagationTest { } @Override - public ClientHttpResponse fallbackResponse(final Throwable cause) { + public ClientHttpResponse fallbackResponse(String route, final Throwable cause) { this.cause = cause; return response; } @@ -214,12 +225,6 @@ public class RibbonCommandCauseFallbackPropagationTest { return "test-route"; } - @Override - public ClientHttpResponse fallbackResponse() { - throw new UnsupportedOperationException( - "fallback without cause is not supported"); - } - public Throwable getCause() { return cause; } @@ -229,30 +234,6 @@ public class RibbonCommandCauseFallbackPropagationTest { } } - public static class TestZuulFallbackProviderWithoutCause - implements ZuulFallbackProvider { - - private final ClientHttpResponse response; - - public TestZuulFallbackProviderWithoutCause(final ClientHttpResponse response) { - this.response = response; - } - - public TestZuulFallbackProviderWithoutCause(final HttpStatus status) { - this(getClientHttpResponse(status)); - } - - @Override - public String getRoute() { - return "test-route"; - } - - @Override - public ClientHttpResponse fallbackResponse() { - return response; - } - } - private static ClientHttpResponse getClientHttpResponse(final HttpStatus status) { return new ClientHttpResponse() { @Override diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java index cc3b4ef5..be260a99 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java @@ -34,8 +34,8 @@ import org.springframework.cloud.netflix.ribbon.RibbonClients; import org.springframework.cloud.netflix.ribbon.SpringClientFactory; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -89,7 +89,7 @@ public abstract class RibbonCommandFallbackTests { public static class TestConfig extends ZuulProxyTestBase.AbstractZuulProxyApplication { @Autowired(required = false) - private Set zuulFallbackProviders = Collections.emptySet(); + private Set zuulFallbackProviders = Collections.emptySet(); @Bean @@ -106,12 +106,12 @@ public abstract class RibbonCommandFallbackTests { } @Bean - public ZuulFallbackProvider defaultFallbackProvider() { + public FallbackProvider defaultFallbackProvider() { return new DefaultFallbackProvider(); } } - public static class DefaultFallbackProvider implements ZuulFallbackProvider { + public static class DefaultFallbackProvider implements FallbackProvider { @Override public String getRoute() { @@ -119,7 +119,7 @@ public abstract class RibbonCommandFallbackTests { } @Override - public ClientHttpResponse fallbackResponse() { + public ClientHttpResponse fallbackResponse(final String route, Throwable cause) { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { @@ -128,7 +128,10 @@ public abstract class RibbonCommandFallbackTests { @Override public int getRawStatusCode() throws IOException { - return 200; + if(route.equals("another")) { + return 200; + } + return 500; } @Override diff --git a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java index 397e9a1e..96ae2988 100644 --- a/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java +++ b/spring-cloud-netflix-zuul/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java @@ -46,8 +46,8 @@ import org.springframework.cloud.netflix.zuul.RoutesEndpoint; import org.springframework.cloud.netflix.zuul.filters.Route; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; -import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase.RetryableTestConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -397,8 +397,8 @@ public abstract class ZuulProxyTestBase { } @Bean - public ZuulFallbackProvider fallbackProvider() { - return new FallbackProvider(); + public FallbackProvider fallbackProvider() { + return new ZuulFallbackProvider(); } @Bean @@ -443,7 +443,7 @@ public abstract class ZuulProxyTestBase { } - public static class FallbackProvider implements ZuulFallbackProvider { + public static class ZuulFallbackProvider implements FallbackProvider { @Override public String getRoute() { @@ -451,7 +451,7 @@ public abstract class ZuulProxyTestBase { } @Override - public ClientHttpResponse fallbackResponse() { + public ClientHttpResponse fallbackResponse(String route, Throwable cause) { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException {