Upgrade Feign to 10.11. Remove some deprecations. Refactor. (#767)
This commit is contained in:
committed by
GitHub
parent
b3578fc454
commit
5b0f9f74af
6
.github/workflows/maven.yml
vendored
6
.github/workflows/maven.yml
vendored
@@ -5,9 +5,9 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
branches: [ 3.1.x ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
branches: [ 3.1.x ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
java: ["8", "11", "16"]
|
||||
java: ["8"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -21,10 +21,11 @@ import feign.slf4j.Slf4jLogger;
|
||||
|
||||
/**
|
||||
* @author Venil Noronha
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
public class DefaultFeignLoggerFactory implements FeignLoggerFactory {
|
||||
|
||||
private Logger logger;
|
||||
private final Logger logger;
|
||||
|
||||
public DefaultFeignLoggerFactory(Logger logger) {
|
||||
this.logger = logger;
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.context.ApplicationContext;
|
||||
* @author Sven Döring
|
||||
* @author Matt King
|
||||
* @author Sam Kruglov
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
public class FeignClientBuilder {
|
||||
|
||||
@@ -54,7 +55,7 @@ public class FeignClientBuilder {
|
||||
*/
|
||||
public static final class Builder<T> {
|
||||
|
||||
private FeignClientFactoryBean feignClientFactoryBean;
|
||||
private final FeignClientFactoryBean feignClientFactoryBean;
|
||||
|
||||
private Builder(final ApplicationContext applicationContext, final Class<T> type, final String name) {
|
||||
this(applicationContext, new FeignClientFactoryBean(), type, name);
|
||||
|
||||
@@ -79,7 +79,7 @@ public class FeignClientFactoryBean
|
||||
* lifecycle race condition.
|
||||
***********************************/
|
||||
|
||||
private static Log LOG = LogFactory.getLog(FeignClientFactoryBean.class);
|
||||
private static final Log LOG = LogFactory.getLog(FeignClientFactoryBean.class);
|
||||
|
||||
private Class<?> type;
|
||||
|
||||
@@ -215,7 +215,7 @@ public class FeignClientFactoryBean
|
||||
builder.queryMapEncoder(queryMapEncoder);
|
||||
}
|
||||
if (decode404) {
|
||||
builder.decode404();
|
||||
builder.dismiss404();
|
||||
}
|
||||
ExceptionPropagationPolicy exceptionPropagationPolicy = getInheritedAwareOptional(context,
|
||||
ExceptionPropagationPolicy.class);
|
||||
@@ -270,7 +270,7 @@ public class FeignClientFactoryBean
|
||||
|
||||
if (config.getDecode404() != null) {
|
||||
if (config.getDecode404()) {
|
||||
builder.decode404();
|
||||
builder.dismiss404();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.cloud.openfeign.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import feign.MethodMetadata;
|
||||
|
||||
@@ -30,8 +30,10 @@ import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
/**
|
||||
* @{link CookieValue} annotation processor.
|
||||
* {@link CookieValue} annotation processor.
|
||||
*
|
||||
* @author Gong Yi
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*
|
||||
*/
|
||||
public class CookieValueParameterProcessor implements AnnotatedParameterProcessor {
|
||||
@@ -51,8 +53,8 @@ public class CookieValueParameterProcessor implements AnnotatedParameterProcesso
|
||||
String name = cookie.value().trim();
|
||||
checkState(emptyToNull(name) != null, "Cookie.name() was empty on parameter %s", parameterIndex);
|
||||
context.setParameterName(name);
|
||||
String cookieExpression = data.template().headers().getOrDefault(HttpHeaders.COOKIE, Arrays.asList("")).stream()
|
||||
.findFirst().orElse("");
|
||||
String cookieExpression = data.template().headers()
|
||||
.getOrDefault(HttpHeaders.COOKIE, Collections.singletonList("")).stream().findFirst().orElse("");
|
||||
if (cookieExpression.length() == 0) {
|
||||
cookieExpression = String.format("%s={%s}", name, name);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.cloud.openfeign.SpringQueryMap;
|
||||
* {@link SpringQueryMap} parameter processor.
|
||||
*
|
||||
* @author Aram Peres
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @see AnnotatedParameterProcessor
|
||||
*/
|
||||
public class QueryMapParameterProcessor implements AnnotatedParameterProcessor {
|
||||
@@ -45,7 +46,6 @@ public class QueryMapParameterProcessor implements AnnotatedParameterProcessor {
|
||||
MethodMetadata metadata = context.getMethodMetadata();
|
||||
if (metadata.queryMapIndex() == null) {
|
||||
metadata.queryMapIndex(paramIndex);
|
||||
metadata.queryMapEncoded(SpringQueryMap.class.cast(annotation).encoded());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ import org.springframework.security.oauth2.client.token.grant.password.ResourceO
|
||||
@Deprecated // spring-security-oauth2 reached EOL
|
||||
public class OAuth2FeignRequestInterceptorBuilder {
|
||||
|
||||
private AccessTokenProvider accessTokenProvider;
|
||||
private final AccessTokenProvider accessTokenProvider;
|
||||
|
||||
private final List<ClientHttpRequestInterceptor> accessTokenProviderInterceptors = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.springframework.cloud.openfeign.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -44,16 +42,6 @@ public final class FeignUtils {
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
static Map<String, Collection<String>> getHeaders(HttpHeaders httpHeaders) {
|
||||
LinkedHashMap<String, Collection<String>> headers = new LinkedHashMap<>();
|
||||
|
||||
for (Map.Entry<String, List<String>> entry : httpHeaders.entrySet()) {
|
||||
headers.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
static Collection<String> addTemplateParameter(Collection<String> possiblyNull, String paramName) {
|
||||
Collection<String> params = ofNullable(possiblyNull).map(ArrayList::new).orElse(new ArrayList<>());
|
||||
params.add(String.format("{%s}", paramName));
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.http.ResponseEntity;
|
||||
*/
|
||||
public class ResponseEntityDecoder implements Decoder {
|
||||
|
||||
private Decoder decoder;
|
||||
private final Decoder decoder;
|
||||
|
||||
public ResponseEntityDecoder(Decoder decoder) {
|
||||
this.decoder = decoder;
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
@@ -49,7 +50,6 @@ import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import static org.springframework.cloud.openfeign.support.FeignUtils.getHeaders;
|
||||
import static org.springframework.cloud.openfeign.support.FeignUtils.getHttpHeaders;
|
||||
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;
|
||||
import static org.springframework.http.MediaType.MULTIPART_FORM_DATA;
|
||||
@@ -158,7 +158,7 @@ public class SpringEncoder implements Encoder {
|
||||
request.headers(null);
|
||||
// converters can modify headers, so update the request
|
||||
// with the modified headers
|
||||
request.headers(getHeaders(outputMessage.getHeaders()));
|
||||
request.headers(new LinkedHashMap<>(outputMessage.getHeaders()));
|
||||
|
||||
// do not use charset for binary data and protobuf
|
||||
Charset charset;
|
||||
|
||||
@@ -108,7 +108,7 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
|
||||
|
||||
private ResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
|
||||
private boolean decodeSlash;
|
||||
private final boolean decodeSlash;
|
||||
|
||||
public SpringMvcContract() {
|
||||
this(Collections.emptyList());
|
||||
|
||||
@@ -68,7 +68,7 @@ class FeignBuilderCustomizerTests {
|
||||
Assertions.assertNotNull(feignBuilderCaptor.getValue());
|
||||
Feign.Builder builder = feignBuilderCaptor.getValue();
|
||||
assertFeignBuilderField(builder, "logLevel", Logger.Level.HEADERS);
|
||||
assertFeignBuilderField(builder, "decode404", true);
|
||||
assertFeignBuilderField(builder, "dismiss404", true);
|
||||
|
||||
context.close();
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class FeignBuilderCustomizerTests {
|
||||
Assertions.assertNotNull(feignBuilderCaptor.getValue());
|
||||
Feign.Builder builder = feignBuilderCaptor.getValue();
|
||||
assertFeignBuilderField(builder, "logLevel", Logger.Level.FULL);
|
||||
assertFeignBuilderField(builder, "decode404", true);
|
||||
assertFeignBuilderField(builder, "dismiss404", true);
|
||||
|
||||
context.close();
|
||||
}
|
||||
@@ -116,7 +116,7 @@ class FeignBuilderCustomizerTests {
|
||||
Assertions.assertNotNull(feignBuilderCaptor.getValue());
|
||||
Feign.Builder builder = feignBuilderCaptor.getValue();
|
||||
assertFeignBuilderField(builder, "logLevel", Logger.Level.BASIC);
|
||||
assertFeignBuilderField(builder, "decode404", true);
|
||||
assertFeignBuilderField(builder, "dismiss404", true);
|
||||
assertFeignBuilderField(builder, "closeAfterDecode", false);
|
||||
|
||||
context.close();
|
||||
@@ -178,7 +178,7 @@ class FeignBuilderCustomizerTests {
|
||||
|
||||
@Bean
|
||||
FeignBuilderCustomizer feignBuilderCustomizer2() {
|
||||
return Feign.Builder::decode404;
|
||||
return Feign.Builder::dismiss404;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -221,7 +221,7 @@ class FeignBuilderCustomizerTests {
|
||||
|
||||
@Bean
|
||||
FeignBuilderCustomizer feignBuilderCustomizer2() {
|
||||
return Feign.Builder::decode404;
|
||||
return Feign.Builder::dismiss404;
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.openfeign;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -45,6 +46,7 @@ import static org.springframework.cloud.openfeign.test.EqualsAndHashCodeAssert.a
|
||||
/**
|
||||
* @author Jonatan Ivanov
|
||||
* @author Hyeonmin Park
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
class FeignClientConfigurationTests {
|
||||
|
||||
@@ -80,9 +82,9 @@ class FeignClientConfigurationTests {
|
||||
config.setErrorDecoder(ErrorDecoder.class);
|
||||
List<Class<RequestInterceptor>> requestInterceptors = Lists.list(RequestInterceptor.class);
|
||||
config.setRequestInterceptors(requestInterceptors);
|
||||
Map<String, Collection<String>> defaultRequestHeaders = Maps.newHashMap("default", Lists.emptyList());
|
||||
Map<String, Collection<String>> defaultRequestHeaders = Maps.newHashMap("default", Collections.emptyList());
|
||||
config.setDefaultRequestHeaders(defaultRequestHeaders);
|
||||
Map<String, Collection<String>> defaultQueryParameters = Maps.newHashMap("default", Lists.emptyList());
|
||||
Map<String, Collection<String>> defaultQueryParameters = Maps.newHashMap("default", Collections.emptyList());
|
||||
config.setDefaultQueryParameters(defaultQueryParameters);
|
||||
config.setDecode404(true);
|
||||
config.setDecoder(Decoder.class);
|
||||
|
||||
@@ -35,6 +35,7 @@ import feign.codec.ErrorDecoder;
|
||||
import feign.micrometer.MicrometerCapability;
|
||||
import feign.optionals.OptionalDecoder;
|
||||
import feign.querymap.BeanQueryMapEncoder;
|
||||
import feign.querymap.FieldQueryMapEncoder;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -49,6 +50,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
@@ -127,8 +129,10 @@ class FeignClientOverrideDefaultsTests {
|
||||
|
||||
@Test
|
||||
void overrideQueryMapEncoder() {
|
||||
QueryMapEncoder.Default.class.cast(context.getInstance("foo", QueryMapEncoder.class));
|
||||
BeanQueryMapEncoder.class.cast(context.getInstance("bar", QueryMapEncoder.class));
|
||||
assertThatCode(() -> {
|
||||
FieldQueryMapEncoder.class.cast(context.getInstance("foo", QueryMapEncoder.class));
|
||||
BeanQueryMapEncoder.class.cast(context.getInstance("bar", QueryMapEncoder.class));
|
||||
}).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -208,7 +212,7 @@ class FeignClientOverrideDefaultsTests {
|
||||
|
||||
@Bean
|
||||
public Logger feignLogger() {
|
||||
return new Logger.JavaLogger();
|
||||
return new Logger.JavaLogger(FooConfiguration.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -218,7 +222,7 @@ class FeignClientOverrideDefaultsTests {
|
||||
|
||||
@Bean
|
||||
public QueryMapEncoder queryMapEncoder() {
|
||||
return new feign.QueryMapEncoder.Default();
|
||||
return new FieldQueryMapEncoder();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -420,7 +420,10 @@ public class FeignClientUsingPropertiesTests {
|
||||
Map<String, String> form = (Map<String, String>) o;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
form.forEach((key, value) -> {
|
||||
builder.append(key + "=" + value + "&");
|
||||
builder.append(key);
|
||||
builder.append("=");
|
||||
builder.append(value);
|
||||
builder.append("&");
|
||||
});
|
||||
|
||||
requestTemplate.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
|
||||
@@ -36,7 +36,7 @@ import feign.Response;
|
||||
*/
|
||||
public class OptionsTestClient implements Client {
|
||||
|
||||
private static ObjectMapper mapper;
|
||||
private final static ObjectMapper mapper;
|
||||
|
||||
static {
|
||||
mapper = new ObjectMapper();
|
||||
@@ -69,13 +69,13 @@ public class OptionsTestClient implements Client {
|
||||
|
||||
static class OptionsResponseForTests {
|
||||
|
||||
private long connectTimeout;
|
||||
private final long connectTimeout;
|
||||
|
||||
private TimeUnit connectTimeoutUnit;
|
||||
private final TimeUnit connectTimeoutUnit;
|
||||
|
||||
private long readTimeout;
|
||||
private final long readTimeout;
|
||||
|
||||
private TimeUnit readTimeoutUnit;
|
||||
private final TimeUnit readTimeoutUnit;
|
||||
|
||||
OptionsResponseForTests(long connectTimeout, TimeUnit connectTimeoutUnit, long readTimeout,
|
||||
TimeUnit readTimeoutUnit) {
|
||||
|
||||
@@ -47,7 +47,6 @@ import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
|
||||
|
||||
import static feign.Request.Body.encoded;
|
||||
import static feign.Request.HttpMethod.POST;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
@@ -56,6 +55,7 @@ import static org.assertj.core.api.Assertions.fail;
|
||||
* Test {@link SpringEncoder} with {@link ProtobufHttpMessageConverter}
|
||||
*
|
||||
* @author ScienJus
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ProtobufSpringEncoderTest {
|
||||
@@ -64,7 +64,7 @@ class ProtobufSpringEncoderTest {
|
||||
private HttpClient httpClient;
|
||||
|
||||
// a protobuf object with some content
|
||||
private org.springframework.cloud.openfeign.encoding.proto.Request request = org.springframework.cloud.openfeign.encoding.proto.Request
|
||||
private final org.springframework.cloud.openfeign.encoding.proto.Request request = org.springframework.cloud.openfeign.encoding.proto.Request
|
||||
.newBuilder().setId(1000000)
|
||||
.setMsg("Erlang/OTP 最初是爱立信为开发电信设备系统设计的编程语言平台," + "电信设备(路由器、接入网关、…)典型设计是通过背板连接主控板卡与多块业务板卡的分布式系统。").build();
|
||||
|
||||
@@ -88,7 +88,7 @@ class ProtobufSpringEncoderTest {
|
||||
RequestTemplate requestTemplate = newRequestTemplate();
|
||||
newEncoder().encode(this.request, Request.class, requestTemplate);
|
||||
// set a charset
|
||||
requestTemplate.body(encoded(requestTemplate.requestBody().asBytes(), StandardCharsets.UTF_8));
|
||||
requestTemplate.body(requestTemplate.body(), StandardCharsets.UTF_8);
|
||||
HttpEntity entity = toApacheHttpEntity(requestTemplate);
|
||||
byte[] bytes = read(entity.getContent(), (int) entity.getContentLength());
|
||||
|
||||
|
||||
@@ -177,12 +177,12 @@ class FeignBlockingLoadBalancerClientTests {
|
||||
private String read(Response response) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(response.body().asInputStream(), StandardCharsets.UTF_8));
|
||||
String outputString = "";
|
||||
StringBuilder outputString = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
outputString += line;
|
||||
outputString.append(line);
|
||||
}
|
||||
return outputString;
|
||||
return outputString.toString();
|
||||
}
|
||||
|
||||
private Request testRequest() {
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.springframework.security.oauth2.common.OAuth2RefreshToken;
|
||||
*/
|
||||
public class MockAccessTokenProvider implements AccessTokenProvider {
|
||||
|
||||
private OAuth2AccessToken token;
|
||||
private final OAuth2AccessToken token;
|
||||
|
||||
public MockAccessTokenProvider(OAuth2AccessToken token) {
|
||||
this.token = token;
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.security.oauth2.common.OAuth2RefreshToken;
|
||||
*/
|
||||
public class MockOAuth2AccessToken implements OAuth2AccessToken {
|
||||
|
||||
private String value;
|
||||
private final String value;
|
||||
|
||||
public MockOAuth2AccessToken(String value) {
|
||||
this.value = value;
|
||||
|
||||
@@ -42,7 +42,7 @@ import static org.springframework.cloud.openfeign.support.FeignHttpClientPropert
|
||||
@DirtiesContext
|
||||
class FeignHttpClientPropertiesTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@AfterEach
|
||||
void clear() {
|
||||
|
||||
@@ -179,7 +179,7 @@ class SpringEncoderTests {
|
||||
.isEqualTo(MULTIPART_FORM_DATA_VALUE);
|
||||
assertThat(((List) request.headers().get(CONTENT_LENGTH)).get(0))
|
||||
.as("Request Content-Length is not equal to 186").isEqualTo("186");
|
||||
assertThat(new String(request.requestBody().asBytes())).as("Body content cannot be decoded").contains("hi");
|
||||
assertThat(new String(request.body())).as("Body content cannot be decoded").contains("hi");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -190,7 +190,7 @@ class SpringEncoderTests {
|
||||
request.header(CONTENT_TYPE, APPLICATION_FORM_URLENCODED_VALUE);
|
||||
String body = "test";
|
||||
encoder.encode(body, String.class, request);
|
||||
assertThat(new String(request.requestBody().asBytes())).as("Body content cannot be decoded").contains(body);
|
||||
assertThat(new String(request.body())).as("Body content cannot be decoded").contains(body);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<name>spring-cloud-openfeign-dependencies</name>
|
||||
<description>Spring Cloud OpenFeign Dependencies</description>
|
||||
<properties>
|
||||
<feign.version>11.8</feign.version>
|
||||
<feign.version>11.10</feign.version>
|
||||
<feign-form.version>3.8.0</feign-form.version>
|
||||
<!-- Deprecated - reached EOL -->
|
||||
<spring-security-oauth2-autoconfigure.version>2.5.2</spring-security-oauth2-autoconfigure.version>
|
||||
|
||||
Reference in New Issue
Block a user