Compare commits
12
Commits
v3.0.2
...
v2.2.8.RELEASE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c33bc490cd | ||
|
|
d738b3b224 | ||
|
|
0c1d281970 | ||
|
|
0bf0426f60 | ||
|
|
9f9ce39789 | ||
|
|
4d0caec7ee | ||
|
|
92f7ba9901 | ||
|
|
b2c208ba5f | ||
|
|
cdfd3695c2 | ||
|
|
59216f2f82 | ||
|
|
4d827623f0 | ||
|
|
5e494aa196 |
@@ -1,38 +0,0 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: springcloud/pipeline-base
|
||||
environment:
|
||||
_JAVA_OPTIONS: "-Xms1024m -Xmx2048m"
|
||||
TERM: dumb
|
||||
branches:
|
||||
ignore:
|
||||
- gh-pages # list of branches to ignore
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
key: sc-openfeign-{{ .Branch }}
|
||||
- run:
|
||||
name: "Download dependencies"
|
||||
command: ./mvnw -s .settings.xml -U --fail-never dependency:go-offline || true
|
||||
- save_cache:
|
||||
key: sc-openfeign-{{ .Branch }}
|
||||
paths:
|
||||
- ~/.m2
|
||||
- run:
|
||||
name: "Running build"
|
||||
command: ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
||||
- run:
|
||||
name: "Aggregate test results"
|
||||
when: always
|
||||
command: |
|
||||
mkdir -p $CIRCLE_TEST_REPORTS/junit/
|
||||
find . -type f -regex ".*/target/.*-reports/.*" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \;
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
- store_artifacts:
|
||||
path: /junit/
|
||||
destination: artifacts
|
||||
- store_test_results:
|
||||
path: /junit/
|
||||
destination: testartifacts
|
||||
@@ -0,0 +1,35 @@
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 2.2.x ]
|
||||
pull_request:
|
||||
branches: [ 2.2.x ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
java: ["8", "11", "16"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Cache local Maven repository
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Build with Maven
|
||||
run: ./mvnw clean install -B -U
|
||||
+1
-1
@@ -5,7 +5,7 @@ Edit the files in the src/main/asciidoc/ directory instead.
|
||||
////
|
||||
|
||||
|
||||
image:https://circleci.com/gh/spring-cloud/spring-cloud-openfeign.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-openfeign"]
|
||||
image::https://github.com/spring-cloud/spring-cloud-openfeign/workflows/Build/badge.svg?branch=2.2.x&style=svg["Build",link="https://github.com/spring-cloud/spring-cloud-openfeign/actions"]
|
||||
|
||||
image:https://codecov.io/gh/spring-cloud/spring-cloud-openfeign/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-openfeign"]
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.2.8.BUILD-SNAPSHOT</version>
|
||||
<version>2.2.8.RELEASE</version>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-openfeign-docs</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
image:https://circleci.com/gh/spring-cloud/spring-cloud-openfeign.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-openfeign"]
|
||||
image::https://github.com/spring-cloud/spring-cloud-openfeign/workflows/Build/badge.svg?branch=2.2.x&style=svg["Build",link="https://github.com/spring-cloud/spring-cloud-openfeign/actions"]
|
||||
|
||||
image:https://codecov.io/gh/spring-cloud/spring-cloud-openfeign/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-openfeign"]
|
||||
|
||||
|
||||
@@ -18,15 +18,16 @@
|
||||
|feign.httpclient.disable-ssl-validation | `false` |
|
||||
|feign.httpclient.enabled | `true` | Enables the use of the Apache HTTP Client by Feign.
|
||||
|feign.httpclient.follow-redirects | `true` |
|
||||
|feign.httpclient.hc5.enabled | `false` | Enables the use of the Apache HTTP Client 5 by Feign.
|
||||
|feign.httpclient.hc5.pool-concurrency-policy | | Pool concurrency policies.
|
||||
|feign.httpclient.hc5.pool-reuse-policy | | Pool connection re-use policies.
|
||||
|feign.httpclient.hc5.socket-timeout | `5` | Default value for socket timeout.
|
||||
|feign.httpclient.hc5.socket-timeout-unit | | Default value for socket timeout unit.
|
||||
|feign.httpclient.max-connections | `200` |
|
||||
|feign.httpclient.max-connections-per-route | `50` |
|
||||
|feign.httpclient.time-to-live | `900` |
|
||||
|feign.httpclient.time-to-live-unit | |
|
||||
|feign.hystrix.enabled | `false` | If true, an OpenFeign client will be wrapped with a Hystrix circuit breaker.
|
||||
|feign.okhttp.enabled | `false` | Enables the use of the OK HTTP Client by Feign.
|
||||
|feign.httpclient.hc5.enabled | `false` | Enables the use of the Apache HC5 by Feign.
|
||||
|feign.httpclient.hc5.socket-timeout | `5` |
|
||||
|feign.httpclient.hc5.socket-timeout-unit | `seconds` |
|
||||
|feign.httpclient.hc5.pool-reuse-policy | `fifo` | Pooled connection re-use policies
|
||||
|feign.httpclient.hc5.pool-concurrency-policy | `strict` | Pool concurrency policies
|
||||
|===
|
||||
|
||||
|===
|
||||
@@ -393,7 +393,7 @@ favor for an opt-in approach.
|
||||
[[spring-cloud-feign-hystrix-fallback]]
|
||||
=== Feign Hystrix Fallbacks
|
||||
|
||||
Hystrix supports the notion of a fallback: a default code path that is executed when they circuit is open or there is an error. To enable fallbacks for a given `@FeignClient` set the `fallback` attribute to the class name that implements the fallback. You also need to declare your implementation as a Spring bean.
|
||||
Hystrix supports the notion of a fallback: a default code path that is executed when the circuit is open or there is an error. To enable fallbacks for a given `@FeignClient` set the `fallback` attribute to the class name that implements the fallback. You also need to declare your implementation as a Spring bean.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@@ -461,7 +461,7 @@ The circuit breaker name follows this pattern `<feignClientName>#<calledMethod>`
|
||||
[[spring-cloud-feign-circuitbreaker-fallback]]
|
||||
=== Feign Spring Cloud CircuitBreaker Fallbacks
|
||||
|
||||
Spring Cloud CircuitBreaker supports the notion of a fallback: a default code path that is executed when they circuit is open or there is an error. To enable fallbacks for a given `@FeignClient` set the `fallback` attribute to the class name that implements the fallback. You also need to declare your implementation as a Spring bean.
|
||||
Spring Cloud CircuitBreaker supports the notion of a fallback: a default code path that is executed when the circuit is open or there is an error. To enable fallbacks for a given `@FeignClient` set the `fallback` attribute to the class name that implements the fallback. You also need to declare your implementation as a Spring bean.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.2.8.BUILD-SNAPSHOT</version>
|
||||
<version>2.2.8.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud OpenFeign</name>
|
||||
<description>Spring Cloud OpenFeign</description>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>2.3.2.RELEASE</version>
|
||||
<version>2.3.4.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<scm>
|
||||
@@ -26,8 +26,8 @@
|
||||
<properties>
|
||||
<main.basedir>${basedir}</main.basedir>
|
||||
<jackson.version>2.11.3</jackson.version>
|
||||
<spring-cloud-commons.version>2.2.8.BUILD-SNAPSHOT</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.2.8.BUILD-SNAPSHOT</spring-cloud-netflix.version>
|
||||
<spring-cloud-commons.version>2.2.8.RELEASE</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.2.8.RELEASE</spring-cloud-netflix.version>
|
||||
|
||||
<!-- Plugin versions -->
|
||||
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.2.8.BUILD-SNAPSHOT</version>
|
||||
<version>2.2.8.RELEASE</version>
|
||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>spring-cloud-openfeign-core</artifactId>
|
||||
|
||||
+14
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.openfeign;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.hystrix.FallbackFactory;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -28,6 +29,7 @@ import org.springframework.context.ApplicationContext;
|
||||
*
|
||||
* @author Sven Döring
|
||||
* @author Matt King
|
||||
* @author Sam Kruglov
|
||||
*/
|
||||
public class FeignClientBuilder {
|
||||
|
||||
@@ -69,6 +71,18 @@ public class FeignClientBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a {@link FeignBuilderCustomizer} to the underlying
|
||||
* {@link Feign.Builder}. May be called multiple times.
|
||||
* @param customizer applied in the same order as supplied here after applying
|
||||
* customizers found in the context.
|
||||
* @return the {@link Builder} with the customizer added
|
||||
*/
|
||||
public Builder<T> customize(final FeignBuilderCustomizer customizer) {
|
||||
this.feignClientFactoryBean.addCustomizer(customizer);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> contextId(final String contextId) {
|
||||
this.feignClientFactoryBean.setContextId(contextId);
|
||||
return this;
|
||||
|
||||
+20
-1
@@ -35,6 +35,8 @@ import feign.Target.HardCodedTarget;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -62,6 +64,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @author Ilia Ilinykh
|
||||
* @author Marcin Grzejszczak
|
||||
* @author Sam Kruglov
|
||||
*/
|
||||
public class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
|
||||
ApplicationContextAware, BeanFactoryAware {
|
||||
@@ -71,6 +74,8 @@ public class FeignClientFactoryBean implements FactoryBean<Object>, Initializing
|
||||
* lifecycle race condition.
|
||||
***********************************/
|
||||
|
||||
private static Log LOG = LogFactory.getLog(FeignClientFactoryBean.class);
|
||||
|
||||
private Class<?> type;
|
||||
|
||||
private String name;
|
||||
@@ -99,6 +104,8 @@ public class FeignClientFactoryBean implements FactoryBean<Object>, Initializing
|
||||
|
||||
private boolean followRedirects = new Request.Options().isFollowRedirects();
|
||||
|
||||
private List<FeignBuilderCustomizer> additionalCustomizers = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
Assert.hasText(contextId, "Context id must be set");
|
||||
@@ -134,6 +141,7 @@ public class FeignClientFactoryBean implements FactoryBean<Object>, Initializing
|
||||
.forEach(feignBuilderCustomizer -> feignBuilderCustomizer
|
||||
.customize(builder));
|
||||
}
|
||||
additionalCustomizers.forEach(customizer -> customizer.customize(builder));
|
||||
}
|
||||
|
||||
protected void configureFeign(FeignContext context, Feign.Builder builder) {
|
||||
@@ -345,7 +353,7 @@ public class FeignClientFactoryBean implements FactoryBean<Object>, Initializing
|
||||
}
|
||||
|
||||
throw new IllegalStateException(
|
||||
"No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?");
|
||||
"No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon or spring-cloud-starter-loadbalancer?");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -365,6 +373,13 @@ public class FeignClientFactoryBean implements FactoryBean<Object>, Initializing
|
||||
Feign.Builder builder = feign(context);
|
||||
|
||||
if (!StringUtils.hasText(url)) {
|
||||
if (url != null && LOG.isWarnEnabled()) {
|
||||
LOG.warn(
|
||||
"The provided URL is empty. Will try picking an instance via load-balancing.");
|
||||
}
|
||||
else if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("URL not provided. Will use LoadBalancer.");
|
||||
}
|
||||
if (!name.startsWith("http")) {
|
||||
url = "http://" + name;
|
||||
}
|
||||
@@ -483,6 +498,10 @@ public class FeignClientFactoryBean implements FactoryBean<Object>, Initializing
|
||||
this.inheritParentContext = inheritParentContext;
|
||||
}
|
||||
|
||||
public void addCustomizer(FeignBuilderCustomizer customizer) {
|
||||
additionalCustomizers.add(customizer);
|
||||
}
|
||||
|
||||
public ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
+20
@@ -33,6 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Matt King
|
||||
* @author Sam Kruglov
|
||||
*/
|
||||
public class FeignBuilderCustomizerTests {
|
||||
|
||||
@@ -78,6 +79,25 @@ public class FeignBuilderCustomizerTests {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildCustomizerOrderedWithAdditional() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
FeignBuilderCustomizerTests.SampleConfiguration3.class);
|
||||
|
||||
FeignClientFactoryBean clientFactoryBean = context
|
||||
.getBean(FeignClientFactoryBean.class);
|
||||
clientFactoryBean.addCustomizer(builder -> builder.logLevel(Logger.Level.BASIC));
|
||||
clientFactoryBean.addCustomizer(Feign.Builder::doNotCloseAfterDecode);
|
||||
FeignContext feignContext = context.getBean(FeignContext.class);
|
||||
|
||||
Feign.Builder builder = clientFactoryBean.feign(feignContext);
|
||||
assertFeignBuilderField(builder, "logLevel", Logger.Level.BASIC);
|
||||
assertFeignBuilderField(builder, "decode404", true);
|
||||
assertFeignBuilderField(builder, "closeAfterDecode", false);
|
||||
|
||||
context.close();
|
||||
}
|
||||
|
||||
private static FeignClientFactoryBean defaultFeignClientFactoryBean() {
|
||||
FeignClientFactoryBean feignClientFactoryBean = new FeignClientFactoryBean();
|
||||
feignClientFactoryBean.setContextId("test");
|
||||
|
||||
+22
-6
@@ -24,6 +24,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import feign.Feign;
|
||||
import feign.hystrix.FallbackFactory;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
@@ -40,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Sven Döring
|
||||
* @author Sam Kruglov
|
||||
*/
|
||||
public class FeignClientBuilderTests {
|
||||
|
||||
@@ -58,6 +60,14 @@ public class FeignClientBuilderTests {
|
||||
|
||||
private static void assertFactoryBeanField(final FeignClientBuilder.Builder builder,
|
||||
final String fieldName, final Object expectedValue) {
|
||||
final Object value = getFactoryBeanField(builder, fieldName);
|
||||
assertThat(value).as("Expected value for the field '" + fieldName + "':")
|
||||
.isEqualTo(expectedValue);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T getFactoryBeanField(final FeignClientBuilder.Builder builder,
|
||||
final String fieldName) {
|
||||
final Field factoryBeanField = ReflectionUtils
|
||||
.findField(FeignClientBuilder.Builder.class, "feignClientFactoryBean");
|
||||
ReflectionUtils.makeAccessible(factoryBeanField);
|
||||
@@ -67,9 +77,7 @@ public class FeignClientBuilderTests {
|
||||
final Field field = ReflectionUtils.findField(FeignClientFactoryBean.class,
|
||||
fieldName);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
final Object value = ReflectionUtils.getField(field, factoryBean);
|
||||
assertThat(value).as("Expected value for the field '" + fieldName + "':")
|
||||
.isEqualTo(expectedValue);
|
||||
return (T) ReflectionUtils.getField(field, factoryBean);
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -131,7 +139,8 @@ public class FeignClientBuilderTests {
|
||||
.forType(TestFeignClient.class, "TestClient").inheritParentContext(false)
|
||||
.fallback(TestFeignClientFallback.class)
|
||||
.fallbackFactory(TestFeignClientFallbackFactory.class).decode404(true)
|
||||
.url("Url/").path("/Path").contextId("TestContext");
|
||||
.url("Url/").path("/Path").contextId("TestContext")
|
||||
.customize(Feign.Builder::doNotCloseAfterDecode);
|
||||
|
||||
// then:
|
||||
assertFactoryBeanField(builder, "applicationContext", this.applicationContext);
|
||||
@@ -147,14 +156,21 @@ public class FeignClientBuilderTests {
|
||||
assertFactoryBeanField(builder, "fallback", TestFeignClientFallback.class);
|
||||
assertFactoryBeanField(builder, "fallbackFactory",
|
||||
TestFeignClientFallbackFactory.class);
|
||||
List<FeignBuilderCustomizer> additionalCustomizers = getFactoryBeanField(builder,
|
||||
"additionalCustomizers");
|
||||
assertThat(additionalCustomizers).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forType_build() {
|
||||
// given:
|
||||
Mockito.when(this.applicationContext.getBean(FeignContext.class))
|
||||
.thenThrow(new ClosedFileSystemException()); // throw an unusual exception
|
||||
// in the
|
||||
.thenThrow(new ClosedFileSystemException()); // throw
|
||||
// an
|
||||
// unusual
|
||||
// exception
|
||||
// in
|
||||
// the
|
||||
// FeignClientFactoryBean
|
||||
final FeignClientBuilder.Builder builder = this.feignClientBuilder
|
||||
.forType(TestClient.class, "TestClient");
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
<parent>
|
||||
<artifactId>spring-cloud-dependencies-parent</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<version>2.3.3.BUILD-SNAPSHOT</version>
|
||||
<version>2.3.4.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
|
||||
<version>2.2.8.BUILD-SNAPSHOT</version>
|
||||
<version>2.2.8.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>spring-cloud-openfeign-dependencies</name>
|
||||
<description>Spring Cloud OpenFeign Dependencies</description>
|
||||
<properties>
|
||||
<feign.version>10.10.1</feign.version>
|
||||
<feign.version>10.12</feign.version>
|
||||
<feign-form.version>3.8.0</feign-form.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.2.8.BUILD-SNAPSHOT</version>
|
||||
<version>2.2.8.RELEASE</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user