Merge remote-tracking branch 'Upstream/master' into http-client-centralization
This commit is contained in:
@@ -1044,8 +1044,46 @@ public class FooConfiguration {
|
||||
|
||||
This replaces the `SpringMvcContract` with `feign.Contract.Default` and adds a `RequestInterceptor` to the collection of `RequestInterceptor`.
|
||||
|
||||
`@FeignClient` also can be configured using configuration properties.
|
||||
|
||||
application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
feign:
|
||||
client:
|
||||
config:
|
||||
feignName:
|
||||
connectTimeout: 5000
|
||||
readTimeout: 5000
|
||||
loggerLevel: full
|
||||
errorDecoder: com.example.SimpleErrorDecoder
|
||||
retryer: com.example.SimpleRetryer
|
||||
requestInterceptors:
|
||||
- com.example.FooRequestInterceptor
|
||||
- com.example.BarRequestInterceptor
|
||||
decode404: false
|
||||
----
|
||||
|
||||
Default configurations can be specified in the `@EnableFeignClients` attribute `defaultConfiguration` in a similar manner as described above. The difference is that this configuration will apply to _all_ feign clients.
|
||||
|
||||
If you prefer using configuration properties to configured all `@FeignClient`, you can create configuration properties with `default` feign name.
|
||||
|
||||
application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
feign:
|
||||
client:
|
||||
config:
|
||||
default:
|
||||
connectTimeout: 5000
|
||||
readTimeout: 5000
|
||||
loggerLevel: basic
|
||||
----
|
||||
|
||||
If we create both `@Configuration` bean and configuration properties, configuration properties will win.
|
||||
It will override `@Configuration` values. But if you want to change the priority to `@Configuration`,
|
||||
you can change `feign.client.default-to-properties` to `false`.
|
||||
|
||||
NOTE: If you need to use `ThreadLocal` bound variables in your `RequestInterceptor`s you will need to either set the
|
||||
thread isolation strategy for Hystrix to `SEMAPHORE` or disable Hystrix in Feign.
|
||||
|
||||
@@ -1868,6 +1906,32 @@ class MyFallbackProvider implements ZuulFallbackProvider {
|
||||
}
|
||||
----
|
||||
|
||||
[[zuul-redirect-location-rewrite]]
|
||||
=== Rewriting `Location` header
|
||||
|
||||
If Zuul is fronting a web application then there may be a need to re-write the `Location` header when the web application redirects through a http status code of 3XX, otherwise the browser will end up redirecting to the web application's url instead of the Zuul url.
|
||||
A `LocationRewriteFilter` Zuul filter can be configured to re-write the Location header to the Zuul's url, it also adds back the stripped global and route specific prefixes. The filter can be added the following way via a Spring Configuration file:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
import org.springframework.cloud.netflix.zuul.filters.post.LocationRewriteFilter;
|
||||
...
|
||||
|
||||
@Configuration
|
||||
@EnableZuulProxy
|
||||
public class ZuulConfig {
|
||||
@Bean
|
||||
public LocationRewriteFilter locationRewriteFilter() {
|
||||
return new LocationRewriteFilter();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
Use this filter with caution though, the filter acts on the `Location` header of ALL 3XX response codes which may not be appropriate in all scenarios, say if the user is redirecting to an external URL.
|
||||
====
|
||||
|
||||
[[zuul-developer-guide]]
|
||||
=== Zuul Developer Guide
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ import javax.annotation.PreDestroy;
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(Feign.class)
|
||||
@EnableConfigurationProperties({ FeignHttpClientProperties.class })
|
||||
@EnableConfigurationProperties({FeignClientProperties.class, FeignHttpClientProperties.class})
|
||||
public class FeignAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
* Copyright 2013-2017 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.
|
||||
@@ -18,9 +18,11 @@ package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -44,6 +46,7 @@ import lombok.EqualsAndHashCode;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Venil Noronha
|
||||
* @author Eko Kurniawan Khannedy
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@@ -74,7 +77,6 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
|
||||
Assert.hasText(this.name, "Name must be set");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
this.applicationContext = context;
|
||||
@@ -93,7 +95,29 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
|
||||
.contract(get(context, Contract.class));
|
||||
// @formatter:on
|
||||
|
||||
// optional values
|
||||
configureFeign(context, builder);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected void configureFeign(FeignContext context, Feign.Builder builder) {
|
||||
FeignClientProperties properties = applicationContext.getBean(FeignClientProperties.class);
|
||||
if (properties != null) {
|
||||
if (properties.isDefaultToProperties()) {
|
||||
configureUsingConfiguration(context, builder);
|
||||
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
|
||||
configureUsingProperties(properties.getConfig().get(this.name), builder);
|
||||
} else {
|
||||
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
|
||||
configureUsingProperties(properties.getConfig().get(this.name), builder);
|
||||
configureUsingConfiguration(context, builder);
|
||||
}
|
||||
} else {
|
||||
configureUsingConfiguration(context, builder);
|
||||
}
|
||||
}
|
||||
|
||||
protected void configureUsingConfiguration(FeignContext context, Feign.Builder builder) {
|
||||
Logger.Level level = getOptional(context, Logger.Level.class);
|
||||
if (level != null) {
|
||||
builder.logLevel(level);
|
||||
@@ -119,8 +143,52 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
|
||||
if (decode404) {
|
||||
builder.decode404();
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
protected void configureUsingProperties(FeignClientProperties.FeignClientConfiguration config, Feign.Builder builder) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.getLoggerLevel() != null) {
|
||||
builder.logLevel(config.getLoggerLevel());
|
||||
}
|
||||
|
||||
if (config.getConnectTimeout() != null && config.getReadTimeout() != null) {
|
||||
builder.options(new Request.Options(config.getConnectTimeout(), config.getReadTimeout()));
|
||||
}
|
||||
|
||||
if (config.getRetryer() != null) {
|
||||
Retryer retryer = getOrInstantiate(config.getRetryer());
|
||||
builder.retryer(retryer);
|
||||
}
|
||||
|
||||
if (config.getErrorDecoder() != null) {
|
||||
ErrorDecoder errorDecoder = getOrInstantiate(config.getErrorDecoder());
|
||||
builder.errorDecoder(errorDecoder);
|
||||
}
|
||||
|
||||
if (config.getRequestInterceptors() != null && !config.getRequestInterceptors().isEmpty()) {
|
||||
// this will add request interceptor to builder, not replace existing
|
||||
for (Class<RequestInterceptor> bean : config.getRequestInterceptors()) {
|
||||
RequestInterceptor interceptor = getOrInstantiate(bean);
|
||||
builder.requestInterceptor(interceptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getDecode404() != null) {
|
||||
if (config.getDecode404()) {
|
||||
builder.decode404();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T getOrInstantiate(Class<T> tClass) {
|
||||
try {
|
||||
return applicationContext.getBean(tClass);
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
return BeanUtils.instantiateClass(tClass);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> T get(FeignContext context, Class<T> type) {
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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.feign;
|
||||
|
||||
import feign.Logger;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.Retryer;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Eko Kurniawan Khannedy
|
||||
*/
|
||||
@ConfigurationProperties("feign.client")
|
||||
public class FeignClientProperties {
|
||||
|
||||
private boolean defaultToProperties = true;
|
||||
|
||||
private String defaultConfig = "default";
|
||||
|
||||
private Map<String, FeignClientConfiguration> config = new HashMap<>();
|
||||
|
||||
public boolean isDefaultToProperties() {
|
||||
return defaultToProperties;
|
||||
}
|
||||
|
||||
public void setDefaultToProperties(boolean defaultToProperties) {
|
||||
this.defaultToProperties = defaultToProperties;
|
||||
}
|
||||
|
||||
public String getDefaultConfig() {
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
public void setDefaultConfig(String defaultConfig) {
|
||||
this.defaultConfig = defaultConfig;
|
||||
}
|
||||
|
||||
public Map<String, FeignClientConfiguration> getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setConfig(Map<String, FeignClientConfiguration> config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FeignClientProperties that = (FeignClientProperties) o;
|
||||
return defaultToProperties == that.defaultToProperties &&
|
||||
Objects.equals(defaultConfig, that.defaultConfig) &&
|
||||
Objects.equals(config, that.config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(defaultToProperties, defaultConfig, config);
|
||||
}
|
||||
|
||||
public static class FeignClientConfiguration {
|
||||
|
||||
private Logger.Level loggerLevel;
|
||||
|
||||
private Integer connectTimeout;
|
||||
|
||||
private Integer readTimeout;
|
||||
|
||||
private Class<Retryer> retryer;
|
||||
|
||||
private Class<ErrorDecoder> errorDecoder;
|
||||
|
||||
private List<Class<RequestInterceptor>> requestInterceptors;
|
||||
|
||||
private Boolean decode404;
|
||||
|
||||
public Logger.Level getLoggerLevel() {
|
||||
return loggerLevel;
|
||||
}
|
||||
|
||||
public void setLoggerLevel(Logger.Level loggerLevel) {
|
||||
this.loggerLevel = loggerLevel;
|
||||
}
|
||||
|
||||
public Integer getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
public void setConnectTimeout(Integer connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
public Integer getReadTimeout() {
|
||||
return readTimeout;
|
||||
}
|
||||
|
||||
public void setReadTimeout(Integer readTimeout) {
|
||||
this.readTimeout = readTimeout;
|
||||
}
|
||||
|
||||
public Class<Retryer> getRetryer() {
|
||||
return retryer;
|
||||
}
|
||||
|
||||
public void setRetryer(Class<Retryer> retryer) {
|
||||
this.retryer = retryer;
|
||||
}
|
||||
|
||||
public Class<ErrorDecoder> getErrorDecoder() {
|
||||
return errorDecoder;
|
||||
}
|
||||
|
||||
public void setErrorDecoder(Class<ErrorDecoder> errorDecoder) {
|
||||
this.errorDecoder = errorDecoder;
|
||||
}
|
||||
|
||||
public List<Class<RequestInterceptor>> getRequestInterceptors() {
|
||||
return requestInterceptors;
|
||||
}
|
||||
|
||||
public void setRequestInterceptors(List<Class<RequestInterceptor>> requestInterceptors) {
|
||||
this.requestInterceptors = requestInterceptors;
|
||||
}
|
||||
|
||||
public Boolean getDecode404() {
|
||||
return decode404;
|
||||
}
|
||||
|
||||
public void setDecode404(Boolean decode404) {
|
||||
this.decode404 = decode404;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FeignClientConfiguration that = (FeignClientConfiguration) o;
|
||||
return loggerLevel == that.loggerLevel &&
|
||||
Objects.equals(connectTimeout, that.connectTimeout) &&
|
||||
Objects.equals(readTimeout, that.readTimeout) &&
|
||||
Objects.equals(retryer, that.retryer) &&
|
||||
Objects.equals(errorDecoder, that.errorDecoder) &&
|
||||
Objects.equals(requestInterceptors, that.requestInterceptors) &&
|
||||
Objects.equals(decode404, that.decode404);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(loggerLevel, connectTimeout, readTimeout, retryer,
|
||||
errorDecoder, requestInterceptors, decode404);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,6 +42,12 @@ public class Route {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Route(String id, String path, String location, String prefix,
|
||||
Boolean retryable, Set<String> ignoredHeaders, boolean prefixStripped) {
|
||||
this(id, path, location, prefix, retryable, ignoredHeaders);
|
||||
this.prefixStripped = prefixStripped;
|
||||
}
|
||||
|
||||
private String id;
|
||||
|
||||
@@ -58,6 +64,8 @@ public class Route {
|
||||
private Set<String> sensitiveHeaders = new LinkedHashSet<>();
|
||||
|
||||
private boolean customSensitiveHeaders;
|
||||
|
||||
private boolean prefixStripped = true;
|
||||
|
||||
public boolean isCustomSensitiveHeaders() {
|
||||
return this.customSensitiveHeaders;
|
||||
|
||||
@@ -151,7 +151,8 @@ public class SimpleRouteLocator implements RouteLocator, Ordered {
|
||||
}
|
||||
return new Route(route.getId(), targetPath, route.getLocation(), prefix,
|
||||
retryable,
|
||||
route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null);
|
||||
route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null,
|
||||
route.isStripPrefix());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -304,7 +304,8 @@ public class ZuulProperties {
|
||||
|
||||
public Route getRoute(String prefix) {
|
||||
return new Route(this.id, this.path, getLocation(), prefix, this.retryable,
|
||||
isCustomSensitiveHeaders() ? this.sensitiveHeaders : null);
|
||||
isCustomSensitiveHeaders() ? this.sensitiveHeaders : null,
|
||||
this.stripPrefix);
|
||||
}
|
||||
|
||||
public void setSensitiveHeaders(Set<String> headers) {
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2017 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.post;
|
||||
|
||||
import com.netflix.util.Pair;
|
||||
import com.netflix.zuul.ZuulFilter;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.netflix.zuul.filters.Route;
|
||||
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
|
||||
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;
|
||||
|
||||
/**
|
||||
* {@link ZuulFilter} Responsible for rewriting the Location header to be the Zuul URL
|
||||
*
|
||||
* @author Biju Kunjummen
|
||||
*/
|
||||
public class LocationRewriteFilter extends ZuulFilter {
|
||||
|
||||
private final UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
|
||||
@Autowired
|
||||
private ZuulProperties zuulProperties;
|
||||
|
||||
@Autowired
|
||||
private RouteLocator routeLocator;
|
||||
|
||||
private static final String LOCATION_HEADER = "Location";
|
||||
|
||||
public LocationRewriteFilter() {
|
||||
}
|
||||
|
||||
public LocationRewriteFilter(ZuulProperties zuulProperties,
|
||||
RouteLocator routeLocator) {
|
||||
this.routeLocator = routeLocator;
|
||||
this.zuulProperties = zuulProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return POST_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int filterOrder() {
|
||||
return SEND_RESPONSE_FILTER_ORDER - 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilter() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
int statusCode = ctx.getResponseStatusCode();
|
||||
return HttpStatus.valueOf(statusCode).is3xxRedirection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
Route route = routeLocator.getMatchingRoute(
|
||||
urlPathHelper.getPathWithinApplication(ctx.getRequest()));
|
||||
|
||||
if (route != null) {
|
||||
Pair<String, String> lh = locationHeader(ctx);
|
||||
if (lh != null) {
|
||||
String location = lh.second();
|
||||
URI originalRequestUri = UriComponentsBuilder
|
||||
.fromHttpRequest(new ServletServerHttpRequest(ctx.getRequest()))
|
||||
.build().toUri();
|
||||
|
||||
UriComponentsBuilder redirectedUriBuilder = UriComponentsBuilder
|
||||
.fromUriString(location);
|
||||
|
||||
UriComponents redirectedUriComps = redirectedUriBuilder.build();
|
||||
|
||||
String newPath = getRestoredPath(this.zuulProperties, route,
|
||||
redirectedUriComps);
|
||||
|
||||
String modifiedLocation = redirectedUriBuilder
|
||||
.scheme(originalRequestUri.getScheme())
|
||||
.host(originalRequestUri.getHost())
|
||||
.port(originalRequestUri.getPort()).replacePath(newPath).build()
|
||||
.toUriString();
|
||||
|
||||
lh.setSecond(modifiedLocation);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getRestoredPath(ZuulProperties zuulProperties, Route route,
|
||||
UriComponents redirectedUriComps) {
|
||||
StringBuilder path = new StringBuilder();
|
||||
String redirectedPathWithoutGlobal = downstreamHasGlobalPrefix(zuulProperties)
|
||||
? redirectedUriComps.getPath()
|
||||
.substring(("/" + zuulProperties.getPrefix()).length())
|
||||
: redirectedUriComps.getPath();
|
||||
|
||||
if (downstreamHasGlobalPrefix(zuulProperties)) {
|
||||
path.append("/" + zuulProperties.getPrefix());
|
||||
}
|
||||
else {
|
||||
path.append(zuulHasGlobalPrefix(zuulProperties)
|
||||
? "/" + zuulProperties.getPrefix() : "");
|
||||
}
|
||||
|
||||
path.append(downstreamHasRoutePrefix(route) ? "" : "/" + route.getPrefix())
|
||||
.append(redirectedPathWithoutGlobal);
|
||||
|
||||
return path.toString();
|
||||
}
|
||||
|
||||
private boolean downstreamHasGlobalPrefix(ZuulProperties zuulProperties) {
|
||||
return (!zuulProperties.isStripPrefix()
|
||||
&& StringUtils.hasText(zuulProperties.getPrefix()));
|
||||
}
|
||||
|
||||
private boolean zuulHasGlobalPrefix(ZuulProperties zuulProperties) {
|
||||
return StringUtils.hasText(zuulProperties.getPrefix());
|
||||
}
|
||||
|
||||
private boolean downstreamHasRoutePrefix(Route route) {
|
||||
return (!route.isPrefixStripped() && StringUtils.hasText(route.getPrefix()));
|
||||
}
|
||||
|
||||
private Pair<String, String> locationHeader(RequestContext ctx) {
|
||||
if (ctx.getZuulResponseHeaders() != null) {
|
||||
for (Pair<String, String> pair : ctx.getZuulResponseHeaders()) {
|
||||
if (pair.first().equals(LOCATION_HEADER)) {
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2013-2015 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.feign;
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import feign.RetryableException;
|
||||
import feign.Retryer;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Eko Kurniawan Khannedy
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = FeignClientUsingPropertiesTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@TestPropertySource("classpath:feign-properties.properties")
|
||||
@DirtiesContext
|
||||
public class FeignClientUsingPropertiesTests {
|
||||
|
||||
@Autowired
|
||||
FeignContext context;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port = 0;
|
||||
|
||||
private FeignClientFactoryBean fooFactoryBean;
|
||||
|
||||
private FeignClientFactoryBean barFactoryBean;
|
||||
|
||||
public FeignClientUsingPropertiesTests() {
|
||||
fooFactoryBean = new FeignClientFactoryBean();
|
||||
fooFactoryBean.setName("foo");
|
||||
fooFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
|
||||
barFactoryBean = new FeignClientFactoryBean();
|
||||
barFactoryBean.setName("bar");
|
||||
barFactoryBean.setType(FeignClientFactoryBean.class);
|
||||
}
|
||||
|
||||
public FooClient fooClient() {
|
||||
fooFactoryBean.setApplicationContext(applicationContext);
|
||||
return fooFactoryBean.feign(context).target(FooClient.class, "http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
public BarClient barClient() {
|
||||
barFactoryBean.setApplicationContext(applicationContext);
|
||||
return barFactoryBean.feign(context).target(BarClient.class, "http://localhost:" + this.port);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFoo() {
|
||||
String response = fooClient().foo();
|
||||
assertNotNull("OK", response);
|
||||
}
|
||||
|
||||
@Test(expected = RetryableException.class)
|
||||
public void testBar() {
|
||||
barClient().bar();
|
||||
fail("it should timeout");
|
||||
}
|
||||
|
||||
protected interface FooClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/foo")
|
||||
String foo();
|
||||
}
|
||||
|
||||
protected interface BarClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/bar")
|
||||
String bar();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
protected static class Application {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/foo")
|
||||
public String foo(HttpServletRequest request) throws IllegalAccessException {
|
||||
if ("Foo".equals(request.getHeader("Foo")) &&
|
||||
"Bar".equals(request.getHeader("Bar"))) {
|
||||
return "OK";
|
||||
} else {
|
||||
throw new IllegalAccessException("It should has Foo and Bar header");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/bar")
|
||||
public String bar() throws InterruptedException {
|
||||
Thread.sleep(2000L);
|
||||
return "OK";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FooRequestInterceptor implements RequestInterceptor {
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
template.header("Foo", "Foo");
|
||||
}
|
||||
}
|
||||
|
||||
public static class BarRequestInterceptor implements RequestInterceptor {
|
||||
@Override
|
||||
public void apply(RequestTemplate template) {
|
||||
template.header("Bar", "Bar");
|
||||
}
|
||||
}
|
||||
|
||||
public static class NoRetryer implements Retryer {
|
||||
|
||||
@Override
|
||||
public void continueOrPropagate(RetryableException e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Retryer clone() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DefaultErrorDecoder extends ErrorDecoder.Default {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,6 +63,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import static java.nio.charset.Charset.defaultCharset;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
|
||||
import static org.springframework.util.StreamUtils.copyToString;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -271,7 +272,7 @@ class FormZuulProxyApplication {
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
return PRE_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -61,6 +61,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@@ -181,7 +182,7 @@ class FormZuulServletProxyApplication {
|
||||
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
return PRE_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = RetryableZuulProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
|
||||
@@ -100,7 +101,7 @@ class RetryableZuulProxyApplication {
|
||||
return new ZuulFilter() {
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
return PRE_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = SimpleZuulServerApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@@ -119,7 +120,7 @@ class SimpleZuulServerApplication {
|
||||
return new ZuulFilter() {
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
return PRE_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2017 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.post;
|
||||
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.StaticServerList;
|
||||
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Biju Kunjummen
|
||||
*/
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
|
||||
"zuul.routes.aservice.path:/service/**", "zuul.routes.aservice.strip-prefix:true",
|
||||
"eureka.client.enabled:false" })
|
||||
@DirtiesContext
|
||||
public class LocationRewriteFilterIntegrationTests {
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
RequestContext context = new RequestContext();
|
||||
RequestContext.testSetCurrentContext(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithRedirectPrefixStripped() {
|
||||
String url = "http://localhost:" + port + "/service/redirectingUri";
|
||||
ResponseEntity<String> response = new TestRestTemplate().getForEntity(url,
|
||||
String.class);
|
||||
List<String> locationHeaders = response.getHeaders().get("Location");
|
||||
|
||||
assertThat(locationHeaders).hasSize(1);
|
||||
String locationHeader = locationHeaders.get(0);
|
||||
assertThat(locationHeader).withFailMessage("Location should have prefix")
|
||||
.isEqualTo(
|
||||
String.format("http://localhost:%d/service/redirectedUri", port));
|
||||
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@EnableZuulProxy
|
||||
@Controller
|
||||
@RibbonClient(name = "aservice", configuration = RibbonConfig.class)
|
||||
protected static class Config {
|
||||
|
||||
@RequestMapping("/redirectingUri")
|
||||
public String redirect1() {
|
||||
return "redirect:/redirectedUri";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocationRewriteFilter locationRewriteFilter() {
|
||||
return new LocationRewriteFilter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class RibbonConfig {
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Bean
|
||||
public ServerList<Server> ribbonServerList() {
|
||||
return new StaticServerList<>(new Server("localhost", this.port));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2017 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.post;
|
||||
|
||||
import com.netflix.util.Pair;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.netflix.zuul.filters.Route;
|
||||
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
|
||||
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Biju Kunjummen
|
||||
*/
|
||||
|
||||
public class LocationRewriteFilterTests {
|
||||
|
||||
private final String ZUUL_HOST = "myzuul.com";
|
||||
private final String ZUUL_SCHEME = "https";
|
||||
private final int ZUUL_PORT = 8443;
|
||||
private final String ZUUL_BASE_URL = String.format("%s://%s:%d", ZUUL_SCHEME,
|
||||
ZUUL_HOST, ZUUL_PORT);
|
||||
|
||||
private final String SERVER_HOST = "someserver.com";
|
||||
private final String SERVER_SCHEME = "http";
|
||||
private final int SERVER_PORT = 8564;
|
||||
private final String SERVER_BASE_URL = String.format("%s://%s:%d", SERVER_SCHEME,
|
||||
SERVER_HOST, SERVER_PORT);
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
RequestContext context = new RequestContext();
|
||||
RequestContext.testSetCurrentContext(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRewriteLocationHeadersWithRoutePrefix() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
ZuulProperties zuulProperties = new ZuulProperties();
|
||||
LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties,
|
||||
new Route("service1", "/redirectingUri", "service1", "prefix", false,
|
||||
Collections.EMPTY_SET, true),
|
||||
"/prefix/redirectingUri", "/redirectedUri;someparam?param1=abc");
|
||||
filter.run();
|
||||
assertThat(getLocationHeader(context).second()).isEqualTo(String
|
||||
.format("%s/prefix/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeUntouchedIfNoRoutesFound() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
ZuulProperties zuulProperties = new ZuulProperties();
|
||||
LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties, null,
|
||||
"/prefix/redirectingUri", "/redirectedUri;someparam?param1=abc");
|
||||
filter.run();
|
||||
assertThat(getLocationHeader(context).second()).isEqualTo(
|
||||
String.format("%s/redirectedUri;someparam?param1=abc", SERVER_BASE_URL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRewriteLocationHeadersIfPrefixIsNotStripped() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
ZuulProperties zuulProperties = new ZuulProperties();
|
||||
LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties,
|
||||
new Route("service1", "/something/redirectingUri", "service1", "prefix",
|
||||
false, Collections.EMPTY_SET, false),
|
||||
"/prefix/redirectingUri",
|
||||
"/something/redirectedUri;someparam?param1=abc");
|
||||
filter.run();
|
||||
assertThat(getLocationHeader(context).second()).isEqualTo(String.format(
|
||||
"%s/something/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRewriteLocationHeadersIfPrefixIsEmpty() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
ZuulProperties zuulProperties = new ZuulProperties();
|
||||
LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties,
|
||||
new Route("service1", "/something/redirectingUri", "service1", "", false,
|
||||
Collections.EMPTY_SET, true),
|
||||
"/redirectingUri", "/something/redirectedUri;someparam?param1=abc");
|
||||
filter.run();
|
||||
assertThat(getLocationHeader(context).second()).isEqualTo(String.format(
|
||||
"%s/something/redirectedUri;someparam?param1=abc", ZUUL_BASE_URL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddBackGlobalPrefixIfPresent() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
ZuulProperties zuulProperties = new ZuulProperties();
|
||||
zuulProperties.setPrefix("global");
|
||||
zuulProperties.setStripPrefix(true);
|
||||
LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties,
|
||||
new Route("service1", "/something/redirectingUri", "service1", "prefix",
|
||||
false, Collections.EMPTY_SET, true),
|
||||
"/global/prefix/redirectingUri",
|
||||
"/something/redirectedUri;someparam?param1=abc");
|
||||
filter.run();
|
||||
assertThat(getLocationHeader(context).second()).isEqualTo(String.format(
|
||||
"%s/global/prefix/something/redirectedUri;someparam?param1=abc",
|
||||
ZUUL_BASE_URL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotAddBackGlobalPrefixIfNotStripped() {
|
||||
RequestContext context = RequestContext.getCurrentContext();
|
||||
ZuulProperties zuulProperties = new ZuulProperties();
|
||||
zuulProperties.setPrefix("global");
|
||||
zuulProperties.setStripPrefix(false);
|
||||
LocationRewriteFilter filter = setFilterUpWith(context, zuulProperties,
|
||||
new Route("service1", "/something/redirectingUri", "service1", "prefix",
|
||||
false, Collections.EMPTY_SET, true),
|
||||
"/global/prefix/redirectingUri",
|
||||
"/global/something/redirectedUri;someparam?param1=abc");
|
||||
filter.run();
|
||||
assertThat(getLocationHeader(context).second()).isEqualTo(String.format(
|
||||
"%s/global/prefix/something/redirectedUri;someparam?param1=abc",
|
||||
ZUUL_BASE_URL));
|
||||
}
|
||||
|
||||
private LocationRewriteFilter setFilterUpWith(RequestContext context,
|
||||
ZuulProperties zuulProperties, Route route, String toZuulRequestUri,
|
||||
String redirectedUri) {
|
||||
MockHttpServletRequest httpServletRequest = new MockHttpServletRequest();
|
||||
httpServletRequest.setRequestURI(toZuulRequestUri);
|
||||
httpServletRequest.setServerName(ZUUL_HOST);
|
||||
httpServletRequest.setScheme(ZUUL_SCHEME);
|
||||
httpServletRequest.setServerPort(ZUUL_PORT);
|
||||
context.setRequest(httpServletRequest);
|
||||
|
||||
MockHttpServletResponse httpServletResponse = new MockHttpServletResponse();
|
||||
context.getZuulResponseHeaders().add(new Pair<>("Location",
|
||||
String.format("%s%s", SERVER_BASE_URL, redirectedUri)));
|
||||
context.setResponse(httpServletResponse);
|
||||
|
||||
RouteLocator routeLocator = mock(RouteLocator.class);
|
||||
when(routeLocator.getMatchingRoute(toZuulRequestUri)).thenReturn(route);
|
||||
LocationRewriteFilter filter = new LocationRewriteFilter(zuulProperties,
|
||||
routeLocator);
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
private Pair<String, String> getLocationHeader(RequestContext ctx) {
|
||||
if (ctx.getZuulResponseHeaders() != null) {
|
||||
for (Pair<String, String> pair : ctx.getZuulResponseHeaders()) {
|
||||
if (pair.first().equals("Location")) {
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.ROUTE_TYPE;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -111,7 +114,7 @@ public class SendErrorFilterIntegrationTests {
|
||||
return new FailureFilter() {
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
return PRE_TYPE;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -121,7 +124,7 @@ public class SendErrorFilterIntegrationTests {
|
||||
return new FailureFilter() {
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "route";
|
||||
return ROUTE_TYPE;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -131,7 +134,7 @@ public class SendErrorFilterIntegrationTests {
|
||||
return new FailureFilter() {
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "post";
|
||||
return POST_TYPE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.FORWARD_TO_KEY;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVICE_ID_KEY;
|
||||
|
||||
@@ -85,7 +86,7 @@ public class PreDecorationFilterTests {
|
||||
public void basicProperties() throws Exception {
|
||||
assertEquals(5, this.filter.filterOrder());
|
||||
assertEquals(true, this.filter.shouldFilter());
|
||||
assertEquals("pre", this.filter.filterType());
|
||||
assertEquals(PRE_TYPE, this.filter.filterType());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.netflix.zuul.filters.route.support;
|
||||
|
||||
import com.netflix.client.AbstractLoadBalancerAwareClient;
|
||||
import com.netflix.client.ClientRequest;
|
||||
import com.netflix.client.http.HttpResponse;
|
||||
import com.netflix.hystrix.HystrixCommandProperties;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -91,7 +93,8 @@ public class RibbonCommandHystrixThreadPoolKeyTests {
|
||||
assertThat(ribbonCommand2.getThreadPoolKey().name()).isEqualTo(ribbonCommand2.getCommandGroup().name());
|
||||
}
|
||||
|
||||
public static class TestRibbonCommand extends AbstractRibbonCommand {
|
||||
public static class TestRibbonCommand
|
||||
extends AbstractRibbonCommand<AbstractLoadBalancerAwareClient<ClientRequest, HttpResponse>, ClientRequest, HttpResponse> {
|
||||
public TestRibbonCommand(String commandKey, ZuulProperties zuulProperties) {
|
||||
super(commandKey, null, null, zuulProperties);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -406,7 +407,7 @@ public abstract class ZuulProxyTestBase {
|
||||
return new ZuulFilter() {
|
||||
@Override
|
||||
public String filterType() {
|
||||
return "pre";
|
||||
return PRE_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# This configuration used by test class org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests
|
||||
|
||||
logging.level.org.springframework.cloud.netflix.feign=debug
|
||||
|
||||
feign.client.default-to-properties=true
|
||||
feign.client.default-config=default
|
||||
|
||||
feign.client.config.default.connectTimeout=5000
|
||||
feign.client.config.default.readTimeout=5000
|
||||
feign.client.config.default.loggerLevel=full
|
||||
feign.client.config.default.errorDecoder=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.DefaultErrorDecoder
|
||||
feign.client.config.default.retryer=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.NoRetryer
|
||||
feign.client.config.default.decode404=true
|
||||
|
||||
feign.client.config.foo.requestInterceptors[0]=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.FooRequestInterceptor
|
||||
feign.client.config.foo.requestInterceptors[1]=org.springframework.cloud.netflix.feign.FeignClientUsingPropertiesTests.BarRequestInterceptor
|
||||
|
||||
feign.client.config.bar.connectTimeout=1000
|
||||
feign.client.config.bar.readTimeout=1000
|
||||
@@ -33,6 +33,8 @@ import com.netflix.discovery.shared.transport.EurekaTransportConfig;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import static org.springframework.cloud.netflix.eureka.EurekaConstants.DEFAULT_PREFIX;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -45,7 +47,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
@Autowired(required = false)
|
||||
PropertyResolver propertyResolver;
|
||||
|
||||
public static final String DEFAULT_URL = "http://localhost:8761" + EurekaConstants.DEFAULT_PREFIX
|
||||
public static final String DEFAULT_URL = "http://localhost:8761" + DEFAULT_PREFIX
|
||||
+ "/";
|
||||
|
||||
public static final String DEFAULT_ZONE = "defaultZone";
|
||||
|
||||
@@ -122,8 +122,9 @@ public class EurekaAutoServiceRegistration implements AutoServiceRegistration, S
|
||||
|
||||
@EventListener(ContextClosedEvent.class)
|
||||
public void onApplicationEvent(ContextClosedEvent event) {
|
||||
// register in case meta data changed
|
||||
stop();
|
||||
if( event.getApplicationContext() == context ) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user