Compare commits
18
Commits
v2.0.0.M1
...
v2.0.0.RC2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21be1e129c | ||
|
|
18111801d3 | ||
|
|
e27d4d38e5 | ||
|
|
01a2cda776 | ||
|
|
9ac36c7f3f | ||
|
|
f4fc531857 | ||
|
|
596b42291f | ||
|
|
17fa94f704 | ||
|
|
baf92c8226 | ||
|
|
30b05c7361 | ||
|
|
042244428f | ||
|
|
485583dad8 | ||
|
|
c45f1532da | ||
|
|
537599fad2 | ||
|
|
d4e95cd777 | ||
|
|
1fa53b8bf9 | ||
|
|
2d7909a8ec | ||
|
|
d68016149d |
@@ -9,15 +9,15 @@ follow the guidelines below.
|
||||
|
||||
## Sign the Contributor License Agreement
|
||||
Before we accept a non-trivial patch or pull request we will need you to sign the
|
||||
https://cla.pivotal.io/sign/spring[Contributor License Agreement].
|
||||
[Contributor License Agreement](https://cla.pivotal.io/sign/spring).
|
||||
Signing the contributor's agreement does not grant anyone commit rights to the main
|
||||
repository, but it does mean that we can accept your contributions, and you will get an
|
||||
author credit if we do. Active contributors might be asked to join the core team, and
|
||||
given the ability to merge pull requests.
|
||||
|
||||
## Code of Conduct
|
||||
This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of
|
||||
conduct]. By participating, you are expected to uphold this code. Please report
|
||||
This project adheres to the Contributor Covenant [code of
|
||||
conduct](https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
|
||||
unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
## Code Conventions and Housekeeping
|
||||
@@ -27,10 +27,8 @@ added after the original pull request but before a merge.
|
||||
* Use the Spring Framework code format conventions. If you use Eclipse
|
||||
you can import formatter settings using the
|
||||
`eclipse-code-formatter.xml` file from the
|
||||
https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring
|
||||
Cloud Build] project. If using IntelliJ, you can use the
|
||||
http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
|
||||
Plugin] to import the same file.
|
||||
[Spring Cloud Build](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml) project. If using IntelliJ, you can use the
|
||||
[Eclipse Code Formatter Plugin](http://plugins.jetbrains.com/plugin/6546) to import the same file.
|
||||
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
|
||||
`@author` tag identifying you, and preferably at least a paragraph on what the class is
|
||||
for.
|
||||
@@ -42,6 +40,6 @@ added after the original pull request but before a merge.
|
||||
* A few unit tests would help a lot as well -- someone has to do it.
|
||||
* If no-one else is using your branch, please rebase it against the current master (or
|
||||
other target branch in the main project).
|
||||
* When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
|
||||
* When writing a commit message please follow [these conventions](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
|
||||
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
|
||||
message (where XXXX is the issue number).
|
||||
message (where XXXX is the issue number).
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
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://codecov.io/gh/spring-cloud/spring-cloud-openfeign/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-openfeign"]
|
||||
|
||||
image:https://api.codacy.com/project/badge/Grade/97b04c4e609c4b4f86b415e4437a6484["Codacy code quality", link="https://www.codacy.com/app/Spring-Cloud/spring-cloud-openfeign?utm_source=github.com&utm_medium=referral&utm_content=spring-cloud/spring-cloud-openfeign&utm_campaign=Badge_Grade"]
|
||||
|
||||
This project provides OpenFeign integrations for Spring Boot apps through autoconfiguration
|
||||
and binding to the Spring Environment and other Spring programming model idioms.
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
comment:
|
||||
layout: "reach, diff, flags, files"
|
||||
behavior: default
|
||||
require_changes: false # if true: only post the comment if coverage changes
|
||||
require_base: no # [yes :: must have a base report to post]
|
||||
require_head: yes # [yes :: must have a head report to post]
|
||||
branches: null
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.0.0.M1</version>
|
||||
<version>2.0.0.RC2</version>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-openfeign-docs</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
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://codecov.io/gh/spring-cloud/spring-cloud-openfeign/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-openfeign"]
|
||||
|
||||
image:https://api.codacy.com/project/badge/Grade/97b04c4e609c4b4f86b415e4437a6484["Codacy code quality", link="https://www.codacy.com/app/Spring-Cloud/spring-cloud-openfeign?utm_source=github.com&utm_medium=referral&utm_content=spring-cloud/spring-cloud-openfeign&utm_campaign=Badge_Grade"]
|
||||
|
||||
include::intro.adoc[]
|
||||
|
||||
== Features
|
||||
|
||||
@@ -112,7 +112,7 @@ Spring Cloud Netflix provides the following beans by default for feign (`BeanTyp
|
||||
* `Client` feignClient: if Ribbon is enabled it is a `LoadBalancerFeignClient`, otherwise the default feign client is used.
|
||||
|
||||
The OkHttpClient and ApacheHttpClient feign clients can be used by setting `feign.okhttp.enabled` or `feign.httpclient.enabled` to `true`, respectively, and having them on the classpath.
|
||||
You can customize the HTTP client used by providing a bean of either `ClosableHttpClient` when using Apache or `OkHttpClient` whe using OK HTTP.
|
||||
You can customize the HTTP client used by providing a bean of either `ClosableHttpClient` when using Apache or `OkHttpClient` when using OK HTTP.
|
||||
|
||||
Spring Cloud Netflix _does not_ provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client:
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.0.0.M1</version>
|
||||
<version>2.0.0.RC2</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.0.0.RC1</version>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<scm>
|
||||
@@ -22,8 +22,8 @@
|
||||
<properties>
|
||||
<main.basedir>${basedir}</main.basedir>
|
||||
<jackson.version>2.7.3</jackson.version>
|
||||
<spring-cloud-commons.version>2.0.0.M7</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.0.0.M7</spring-cloud-netflix.version>
|
||||
<spring-cloud-commons.version>2.0.0.RC2</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.0.0.RC2</spring-cloud-netflix.version>
|
||||
|
||||
<!-- Plugin versions -->
|
||||
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.0.0.M1</version>
|
||||
<version>2.0.0.RC2</version>
|
||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>spring-cloud-openfeign-core</artifactId>
|
||||
@@ -188,6 +188,18 @@
|
||||
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.protobuf-java-format</groupId>
|
||||
<artifactId>protobuf-java-format</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@ package org.springframework.cloud.openfeign.encoding;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -43,7 +42,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@ConditionalOnProperty(value = "feign.compression.response.enabled", matchIfMissing = false)
|
||||
//The OK HTTP client uses "transparent" compression.
|
||||
//If the accept-encoding header is present it disable transparent compression
|
||||
@ConditionalOnMissingBean(OkHttpClient.class)
|
||||
@ConditionalOnMissingBean(type = "okhttp3.OkHttpClient")
|
||||
@AutoConfigureAfter(FeignAutoConfiguration.class)
|
||||
public class FeignAcceptGzipEncodingAutoConfiguration {
|
||||
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@ package org.springframework.cloud.openfeign.encoding;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -42,7 +41,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@ConditionalOnBean(Client.class)
|
||||
//The OK HTTP client uses "transparent" compression.
|
||||
//If the content-encoding header is present it disable transparent compression
|
||||
@ConditionalOnMissingBean(OkHttpClient.class)
|
||||
@ConditionalOnMissingBean(type = "okhttp3.OkHttpClient")
|
||||
@ConditionalOnProperty(value = "feign.compression.request.enabled", matchIfMissing = false)
|
||||
@AutoConfigureAfter(FeignAutoConfiguration.class)
|
||||
public class FeignContentGzipEncodingAutoConfiguration {
|
||||
|
||||
+9
-55
@@ -18,10 +18,7 @@ package org.springframework.cloud.openfeign.ribbon;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
@@ -40,72 +37,29 @@ import com.netflix.loadbalancer.ILoadBalancer;
|
||||
public class CachingSpringLoadBalancerFactory {
|
||||
|
||||
private final SpringClientFactory factory;
|
||||
private final LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory;
|
||||
private final LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory;
|
||||
private final LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory;
|
||||
private boolean enableRetry = false;
|
||||
private LoadBalancedRetryFactory loadBalancedRetryFactory = null;
|
||||
|
||||
private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap<>();
|
||||
|
||||
public CachingSpringLoadBalancerFactory(SpringClientFactory factory) {
|
||||
this.factory = factory;
|
||||
this.loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(factory);
|
||||
this.loadBalancedBackOffPolicyFactory = null;
|
||||
this.loadBalancedRetryListenerFactory = null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
//TODO remove in 2.0.x
|
||||
public CachingSpringLoadBalancerFactory(SpringClientFactory factory,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
public CachingSpringLoadBalancerFactory(SpringClientFactory factory, LoadBalancedRetryFactory loadBalancedRetryPolicyFactory) {
|
||||
this.factory = factory;
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
this.loadBalancedBackOffPolicyFactory = null;
|
||||
this.loadBalancedRetryListenerFactory = null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
//TODO remove in 2.0.0x
|
||||
public CachingSpringLoadBalancerFactory(SpringClientFactory factory,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, boolean enableRetry) {
|
||||
this.factory = factory;
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
this.enableRetry = enableRetry;
|
||||
this.loadBalancedBackOffPolicyFactory = null;
|
||||
this.loadBalancedRetryListenerFactory = null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
//TODO remove in 2.0.0x
|
||||
public CachingSpringLoadBalancerFactory(SpringClientFactory factory,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
|
||||
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory) {
|
||||
this.factory = factory;
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory;
|
||||
this.loadBalancedRetryListenerFactory = null;
|
||||
this.enableRetry = true;
|
||||
}
|
||||
|
||||
public CachingSpringLoadBalancerFactory(SpringClientFactory factory, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
|
||||
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory,
|
||||
LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) {
|
||||
this.factory = factory;
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory;
|
||||
this.loadBalancedRetryListenerFactory = loadBalancedRetryListenerFactory;
|
||||
this.enableRetry = true;
|
||||
this.loadBalancedRetryFactory = loadBalancedRetryPolicyFactory;
|
||||
}
|
||||
|
||||
public FeignLoadBalancer create(String clientName) {
|
||||
if (this.cache.containsKey(clientName)) {
|
||||
return this.cache.get(clientName);
|
||||
FeignLoadBalancer client = this.cache.get(clientName);
|
||||
if(client != null) {
|
||||
return client;
|
||||
}
|
||||
IClientConfig config = this.factory.getClientConfig(clientName);
|
||||
ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
|
||||
ServerIntrospector serverIntrospector = this.factory.getInstance(clientName, ServerIntrospector.class);
|
||||
FeignLoadBalancer client = enableRetry ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
|
||||
loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory) : new FeignLoadBalancer(lb, config, serverIntrospector);
|
||||
client = loadBalancedRetryFactory != null ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
|
||||
loadBalancedRetryFactory) : new FeignLoadBalancer(lb, config, serverIntrospector);
|
||||
this.cache.put(clientName, client);
|
||||
return client;
|
||||
}
|
||||
|
||||
+3
-7
@@ -21,9 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
|
||||
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.support.FeignHttpClientProperties;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
@@ -67,10 +65,8 @@ public class FeignRibbonClientAutoConfiguration {
|
||||
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
|
||||
public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory(
|
||||
SpringClientFactory factory,
|
||||
LoadBalancedRetryPolicyFactory retryPolicyFactory,
|
||||
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory,
|
||||
LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) {
|
||||
return new CachingSpringLoadBalancerFactory(factory, retryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory);
|
||||
LoadBalancedRetryFactory retryFactory) {
|
||||
return new CachingSpringLoadBalancerFactory(factory, retryFactory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
+10
-44
@@ -24,12 +24,10 @@ import feign.Response;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRecoveryCallback;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.RibbonRecoveryCallback;
|
||||
import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonProperties;
|
||||
@@ -55,45 +53,13 @@ import com.netflix.loadbalancer.Server;
|
||||
*/
|
||||
public class RetryableFeignLoadBalancer extends FeignLoadBalancer implements ServiceInstanceChooser {
|
||||
|
||||
private final LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory;
|
||||
private final LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory;
|
||||
private final LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory;
|
||||
|
||||
@Deprecated
|
||||
//TODO remove in 2.0.x
|
||||
public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,
|
||||
ServerIntrospector serverIntrospector, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
|
||||
super(lb, clientConfig, serverIntrospector);
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig));
|
||||
this.loadBalancedBackOffPolicyFactory = new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory();
|
||||
this.loadBalancedRetryListenerFactory = new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
//TODO remove in 2.0.x
|
||||
public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,
|
||||
ServerIntrospector serverIntrospector, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
|
||||
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory) {
|
||||
super(lb, clientConfig, serverIntrospector);
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig));
|
||||
this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory == null ?
|
||||
new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory() : loadBalancedBackOffPolicyFactory;
|
||||
this.loadBalancedRetryListenerFactory = new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory();
|
||||
}
|
||||
private final LoadBalancedRetryFactory loadBalancedRetryFactory;
|
||||
|
||||
public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, ServerIntrospector serverIntrospector,
|
||||
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
|
||||
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory,
|
||||
LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) {
|
||||
LoadBalancedRetryFactory loadBalancedRetryFactory) {
|
||||
super(lb, clientConfig, serverIntrospector);
|
||||
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
|
||||
this.loadBalancedRetryFactory = loadBalancedRetryFactory;
|
||||
this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig));
|
||||
this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory == null ?
|
||||
new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory() : loadBalancedBackOffPolicyFactory;
|
||||
this.loadBalancedRetryListenerFactory = loadBalancedRetryListenerFactory == null ?
|
||||
new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory() : loadBalancedRetryListenerFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,11 +75,11 @@ public class RetryableFeignLoadBalancer extends FeignLoadBalancer implements Ser
|
||||
else {
|
||||
options = new Request.Options(this.connectTimeout, this.readTimeout);
|
||||
}
|
||||
final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryPolicyFactory.create(this.getClientName(), this);
|
||||
final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryFactory.createRetryPolicy(this.getClientName(), this);
|
||||
RetryTemplate retryTemplate = new RetryTemplate();
|
||||
BackOffPolicy backOffPolicy = loadBalancedBackOffPolicyFactory.createBackOffPolicy(this.getClientName());
|
||||
BackOffPolicy backOffPolicy = loadBalancedRetryFactory.createBackOffPolicy(this.getClientName());
|
||||
retryTemplate.setBackOffPolicy(backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy);
|
||||
RetryListener[] retryListeners = this.loadBalancedRetryListenerFactory.createRetryListeners(this.getClientName());
|
||||
RetryListener[] retryListeners = this.loadBalancedRetryFactory.createRetryListeners(this.getClientName());
|
||||
if (retryListeners != null && retryListeners.length != 0) {
|
||||
retryTemplate.setListeners(retryListeners);
|
||||
}
|
||||
@@ -136,14 +102,14 @@ public class RetryableFeignLoadBalancer extends FeignLoadBalancer implements Ser
|
||||
}
|
||||
Response response = request.client().execute(feignRequest, options);
|
||||
if (retryPolicy.retryableStatusCode(response.status())) {
|
||||
byte[] byteArray = StreamUtils.copyToByteArray(response.body().asInputStream());
|
||||
byte[] byteArray = response.body() == null ? new byte[]{} : StreamUtils.copyToByteArray(response.body().asInputStream());
|
||||
response.close();
|
||||
throw new RibbonResponseStatusCodeException(RetryableFeignLoadBalancer.this.clientName, response,
|
||||
byteArray, request.getUri());
|
||||
}
|
||||
return new RibbonResponse(request.getUri(), response);
|
||||
}
|
||||
}, new RibbonRecoveryCallback<RibbonResponse, Response>() {
|
||||
}, new LoadBalancedRecoveryCallback<RibbonResponse, Response>() {
|
||||
@Override
|
||||
protected RibbonResponse createResponse(Response response, URI uri) {
|
||||
return new RibbonResponse(uri, response);
|
||||
|
||||
+11
-3
@@ -22,6 +22,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -33,6 +34,7 @@ import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
@@ -43,6 +45,7 @@ import static org.springframework.cloud.openfeign.support.FeignUtils.getHttpHead
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author ScienJus
|
||||
*/
|
||||
public class SpringEncoder implements Encoder {
|
||||
|
||||
@@ -99,12 +102,17 @@ public class SpringEncoder implements Encoder {
|
||||
// with the modified headers
|
||||
request.headers(getHeaders(outputMessage.getHeaders()));
|
||||
|
||||
// do not use charset for binary data
|
||||
// do not use charset for binary data and protobuf
|
||||
Charset charset;
|
||||
if (messageConverter instanceof ByteArrayHttpMessageConverter) {
|
||||
request.body(outputMessage.getOutputStream().toByteArray(), null);
|
||||
charset = null;
|
||||
} else if (messageConverter instanceof ProtobufHttpMessageConverter &&
|
||||
ProtobufHttpMessageConverter.PROTOBUF.isCompatibleWith(outputMessage.getHeaders().getContentType())) {
|
||||
charset = null;
|
||||
} else {
|
||||
request.body(outputMessage.getOutputStream().toByteArray(), Charset.forName("UTF-8"));
|
||||
charset = StandardCharsets.UTF_8;
|
||||
}
|
||||
request.body(outputMessage.getOutputStream().toByteArray(), charset);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.openfeign.encoding.proto;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||
import org.springframework.cloud.test.ClassPathExclusions;
|
||||
import org.springframework.cloud.test.ModifiedClassPathRunner;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
|
||||
/**
|
||||
* Test {@link SpringEncoder} when protobuf is not in classpath
|
||||
*
|
||||
* @author ScienJus
|
||||
*/
|
||||
@RunWith(ModifiedClassPathRunner.class)
|
||||
@ClassPathExclusions("protobuf-*.jar")
|
||||
public class ProtobufNotInClasspathTest {
|
||||
|
||||
@Test
|
||||
public void testEncodeWhenProtobufNotInClasspath() {
|
||||
ObjectFactory<HttpMessageConverters> converters = new ObjectFactory<HttpMessageConverters>() {
|
||||
@Override
|
||||
public HttpMessageConverters getObject() throws BeansException {
|
||||
return new HttpMessageConverters(new StringHttpMessageConverter());
|
||||
}
|
||||
};
|
||||
RequestTemplate requestTemplate = new RequestTemplate();
|
||||
requestTemplate.method("POST");
|
||||
new SpringEncoder(converters).encode("a=b", String.class, requestTemplate);
|
||||
}
|
||||
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.openfeign.encoding.proto;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import feign.RequestTemplate;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.BDDMockito;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.cloud.openfeign.support.SpringEncoder;
|
||||
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test {@link SpringEncoder} with {@link ProtobufHttpMessageConverter}
|
||||
*
|
||||
* @author ScienJus
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ProtobufSpringEncoderTest {
|
||||
|
||||
@Mock
|
||||
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.newBuilder()
|
||||
.setId(1000000)
|
||||
.setMsg("Erlang/OTP 最初是爱立信为开发电信设备系统设计的编程语言平台," +
|
||||
"电信设备(路由器、接入网关、…)典型设计是通过背板连接主控板卡与多块业务板卡的分布式系统。")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void testProtobuf() throws IOException, URISyntaxException {
|
||||
// protobuf convert to request by feign and ProtobufHttpMessageConverter
|
||||
RequestTemplate requestTemplate = newRequestTemplate();
|
||||
newEncoder().encode(request, Request.class, requestTemplate);
|
||||
HttpEntity entity = toApacheHttpEntity(requestTemplate);
|
||||
byte[] bytes = read(entity.getContent(), (int) entity.getContentLength());
|
||||
|
||||
Assert.assertArrayEquals(bytes, request.toByteArray());
|
||||
org.springframework.cloud.openfeign.encoding.proto.Request copy = org.springframework.cloud.openfeign.encoding.proto.Request.parseFrom(bytes);
|
||||
Assert.assertEquals(request, copy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProtobufWithCharsetWillFail() throws IOException, URISyntaxException {
|
||||
// protobuf convert to request by feign and ProtobufHttpMessageConverter
|
||||
RequestTemplate requestTemplate = newRequestTemplate();
|
||||
newEncoder().encode(request, Request.class, requestTemplate);
|
||||
// set a charset
|
||||
requestTemplate.body(requestTemplate.body(), StandardCharsets.UTF_8);
|
||||
HttpEntity entity = toApacheHttpEntity(requestTemplate);
|
||||
byte[] bytes = read(entity.getContent(), (int) entity.getContentLength());
|
||||
|
||||
// http request-body is different with original protobuf body
|
||||
Assert.assertNotEquals(bytes.length, request.toByteArray().length);
|
||||
try {
|
||||
org.springframework.cloud.openfeign.encoding.proto.Request copy = org.springframework.cloud.openfeign.encoding.proto.Request.parseFrom(bytes);
|
||||
Assert.fail("Expected an InvalidProtocolBufferException to be thrown");
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
|
||||
private SpringEncoder newEncoder() {
|
||||
ObjectFactory<HttpMessageConverters> converters = new ObjectFactory<HttpMessageConverters>() {
|
||||
@Override
|
||||
public HttpMessageConverters getObject() throws BeansException {
|
||||
return new HttpMessageConverters(new ProtobufHttpMessageConverter());
|
||||
}
|
||||
};
|
||||
return new SpringEncoder(converters);
|
||||
}
|
||||
|
||||
private RequestTemplate newRequestTemplate() {
|
||||
RequestTemplate requestTemplate = new RequestTemplate();
|
||||
requestTemplate.method("POST");
|
||||
return requestTemplate;
|
||||
}
|
||||
|
||||
private HttpEntity toApacheHttpEntity(RequestTemplate requestTemplate) throws IOException, URISyntaxException {
|
||||
final List<HttpUriRequest> request = new ArrayList<>(1);
|
||||
BDDMockito.given(httpClient.execute(Matchers.<HttpUriRequest>any())).will(new Answer<HttpResponse>() {
|
||||
@Override
|
||||
public HttpResponse answer(InvocationOnMock invocationOnMock) throws Throwable {
|
||||
request.add((HttpUriRequest) invocationOnMock.getArguments()[0]);
|
||||
return new BasicHttpResponse(new BasicStatusLine(new ProtocolVersion("http", 1, 1), 200, null));
|
||||
}
|
||||
});
|
||||
new ApacheHttpClient(httpClient).execute(requestTemplate.request(), new feign.Request.Options());
|
||||
HttpUriRequest httpUriRequest = request.get(0);
|
||||
return ((HttpEntityEnclosingRequestBase)httpUriRequest).getEntity();
|
||||
}
|
||||
|
||||
private byte[] read(InputStream in, int length) throws IOException {
|
||||
byte[] bytes = new byte[length];
|
||||
in.read(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
*/
|
||||
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: protobuf_test.proto
|
||||
|
||||
package org.springframework.cloud.openfeign.encoding.proto;
|
||||
|
||||
public final class ProtobufTest {
|
||||
private ProtobufTest() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||
}
|
||||
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
registerAllExtensions(
|
||||
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||
}
|
||||
static final com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_Request_descriptor;
|
||||
static final
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||
internal_static_Request_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
String[] descriptorData = {
|
||||
"\n\023protobuf_test.proto\"\"\n\007Request\022\n\n\002id\030\001" +
|
||||
" \001(\005\022\013\n\003msg\030\002 \001(\tB\024\n\020feign.httpclientP\001b" +
|
||||
"\006proto3"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
|
||||
public com.google.protobuf.ExtensionRegistry assignDescriptors(
|
||||
com.google.protobuf.Descriptors.FileDescriptor root) {
|
||||
descriptor = root;
|
||||
return null;
|
||||
}
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
}, assigner);
|
||||
internal_static_Request_descriptor =
|
||||
getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_Request_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||
internal_static_Request_descriptor,
|
||||
new String[] { "Id", "Msg", });
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
||||
+587
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
*/
|
||||
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: protobuf_test.proto
|
||||
|
||||
package org.springframework.cloud.openfeign.encoding.proto;
|
||||
|
||||
/**
|
||||
* Protobuf type {@code Request}
|
||||
*/
|
||||
public final class Request extends
|
||||
com.google.protobuf.GeneratedMessageV3 implements
|
||||
// @@protoc_insertion_point(message_implements:Request)
|
||||
org.springframework.cloud.openfeign.encoding.proto.RequestOrBuilder {
|
||||
private static final long serialVersionUID = 0L;
|
||||
// Use Request.newBuilder() to construct.
|
||||
private Request(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
|
||||
super(builder);
|
||||
}
|
||||
private Request() {
|
||||
id_ = 0;
|
||||
msg_ = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public final com.google.protobuf.UnknownFieldSet
|
||||
getUnknownFields() {
|
||||
return this.unknownFields;
|
||||
}
|
||||
private Request(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
this();
|
||||
int mutable_bitField0_ = 0;
|
||||
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||
try {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int tag = input.readTag();
|
||||
switch (tag) {
|
||||
case 0:
|
||||
done = true;
|
||||
break;
|
||||
default: {
|
||||
if (!parseUnknownFieldProto3(
|
||||
input, unknownFields, extensionRegistry, tag)) {
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
|
||||
id_ = input.readInt32();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
String s = input.readStringRequireUtf8();
|
||||
|
||||
msg_ = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(this);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||
e).setUnfinishedMessage(this);
|
||||
} finally {
|
||||
this.unknownFields = unknownFields.build();
|
||||
makeExtensionsImmutable();
|
||||
}
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.springframework.cloud.openfeign.encoding.proto.ProtobufTest.internal_static_Request_descriptor;
|
||||
}
|
||||
|
||||
protected FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.springframework.cloud.openfeign.encoding.proto.ProtobufTest.internal_static_Request_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
Request.class, Request.Builder.class);
|
||||
}
|
||||
|
||||
public static final int ID_FIELD_NUMBER = 1;
|
||||
private int id_;
|
||||
/**
|
||||
* <code>int32 id = 1;</code>
|
||||
*/
|
||||
public int getId() {
|
||||
return id_;
|
||||
}
|
||||
|
||||
public static final int MSG_FIELD_NUMBER = 2;
|
||||
private volatile Object msg_;
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
public String getMsg() {
|
||||
Object ref = msg_;
|
||||
if (ref instanceof String) {
|
||||
return (String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
msg_ = s;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getMsgBytes() {
|
||||
Object ref = msg_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(String) ref);
|
||||
msg_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
byte isInitialized = memoizedIsInitialized;
|
||||
if (isInitialized == 1) return true;
|
||||
if (isInitialized == 0) return false;
|
||||
|
||||
memoizedIsInitialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
if (id_ != 0) {
|
||||
output.writeInt32(1, id_);
|
||||
}
|
||||
if (!getMsgBytes().isEmpty()) {
|
||||
com.google.protobuf.GeneratedMessageV3.writeString(output, 2, msg_);
|
||||
}
|
||||
unknownFields.writeTo(output);
|
||||
}
|
||||
|
||||
public int getSerializedSize() {
|
||||
int size = memoizedSize;
|
||||
if (size != -1) return size;
|
||||
|
||||
size = 0;
|
||||
if (id_ != 0) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt32Size(1, id_);
|
||||
}
|
||||
if (!getMsgBytes().isEmpty()) {
|
||||
size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, msg_);
|
||||
}
|
||||
size += unknownFields.getSerializedSize();
|
||||
memoizedSize = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Request)) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
Request other = (Request) obj;
|
||||
|
||||
boolean result = true;
|
||||
result = result && (getId()
|
||||
== other.getId());
|
||||
result = result && getMsg()
|
||||
.equals(other.getMsg());
|
||||
result = result && unknownFields.equals(other.unknownFields);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (memoizedHashCode != 0) {
|
||||
return memoizedHashCode;
|
||||
}
|
||||
int hash = 41;
|
||||
hash = (19 * hash) + getDescriptor().hashCode();
|
||||
hash = (37 * hash) + ID_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getId();
|
||||
hash = (37 * hash) + MSG_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getMsg().hashCode();
|
||||
hash = (29 * hash) + unknownFields.hashCode();
|
||||
memoizedHashCode = hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static Request parseFrom(
|
||||
java.nio.ByteBuffer data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static Request parseFrom(
|
||||
java.nio.ByteBuffer data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static Request parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static Request parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static Request parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static Request parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static Request parseFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input);
|
||||
}
|
||||
public static Request parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
public static Request parseDelimitedFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseDelimitedWithIOException(PARSER, input);
|
||||
}
|
||||
public static Request parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
public static Request parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input);
|
||||
}
|
||||
public static Request parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
|
||||
public Builder newBuilderForType() { return newBuilder(); }
|
||||
public static Builder newBuilder() {
|
||||
return DEFAULT_INSTANCE.toBuilder();
|
||||
}
|
||||
public static Builder newBuilder(Request prototype) {
|
||||
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
|
||||
}
|
||||
public Builder toBuilder() {
|
||||
return this == DEFAULT_INSTANCE
|
||||
? new Builder() : new Builder().mergeFrom(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder newBuilderForType(
|
||||
BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code Request}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
|
||||
// @@protoc_insertion_point(builder_implements:Request)
|
||||
org.springframework.cloud.openfeign.encoding.proto.RequestOrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.springframework.cloud.openfeign.encoding.proto.ProtobufTest.internal_static_Request_descriptor;
|
||||
}
|
||||
|
||||
protected FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.springframework.cloud.openfeign.encoding.proto.ProtobufTest.internal_static_Request_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
Request.class, Request.Builder.class);
|
||||
}
|
||||
|
||||
// Construct using org.springframework.cloud.openfeign.encoding.proto.Request.newBuilder()
|
||||
private Builder() {
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
|
||||
private Builder(
|
||||
BuilderParent parent) {
|
||||
super(parent);
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
private void maybeForceBuilderInitialization() {
|
||||
if (com.google.protobuf.GeneratedMessageV3
|
||||
.alwaysUseFieldBuilders) {
|
||||
}
|
||||
}
|
||||
public Builder clear() {
|
||||
super.clear();
|
||||
id_ = 0;
|
||||
|
||||
msg_ = "";
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return org.springframework.cloud.openfeign.encoding.proto.ProtobufTest.internal_static_Request_descriptor;
|
||||
}
|
||||
|
||||
public Request getDefaultInstanceForType() {
|
||||
return Request.getDefaultInstance();
|
||||
}
|
||||
|
||||
public Request build() {
|
||||
Request result = buildPartial();
|
||||
if (!result.isInitialized()) {
|
||||
throw newUninitializedMessageException(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Request buildPartial() {
|
||||
Request result = new Request(this);
|
||||
result.id_ = id_;
|
||||
result.msg_ = msg_;
|
||||
onBuilt();
|
||||
return result;
|
||||
}
|
||||
|
||||
public Builder clone() {
|
||||
return (Builder) super.clone();
|
||||
}
|
||||
public Builder setField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
return (Builder) super.setField(field, value);
|
||||
}
|
||||
public Builder clearField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field) {
|
||||
return (Builder) super.clearField(field);
|
||||
}
|
||||
public Builder clearOneof(
|
||||
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
|
||||
return (Builder) super.clearOneof(oneof);
|
||||
}
|
||||
public Builder setRepeatedField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
int index, Object value) {
|
||||
return (Builder) super.setRepeatedField(field, index, value);
|
||||
}
|
||||
public Builder addRepeatedField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
return (Builder) super.addRepeatedField(field, value);
|
||||
}
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
if (other instanceof Request) {
|
||||
return mergeFrom((Request)other);
|
||||
} else {
|
||||
super.mergeFrom(other);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Builder mergeFrom(Request other) {
|
||||
if (other == Request.getDefaultInstance()) return this;
|
||||
if (other.getId() != 0) {
|
||||
setId(other.getId());
|
||||
}
|
||||
if (!other.getMsg().isEmpty()) {
|
||||
msg_ = other.msg_;
|
||||
onChanged();
|
||||
}
|
||||
this.mergeUnknownFields(other.unknownFields);
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isInitialized() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
Request parsedMessage = null;
|
||||
try {
|
||||
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
parsedMessage = (Request) e.getUnfinishedMessage();
|
||||
throw e.unwrapIOException();
|
||||
} finally {
|
||||
if (parsedMessage != null) {
|
||||
mergeFrom(parsedMessage);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private int id_ ;
|
||||
/**
|
||||
* <code>int32 id = 1;</code>
|
||||
*/
|
||||
public int getId() {
|
||||
return id_;
|
||||
}
|
||||
/**
|
||||
* <code>int32 id = 1;</code>
|
||||
*/
|
||||
public Builder setId(int value) {
|
||||
|
||||
id_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>int32 id = 1;</code>
|
||||
*/
|
||||
public Builder clearId() {
|
||||
|
||||
id_ = 0;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
private Object msg_ = "";
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
public String getMsg() {
|
||||
Object ref = msg_;
|
||||
if (!(ref instanceof String)) {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
msg_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getMsgBytes() {
|
||||
Object ref = msg_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(String) ref);
|
||||
msg_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
public Builder setMsg(
|
||||
String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
msg_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
public Builder clearMsg() {
|
||||
|
||||
msg_ = getDefaultInstance().getMsg();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
public Builder setMsgBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
checkByteStringIsUtf8(value);
|
||||
|
||||
msg_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public final Builder setUnknownFields(
|
||||
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||
return super.setUnknownFieldsProto3(unknownFields);
|
||||
}
|
||||
|
||||
public final Builder mergeUnknownFields(
|
||||
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||
return super.mergeUnknownFields(unknownFields);
|
||||
}
|
||||
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:Request)
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(class_scope:Request)
|
||||
private static final Request DEFAULT_INSTANCE;
|
||||
static {
|
||||
DEFAULT_INSTANCE = new Request();
|
||||
}
|
||||
|
||||
public static Request getDefaultInstance() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
private static final com.google.protobuf.Parser<Request>
|
||||
PARSER = new com.google.protobuf.AbstractParser<Request>() {
|
||||
public Request parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return new Request(input, extensionRegistry);
|
||||
}
|
||||
};
|
||||
|
||||
public static com.google.protobuf.Parser<Request> parser() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Parser<Request> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
public Request getDefaultInstanceForType() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012-2013 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.
|
||||
*/
|
||||
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: protobuf_test.proto
|
||||
|
||||
package org.springframework.cloud.openfeign.encoding.proto;
|
||||
|
||||
public interface RequestOrBuilder extends
|
||||
// @@protoc_insertion_point(interface_extends:Request)
|
||||
com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
/**
|
||||
* <code>int32 id = 1;</code>
|
||||
*/
|
||||
int getId();
|
||||
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
String getMsg();
|
||||
/**
|
||||
* <code>string msg = 2;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getMsgBytes();
|
||||
}
|
||||
+4
-38
@@ -23,9 +23,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -42,13 +40,7 @@ public class CachingSpringLoadBalancerFactoryTests {
|
||||
private SpringClientFactory delegate;
|
||||
|
||||
@Mock
|
||||
private RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory;
|
||||
|
||||
@Mock
|
||||
private LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory;
|
||||
|
||||
@Mock
|
||||
private LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory;
|
||||
private RibbonLoadBalancedRetryFactory loadBalancedRetryFactory;
|
||||
|
||||
private CachingSpringLoadBalancerFactory factory;
|
||||
|
||||
@@ -64,7 +56,7 @@ public class CachingSpringLoadBalancerFactoryTests {
|
||||
when(this.delegate.getClientConfig("client2")).thenReturn(config);
|
||||
|
||||
this.factory = new CachingSpringLoadBalancerFactory(this.delegate,
|
||||
loadBalancedRetryPolicyFactory);
|
||||
loadBalancedRetryFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,34 +95,8 @@ public class CachingSpringLoadBalancerFactoryTests {
|
||||
config.set(CommonClientConfigKey.ConnectTimeout, 1000);
|
||||
config.set(CommonClientConfigKey.ReadTimeout, 500);
|
||||
when(this.delegate.getClientConfig("retry")).thenReturn(config);
|
||||
CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(
|
||||
this.delegate, loadBalancedRetryPolicyFactory, false);
|
||||
CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(this.delegate, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer client = this.factory.create("retry");
|
||||
assertNotNull("client was null", client);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delegateCreatesWithBackOff() {
|
||||
IClientConfig config = new DefaultClientConfigImpl();
|
||||
config.set(CommonClientConfigKey.ConnectTimeout, 1000);
|
||||
config.set(CommonClientConfigKey.ReadTimeout, 500);
|
||||
when(this.delegate.getClientConfig("retry")).thenReturn(config);
|
||||
CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(
|
||||
this.delegate, loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory);
|
||||
FeignLoadBalancer client = this.factory.create("retry");
|
||||
assertNotNull("client was null", client);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delegateCreatesWithRetryListener() {
|
||||
IClientConfig config = new DefaultClientConfigImpl();
|
||||
config.set(CommonClientConfigKey.ConnectTimeout, 1000);
|
||||
config.set(CommonClientConfigKey.ReadTimeout, 500);
|
||||
when(this.delegate.getClientConfig("retry")).thenReturn(config);
|
||||
CachingSpringLoadBalancerFactory factory = new CachingSpringLoadBalancerFactory(
|
||||
this.delegate, loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory);
|
||||
FeignLoadBalancer client = this.factory.create("retry");
|
||||
assertNotNull("client was null", client);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-4
@@ -32,7 +32,6 @@ import org.hamcrest.CustomMatcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
|
||||
@@ -48,7 +47,6 @@ public class FeignRibbonClientTests {
|
||||
|
||||
private AbstractLoadBalancer loadBalancer = mock(AbstractLoadBalancer.class);
|
||||
private Client delegate = mock(Client.class);
|
||||
private RibbonLoadBalancedRetryPolicyFactory retryPolicyFactory = mock(RibbonLoadBalancedRetryPolicyFactory.class);
|
||||
|
||||
private SpringClientFactory factory = new SpringClientFactory() {
|
||||
@Override
|
||||
@@ -77,8 +75,7 @@ public class FeignRibbonClientTests {
|
||||
|
||||
// Even though we don't maintain FeignRibbonClient, keep these tests
|
||||
// around to make sure the expected behaviour doesn't break
|
||||
private Client client = new LoadBalancerFeignClient(this.delegate, new CachingSpringLoadBalancerFactory(this.factory,
|
||||
retryPolicyFactory), this.factory);
|
||||
private Client client = new LoadBalancerFeignClient(this.delegate, new CachingSpringLoadBalancerFactory(this.factory), this.factory);
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
|
||||
+153
-87
@@ -37,14 +37,12 @@ import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser;
|
||||
import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicy;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
@@ -78,6 +76,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
@@ -96,8 +95,6 @@ public class RetryableFeignLoadBalancerTests {
|
||||
@Mock
|
||||
private IClientConfig config;
|
||||
private ServerIntrospector inspector = new DefaultServerIntrospector();
|
||||
private LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory =
|
||||
new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory();
|
||||
|
||||
private Integer defaultConnectTimeout = 10000;
|
||||
private Integer defaultReadTimeout = 10000;
|
||||
@@ -128,7 +125,7 @@ public class RetryableFeignLoadBalancerTests {
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404,502,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory);
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://foo", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
@@ -136,8 +133,7 @@ public class RetryableFeignLoadBalancerTests {
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().status(200).headers(new HashMap<String, Collection<String>>()).build();
|
||||
doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory,
|
||||
loadBalancedBackOffPolicyFactory);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
verify(client, times(1)).execute(any(Request.class), any(Request.Options.class));
|
||||
@@ -151,12 +147,22 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
doThrow(new IOException("boom")).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, new LoadBalancedRetryPolicyFactory() {
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, new LoadBalancedRetryFactory() {
|
||||
@Override
|
||||
public LoadBalancedRetryPolicy create(String s, ServiceInstanceChooser serviceInstanceChooser) {
|
||||
public LoadBalancedRetryPolicy createRetryPolicy(String s, ServiceInstanceChooser serviceInstanceChooser) {
|
||||
return null;
|
||||
}
|
||||
}, loadBalancedBackOffPolicyFactory);
|
||||
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
try {
|
||||
feignLb.execute(request, null);
|
||||
} catch(Exception e) {
|
||||
@@ -179,7 +185,13 @@ public class RetryableFeignLoadBalancerTests {
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://foo", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
@@ -187,13 +199,12 @@ public class RetryableFeignLoadBalancerTests {
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().status(200).headers(new HashMap<String, Collection<String>>()).build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory();
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory,
|
||||
backOffPolicyFactory);
|
||||
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicyFactory.getCount());
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -209,7 +220,13 @@ public class RetryableFeignLoadBalancerTests {
|
||||
doReturn("404").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://foo", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
@@ -218,13 +235,51 @@ public class RetryableFeignLoadBalancerTests {
|
||||
Response response = Response.builder().status(200).headers(new HashMap<String, Collection<String>>()).build();
|
||||
Response fourOFourResponse = Response.builder().status(404).headers(new HashMap<String, Collection<String>>()).build();
|
||||
doReturn(fourOFourResponse).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory();
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory,
|
||||
backOffPolicyFactory);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicyFactory.getCount());
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executeRetryOnStatusCodeWithEmptyBody() throws Exception {
|
||||
int retriesNextServer = 0;
|
||||
when(this.config.get(MaxAutoRetriesNextServer,
|
||||
DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER)).thenReturn(retriesNextServer);
|
||||
doReturn(new Server("foo", 80)).when(lb).chooseServer(anyObject());
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
IClientConfig config = mock(IClientConfig.class);
|
||||
doReturn(1).when(config).get(eq(CommonClientConfigKey.MaxAutoRetries), anyInt());
|
||||
doReturn(retriesNextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt());
|
||||
doReturn(true).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false));
|
||||
doReturn(defaultConnectTimeout).when(config).get(eq(CommonClientConfigKey.ConnectTimeout));
|
||||
doReturn(defaultReadTimeout).when(config).get(eq(CommonClientConfigKey.ReadTimeout));
|
||||
doReturn("404").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://foo", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().status(404).headers(new HashMap<String, Collection<String>>()).build();
|
||||
Response fourOFourResponse = Response.builder().status(404).headers(new HashMap<String, Collection<String>>()).build();
|
||||
doReturn(fourOFourResponse).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(404, ribbonResponse.toResponse().status());
|
||||
assertEquals(new Integer(0), ribbonResponse.toResponse().body().length());
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -232,7 +287,7 @@ public class RetryableFeignLoadBalancerTests {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory);
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://foo", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
@@ -240,8 +295,7 @@ public class RetryableFeignLoadBalancerTests {
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://foo"));
|
||||
Response response = Response.builder().status(200).headers(new HashMap<String, Collection<String>>()).build();
|
||||
doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory,
|
||||
loadBalancedBackOffPolicyFactory);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
RequestSpecificRetryHandler retryHandler = feignLb.getRequestSpecificRetryHandler(request, config);
|
||||
assertEquals(1, retryHandler.getMaxRetriesOnNextServer());
|
||||
assertEquals(1, retryHandler.getMaxRetriesOnSameServer());
|
||||
@@ -253,7 +307,7 @@ public class RetryableFeignLoadBalancerTests {
|
||||
RibbonLoadBalancerContext lbContext = new RibbonLoadBalancerContext(lb, config);
|
||||
SpringClientFactory clientFactory = mock(SpringClientFactory.class);
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory);
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://foo", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
@@ -292,7 +346,7 @@ public class RetryableFeignLoadBalancerTests {
|
||||
public List<Server> getAllServers() {
|
||||
return null;
|
||||
}
|
||||
}, config, inspector, loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory);
|
||||
}, config, inspector, loadBalancedRetryFactory);
|
||||
ServiceInstance serviceInstance = feignLb.choose("foo");
|
||||
assertEquals("foo", serviceInstance.getHost());
|
||||
assertEquals(80, serviceInstance.getPort());
|
||||
@@ -312,7 +366,19 @@ public class RetryableFeignLoadBalancerTests {
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
MyRetryListener myRetryListener = new MyRetryListener();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory) {
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[]{myRetryListener};
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://listener", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
@@ -320,15 +386,13 @@ public class RetryableFeignLoadBalancerTests {
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener"));
|
||||
Response response = Response.builder().status(200).headers(new HashMap<String, Collection<String>>()).build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory();
|
||||
MyRetryListeners myRetryListeners = new MyRetryListeners();
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory,
|
||||
backOffPolicyFactory, myRetryListeners);
|
||||
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicyFactory.getCount());
|
||||
assertEquals(1, myRetryListeners.getOnError());
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
assertEquals(1, myRetryListener.getOnError());
|
||||
}
|
||||
|
||||
@Test(expected = TerminatedRetryException.class)
|
||||
@@ -344,17 +408,26 @@ public class RetryableFeignLoadBalancerTests {
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
Response response = Response.builder().status(200).headers(new HashMap<String, Collection<String>>()).build();
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
MyRetryListenerNotRetry myRetryListenerNotRetry = new MyRetryListenerNotRetry();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[]{myRetryListenerNotRetry};
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://listener", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
Client client = mock(Client.class);
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener"));
|
||||
Response response = Response.builder().status(200).headers(new HashMap<String, Collection<String>>()).build();
|
||||
MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory();
|
||||
MyRetryListenersNotRetry myRetryListenersNotRetry = new MyRetryListenersNotRetry();
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory,
|
||||
backOffPolicyFactory, myRetryListenersNotRetry);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
}
|
||||
|
||||
@@ -371,7 +444,13 @@ public class RetryableFeignLoadBalancerTests {
|
||||
doReturn("").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://listener", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
@@ -379,13 +458,11 @@ public class RetryableFeignLoadBalancerTests {
|
||||
FeignLoadBalancer.RibbonRequest request = new FeignLoadBalancer.RibbonRequest(client, feignRequest, new URI("http://listener"));
|
||||
Response response = Response.builder().status(200).headers(new HashMap<String, Collection<String>>()).build();
|
||||
doThrow(new IOException("boom")).doReturn(response).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory();
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory,
|
||||
backOffPolicyFactory);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
assertEquals(200, ribbonResponse.toResponse().status());
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicyFactory.getCount());
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -402,7 +479,13 @@ public class RetryableFeignLoadBalancerTests {
|
||||
doReturn("404").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES), eq(""));
|
||||
doReturn(config).when(clientFactory).getClientConfig(eq("default"));
|
||||
doReturn(lbContext).when(clientFactory).getLoadBalancerContext(any(String.class));
|
||||
RibbonLoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
|
||||
MyBackOffPolicy backOffPolicy = new MyBackOffPolicy();
|
||||
RibbonLoadBalancedRetryFactory loadBalancedRetryFactory = new RibbonLoadBalancedRetryFactory(clientFactory){
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return backOffPolicy;
|
||||
}
|
||||
};
|
||||
HttpRequest springRequest = mock(HttpRequest.class);
|
||||
Request feignRequest = Request.create("GET", "http://foo", new HashMap<String, Collection<String>>(),
|
||||
new byte[]{}, StandardCharsets.UTF_8);
|
||||
@@ -435,18 +518,17 @@ public class RetryableFeignLoadBalancerTests {
|
||||
}
|
||||
}).build();
|
||||
doReturn(fourOFourResponse).when(client).execute(any(Request.class), any(Request.Options.class));
|
||||
MyBackOffPolicyFactory backOffPolicyFactory = new MyBackOffPolicyFactory();
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryPolicyFactory, backOffPolicyFactory);
|
||||
RetryableFeignLoadBalancer feignLb = new RetryableFeignLoadBalancer(lb, config, inspector, loadBalancedRetryFactory);
|
||||
FeignLoadBalancer.RibbonResponse ribbonResponse = feignLb.execute(request, null);
|
||||
verify(client, times(2)).execute(any(Request.class), any(Request.Options.class));
|
||||
assertEquals(1, backOffPolicyFactory.getCount());
|
||||
assertEquals(1, backOffPolicy.getCount());
|
||||
InputStream inputStream = ribbonResponse.toResponse().body().asInputStream();
|
||||
byte[] buf = new byte[100];
|
||||
int read = inputStream.read(buf);
|
||||
Assert.assertThat(new String(buf, 0, read), is("test"));
|
||||
}
|
||||
|
||||
class MyBackOffPolicyFactory implements LoadBalancedBackOffPolicyFactory, BackOffPolicy {
|
||||
class MyBackOffPolicy implements BackOffPolicy {
|
||||
|
||||
private int count = 0;
|
||||
|
||||
@@ -464,34 +546,25 @@ public class RetryableFeignLoadBalancerTests {
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackOffPolicy createBackOffPolicy(String service) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
class MyRetryListeners implements LoadBalancedRetryListenerFactory {
|
||||
class MyRetryListener implements RetryListener {
|
||||
|
||||
private int onError = 0;
|
||||
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[] {new RetryListener() {
|
||||
@Override
|
||||
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
|
||||
return true;
|
||||
}
|
||||
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
@Override
|
||||
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
onError++;
|
||||
}
|
||||
}};
|
||||
@Override
|
||||
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
onError++;
|
||||
}
|
||||
|
||||
public int getOnError() {
|
||||
@@ -499,27 +572,20 @@ public class RetryableFeignLoadBalancerTests {
|
||||
}
|
||||
}
|
||||
|
||||
class MyRetryListenersNotRetry implements LoadBalancedRetryListenerFactory {
|
||||
class MyRetryListenerNotRetry implements RetryListener {
|
||||
|
||||
@Override
|
||||
public RetryListener[] createRetryListeners(String service) {
|
||||
return new RetryListener[] {new RetryListener() {
|
||||
@Override
|
||||
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
|
||||
}
|
||||
}};
|
||||
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,11 +5,11 @@
|
||||
<parent>
|
||||
<artifactId>spring-cloud-dependencies-parent</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<version>2.0.0.RC1</version>
|
||||
<version>2.0.1.RELEASE</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
|
||||
<version>2.0.0.M1</version>
|
||||
<version>2.0.0.RC2</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>spring-cloud-openfeign-dependencies</name>
|
||||
<description>Spring Cloud OpenFeign Dependencies</description>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.0.0.M1</version>
|
||||
<version>2.0.0.RC2</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user