Remove deprecated ZuulFallbackProvider in favor of FallbackProvider. Add route parameter to fallbackResponse. Fixes #2655 (#2664)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user