Remove deprecated ZuulFallbackProvider in favor of FallbackProvider. Add route parameter to fallbackResponse. Fixes #2655 (#2664)

This commit is contained in:
Ryan Baxter
2018-01-18 13:40:43 -05:00
committed by GitHub
parent 7b7cf7e5e8
commit 6bb5830220
20 changed files with 118 additions and 231 deletions

View File

@@ -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

View File

@@ -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<ZuulFallbackProvider> zuulFallbackProviders = Collections.emptySet();
private Set<FallbackProvider> zuulFallbackProviders = Collections.emptySet();
@Bean
@ConditionalOnMissingBean
@@ -68,7 +68,7 @@ public class RibbonCommandFactoryConfiguration {
protected static class OkHttpRibbonConfiguration {
@Autowired(required = false)
private Set<ZuulFallbackProvider> zuulFallbackProviders = Collections.emptySet();
private Set<FallbackProvider> zuulFallbackProviders = Collections.emptySet();
@Bean
@ConditionalOnMissingBean
@@ -84,7 +84,7 @@ public class RibbonCommandFactoryConfiguration {
protected static class HttpClientRibbonConfiguration {
@Autowired(required = false)
private Set<ZuulFallbackProvider> zuulFallbackProviders = Collections.emptySet();
private Set<FallbackProvider> zuulFallbackProviders = Collections.emptySet();
@Bean
@ConditionalOnMissingBean

View File

@@ -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 <code>null</code>
* @return the fallback response
*/
ClientHttpResponse fallbackResponse(Throwable cause);
ClientHttpResponse fallbackResponse(String route, Throwable cause);
}

View File

@@ -48,13 +48,13 @@ public class RestClientRibbonCommand extends AbstractRibbonCommand<RestClient, H
public RestClientRibbonCommand(String commandKey, RestClient client,
RibbonCommandContext context, ZuulProperties zuulProperties,
ZuulFallbackProvider zuulFallbackProvider) {
FallbackProvider zuulFallbackProvider) {
super(commandKey, client, context, zuulProperties, zuulFallbackProvider);
}
public RestClientRibbonCommand(String commandKey, RestClient client,
RibbonCommandContext context, ZuulProperties zuulProperties,
ZuulFallbackProvider zuulFallbackProvider, IClientConfig config) {
FallbackProvider zuulFallbackProvider, IClientConfig config) {
super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config);
}

View File

@@ -39,12 +39,12 @@ public class RestClientRibbonCommandFactory extends AbstractRibbonCommandFactory
private ZuulProperties zuulProperties;
public RestClientRibbonCommandFactory(SpringClientFactory clientFactory) {
this(clientFactory, new ZuulProperties(), Collections.<ZuulFallbackProvider>emptySet());
this(clientFactory, new ZuulProperties(), Collections.<FallbackProvider>emptySet());
}
public RestClientRibbonCommandFactory(SpringClientFactory clientFactory,
ZuulProperties zuulProperties,
Set<ZuulFallbackProvider> zuulFallbackProviders) {
Set<FallbackProvider> 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,

View File

@@ -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();
}

View File

@@ -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 AbstractRibbonCommand<RibbonLoadBal
final RibbonLoadBalancingHttpClient client,
final RibbonCommandContext context,
final ZuulProperties zuulProperties,
final ZuulFallbackProvider zuulFallbackProvider) {
final FallbackProvider zuulFallbackProvider) {
super(commandKey, client, context, zuulProperties, zuulFallbackProvider);
}
@@ -51,7 +51,7 @@ public class HttpClientRibbonCommand extends AbstractRibbonCommand<RibbonLoadBal
final RibbonLoadBalancingHttpClient client,
final RibbonCommandContext context,
final ZuulProperties zuulProperties,
final ZuulFallbackProvider zuulFallbackProvider,
final FallbackProvider zuulFallbackProvider,
final IClientConfig config) {
super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config);
}

View File

@@ -22,9 +22,9 @@ import java.util.Set;
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.zuul.filters.route.FallbackProvider;
import org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommandFactory;
import org.springframework.cloud.netflix.ribbon.support.RibbonCommandContext;
import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
/**
* @author Christian Lohmann
@@ -37,11 +37,11 @@ public class HttpClientRibbonCommandFactory extends AbstractRibbonCommandFactory
private final ZuulProperties zuulProperties;
public HttpClientRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties) {
this(clientFactory, zuulProperties, Collections.<ZuulFallbackProvider>emptySet());
this(clientFactory, zuulProperties, Collections.<FallbackProvider>emptySet());
}
public HttpClientRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties,
Set<ZuulFallbackProvider> fallbackProviders) {
Set<FallbackProvider> 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);

View File

@@ -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 AbstractRibbonCommand<OkHttpLoadBalanci
final OkHttpLoadBalancingClient client,
final RibbonCommandContext context,
final ZuulProperties zuulProperties,
final ZuulFallbackProvider zuulFallbackProvider) {
final FallbackProvider zuulFallbackProvider) {
super(commandKey, client, context, zuulProperties, zuulFallbackProvider);
}
@@ -51,7 +51,7 @@ public class OkHttpRibbonCommand extends AbstractRibbonCommand<OkHttpLoadBalanci
final OkHttpLoadBalancingClient client,
final RibbonCommandContext context,
final ZuulProperties zuulProperties,
final ZuulFallbackProvider zuulFallbackProvider,
final FallbackProvider zuulFallbackProvider,
final IClientConfig config) {
super(commandKey, client, context, zuulProperties, zuulFallbackProvider, config);
}

View File

@@ -23,7 +23,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 org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommandFactory;
/**
@@ -37,11 +37,11 @@ public class OkHttpRibbonCommandFactory extends AbstractRibbonCommandFactory {
private ZuulProperties zuulProperties;
public OkHttpRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties) {
this(clientFactory, zuulProperties, Collections.<ZuulFallbackProvider>emptySet());
this(clientFactory, zuulProperties, Collections.<FallbackProvider>emptySet());
}
public OkHttpRibbonCommandFactory(SpringClientFactory clientFactory, ZuulProperties zuulProperties,
Set<ZuulFallbackProvider> zuulFallbackProviders) {
Set<FallbackProvider> 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));

View File

@@ -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<LBC extends AbstractLoadBalancerAwar
protected final LBC client;
protected RibbonCommandContext context;
protected ZuulFallbackProvider zuulFallbackProvider;
protected FallbackProvider zuulFallbackProvider;
protected IClientConfig config;
public AbstractRibbonCommand(LBC client, RibbonCommandContext context,
@@ -63,19 +62,19 @@ public abstract class AbstractRibbonCommand<LBC extends AbstractLoadBalancerAwar
public AbstractRibbonCommand(String commandKey, LBC client,
RibbonCommandContext context, ZuulProperties zuulProperties,
ZuulFallbackProvider fallbackProvider) {
FallbackProvider fallbackProvider) {
this(commandKey, client, context, zuulProperties, fallbackProvider, null);
}
public AbstractRibbonCommand(String commandKey, LBC client,
RibbonCommandContext context, ZuulProperties zuulProperties,
ZuulFallbackProvider fallbackProvider, IClientConfig config) {
FallbackProvider fallbackProvider, IClientConfig config) {
this(getSetter(commandKey, zuulProperties), client, context, fallbackProvider, config);
}
protected AbstractRibbonCommand(Setter setter, LBC client,
RibbonCommandContext context,
ZuulFallbackProvider fallbackProvider, IClientConfig config) {
FallbackProvider fallbackProvider, IClientConfig config) {
super(setter);
this.client = client;
this.context = context;
@@ -139,16 +138,9 @@ public abstract class AbstractRibbonCommand<LBC extends AbstractLoadBalancerAwar
}
protected ClientHttpResponse getFallbackResponse() {
if (zuulFallbackProvider instanceof FallbackProvider) {
Throwable cause = getFailedExecutionException();
cause = cause == null ? getExecutionException() : cause;
if (cause == null) {
zuulFallbackProvider.fallbackResponse();
} else {
return ((FallbackProvider) zuulFallbackProvider).fallbackResponse(cause);
}
}
return zuulFallbackProvider.fallbackResponse();
Throwable cause = getFailedExecutionException();
cause = cause == null ? getExecutionException() : cause;
return zuulFallbackProvider.fallbackResponse(context.getServiceId(), cause);
}
public LBC getClient() {

View File

@@ -21,20 +21,20 @@ package org.springframework.cloud.netflix.zuul.filters.route.support;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
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;
/**
* @author Ryan Baxter
*/
public abstract class AbstractRibbonCommandFactory implements RibbonCommandFactory {
private Map<String, ZuulFallbackProvider> fallbackProviderCache;
private ZuulFallbackProvider defaultFallbackProvider = null;
private Map<String, FallbackProvider> fallbackProviderCache;
private FallbackProvider defaultFallbackProvider = null;
public AbstractRibbonCommandFactory(Set<ZuulFallbackProvider> fallbackProviders){
public AbstractRibbonCommandFactory(Set<FallbackProvider> 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;
}

View File

@@ -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<ZuulFallbackProvider>());
this.ribbonCommandFactory = new HttpClientRibbonCommandFactory(springClientFactory, zuulProperties, new HashSet<FallbackProvider>());
}
@Test

View File

@@ -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<ZuulFallbackProvider> zuulFallbackProviders = Collections.emptySet();
private Set<FallbackProvider> zuulFallbackProviders = Collections.emptySet();
@RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH)
public String patch(@PathVariable final String id,

View File

@@ -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<ZuulFallbackProvider>());
commandFactory = new OkHttpRibbonCommandFactory(springClientFactory, zuulProperties, new HashSet<FallbackProvider>());
}
@Test

View File

@@ -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<ZuulFallbackProvider> zuulFallbackProviders = Collections.emptySet();
private Set<FallbackProvider> zuulFallbackProviders = Collections.emptySet();
@Bean
public RibbonCommandFactory<?> ribbonCommandFactory(

View File

@@ -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<ZuulFallbackProvider> fallbackProviders = Collections.emptySet();
private Set<FallbackProvider> 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<ZuulFallbackProvider> fallbackProviders) {
Set<FallbackProvider> fallbackProviders) {
super(clientFactory, new ZuulProperties(), fallbackProviders);
this.clientFactory = clientFactory;
}

View File

@@ -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<ClientRequest, HttpResponse> client,
ZuulFallbackProvider fallbackProvider) {
this(client, new ZuulProperties(), fallbackProvider);
FallbackProvider fallbackProvider, RibbonCommandContext context) {
this(client, new ZuulProperties(), fallbackProvider, context);
}
public TestRibbonCommand(
AbstractLoadBalancerAwareClient<ClientRequest, HttpResponse> 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<ClientRequest, HttpResponse> 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

View File

@@ -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<ZuulFallbackProvider> zuulFallbackProviders = Collections.emptySet();
private Set<FallbackProvider> 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

View File

@@ -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 {