Compare commits
55
Commits
v2.0.0.RC1
...
2.0.x
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5113db4e3 | ||
|
|
a98f379e68 | ||
|
|
7b5d469839 | ||
|
|
816eaa6abf | ||
|
|
4d9a7c4ddd | ||
|
|
ab1f1f43a8 | ||
|
|
c51117d556 | ||
|
|
d6ad74a933 | ||
|
|
6aa6684d13 | ||
|
|
11098e9a99 | ||
|
|
36cc521a81 | ||
|
|
3a79850467 | ||
|
|
117e2c2b01 | ||
|
|
80de4e6b66 | ||
|
|
5f4acbe80e | ||
|
|
a693c30930 | ||
|
|
4e7e187323 | ||
|
|
88a6682f46 | ||
|
|
5ddd771ed5 | ||
|
|
9f9c41ab59 | ||
|
|
4dd68ca2f2 | ||
|
|
af094d0bfc | ||
|
|
77cdd40f7d | ||
|
|
750cb35e6a | ||
|
|
b512c451fd | ||
|
|
da6a51778f | ||
|
|
9fc19bb6fe | ||
|
|
e0bf63bed1 | ||
|
|
a33fd6d869 | ||
|
|
06ccb9d1e5 | ||
|
|
d57cea265e | ||
|
|
34cb91bc4c | ||
|
|
58dc45d230 | ||
|
|
80af701ccf | ||
|
|
46bc5da424 | ||
|
|
7dcb696ec4 | ||
|
|
69461d4385 | ||
|
|
8364b16b8e | ||
|
|
6d4686624e | ||
|
|
51ad63231d | ||
|
|
6c09501d77 | ||
|
|
7e1c91c8b8 | ||
|
|
674b88b467 | ||
|
|
a57c416d4a | ||
|
|
ffd4290e06 | ||
|
|
804ef91620 | ||
|
|
48e2f70757 | ||
|
|
569628689b | ||
|
|
af02a8c692 | ||
|
|
21be1e129c | ||
|
|
18111801d3 | ||
|
|
e27d4d38e5 | ||
|
|
01a2cda776 | ||
|
|
9ac36c7f3f | ||
|
|
f4fc531857 |
@@ -28,7 +28,7 @@ added after the original pull request but before a merge.
|
||||
you can import formatter settings using the
|
||||
`eclipse-code-formatter.xml` file from the
|
||||
[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.
|
||||
[Eclipse Code Formatter Plugin](https://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.
|
||||
@@ -40,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 [these conventions](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
|
||||
* When writing a commit message please follow [these conventions](https://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).
|
||||
|
||||
+5
-5
@@ -21,7 +21,7 @@
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>http://repo.spring.io/libs-snapshot-local</url>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
@@ -29,7 +29,7 @@
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>http://repo.spring.io/libs-milestone-local</url>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
@@ -37,7 +37,7 @@
|
||||
<repository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>http://repo.spring.io/release</url>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
@@ -47,7 +47,7 @@
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>http://repo.spring.io/libs-snapshot-local</url>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
@@ -55,7 +55,7 @@
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>http://repo.spring.io/libs-milestone-local</url>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
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
|
||||
https://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,
|
||||
|
||||
+142
-8
@@ -51,7 +51,7 @@ credentials and you already have those.
|
||||
|
||||
The projects that require middleware generally include a
|
||||
`docker-compose.yml`, so consider using
|
||||
http://compose.docker.io/[Docker Compose] to run the middeware servers
|
||||
https://compose.docker.io/[Docker Compose] to run the middeware servers
|
||||
in Docker containers. See the README in the
|
||||
https://github.com/spring-cloud-samples/scripts[scripts demo
|
||||
repository] for specific instructions about the common cases of mongo,
|
||||
@@ -73,13 +73,13 @@ a modified file in the correct place. Just commit it and push the change.
|
||||
|
||||
=== Working with the code
|
||||
If you don't have an IDE preference we would recommend that you use
|
||||
http://www.springsource.com/developer/sts[Spring Tools Suite] or
|
||||
http://eclipse.org[Eclipse] when working with the code. We use the
|
||||
http://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools
|
||||
https://www.springsource.com/developer/sts[Spring Tools Suite] or
|
||||
https://eclipse.org[Eclipse] when working with the code. We use the
|
||||
https://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools
|
||||
should also work without issue as long as they use Maven 3.3.3 or better.
|
||||
|
||||
==== Importing into eclipse with m2eclipse
|
||||
We recommend the http://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with
|
||||
We recommend the https://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with
|
||||
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
|
||||
marketplace".
|
||||
|
||||
@@ -108,6 +108,8 @@ from the `file` menu.
|
||||
|
||||
== Contributing
|
||||
|
||||
:spring-cloud-build-branch: master
|
||||
|
||||
Spring Cloud is released under the non-restrictive Apache 2.0 license,
|
||||
and follows a very standard Github development process, using Github
|
||||
tracker for issues and merging pull requests into master. If you want
|
||||
@@ -136,7 +138,7 @@ added after the original pull request but before a merge.
|
||||
`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
|
||||
https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
|
||||
Plugin] 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
|
||||
@@ -149,6 +151,138 @@ 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 https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
|
||||
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).
|
||||
|
||||
=== Checkstyle
|
||||
|
||||
Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are:
|
||||
|
||||
.spring-cloud-build-tools/
|
||||
----
|
||||
└── src
|
||||
├── checkstyle
|
||||
│ └── checkstyle-suppressions.xml <3>
|
||||
└── main
|
||||
└── resources
|
||||
├── checkstyle-header.txt <2>
|
||||
└── checkstyle.xml <1>
|
||||
----
|
||||
<1> Default Checkstyle rules
|
||||
<2> File header setup
|
||||
<3> Default suppression rules
|
||||
|
||||
==== Checkstyle configuration
|
||||
|
||||
Checkstyle rules are *disabled by default*. To add checkstyle to your project just define the following properties and plugins.
|
||||
|
||||
.pom.xml
|
||||
----
|
||||
<properties>
|
||||
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> <1>
|
||||
<maven-checkstyle-plugin.failsOnViolation>true
|
||||
</maven-checkstyle-plugin.failsOnViolation> <2>
|
||||
<maven-checkstyle-plugin.includeTestSourceDirectory>true
|
||||
</maven-checkstyle-plugin.includeTestSourceDirectory> <3>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin> <4>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin> <5>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin> <5>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
</build>
|
||||
----
|
||||
<1> Fails the build upon Checkstyle errors
|
||||
<2> Fails the build upon Checkstyle violations
|
||||
<3> Checkstyle analyzes also the test sources
|
||||
<4> Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules
|
||||
<5> Add checkstyle plugin to your build and reporting phases
|
||||
|
||||
If you need to suppress some rules (e.g. line length needs to be longer), then it's enough for you to define a file under `${project.root}/src/checkstyle/checkstyle-suppressions.xml` with your suppressions. Example:
|
||||
|
||||
.projectRoot/src/checkstyle/checkstyle-suppresions.xml
|
||||
----
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
|
||||
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
|
||||
<suppressions>
|
||||
<suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/>
|
||||
<suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/>
|
||||
</suppressions>
|
||||
----
|
||||
|
||||
It's advisable to copy the `${spring-cloud-build.rootFolder}/.editorconfig` and `${spring-cloud-build.rootFolder}/.springformat` to your project. That way, some default formatting rules will be applied. You can do so by running this script:
|
||||
|
||||
```bash
|
||||
$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig
|
||||
$ touch .springformat
|
||||
```
|
||||
|
||||
=== IDE setup
|
||||
|
||||
==== Intellij IDEA
|
||||
|
||||
In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin.
|
||||
|
||||
.spring-cloud-build-tools/
|
||||
----
|
||||
└── src
|
||||
├── checkstyle
|
||||
│ └── checkstyle-suppressions.xml <3>
|
||||
└── main
|
||||
└── resources
|
||||
├── checkstyle-header.txt <2>
|
||||
├── checkstyle.xml <1>
|
||||
└── intellij
|
||||
├── Intellij_Project_Defaults.xml <4>
|
||||
└── Intellij_Spring_Boot_Java_Conventions.xml <5>
|
||||
----
|
||||
<1> Default Checkstyle rules
|
||||
<2> File header setup
|
||||
<3> Default suppression rules
|
||||
<4> Project defaults for Intellij that apply most of Checkstyle rules
|
||||
<5> Project style conventions for Intellij that apply most of Checkstyle rules
|
||||
|
||||
.Code style
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-code-style.png[Code style]
|
||||
|
||||
Go to `File` -> `Settings` -> `Editor` -> `Code style`. There click on the icon next to the `Scheme` section. There, click on the `Import Scheme` value and pick the `Intellij IDEA code style XML` option. Import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml` file.
|
||||
|
||||
.Inspection profiles
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-inspections.png[Code style]
|
||||
|
||||
Go to `File` -> `Settings` -> `Editor` -> `Inspections`. There click on the icon next to the `Profile` section. There, click on the `Import Profile` and import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml` file.
|
||||
|
||||
.Checkstyle
|
||||
|
||||
To have Intellij work with Checkstyle, you have to install the `Checkstyle` plugin. It's advisable to also install the `Assertions2Assertj` to automatically convert the JUnit assertions
|
||||
|
||||
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-checkstyle.png[Checkstyle]
|
||||
|
||||
Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on the `+` icon in the `Configuration file` section. There, you'll have to define where the checkstyle rules should be picked from. In the image above, we've picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build's GitHub repository (e.g. for the `checkstyle.xml` : `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml`). We need to provide the following variables:
|
||||
|
||||
- `checkstyle.header.file` - please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/main/resources/checkstyle/checkstyle-header.txt` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` URL.
|
||||
- `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL.
|
||||
- `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`.
|
||||
|
||||
IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
|
||||
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
|
||||
/* Remove the comments around the @import statement below when using this as a custom stylesheet */
|
||||
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic|Noto+Serif:400,400italic,700,700italic|Droid+Sans+Mono:400";*/
|
||||
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.0.0.RC1</version>
|
||||
<version>2.0.5.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-openfeign-docs</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -40,7 +40,7 @@ function check_if_anything_to_sync() {
|
||||
|
||||
function retrieve_current_branch() {
|
||||
# Code getting the name of the current branch. For master we want to publish as we did until now
|
||||
# http://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch
|
||||
# https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch
|
||||
# If there is a branch already passed will reuse it - otherwise will try to find it
|
||||
CURRENT_BRANCH=${BRANCH}
|
||||
if [[ -z "${CURRENT_BRANCH}" ]] ; then
|
||||
@@ -147,7 +147,7 @@ function copy_docs_for_current_version() {
|
||||
COMMIT_CHANGES="yes"
|
||||
else
|
||||
echo -e "Current branch is [${CURRENT_BRANCH}]"
|
||||
# http://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin
|
||||
# https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin
|
||||
if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then
|
||||
mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH}
|
||||
echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder"
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
spring-cloud-openfeign.adoc
|
||||
@@ -1,7 +1,7 @@
|
||||
:github-tag: master
|
||||
:github-repo: spring-cloud/spring-cloud-openfeign
|
||||
:github-raw: http://raw.github.com/{github-repo}/{github-tag}
|
||||
:github-code: http://github.com/{github-repo}/tree/{github-tag}
|
||||
:github-raw: https://raw.github.com/{github-repo}/{github-tag}
|
||||
:github-code: https://github.com/{github-repo}/tree/{github-tag}
|
||||
:all: {asterisk}{asterisk}
|
||||
:nofooter:
|
||||
:branch: master
|
||||
@@ -21,7 +21,7 @@ https://github.com/Netflix/feign[Feign] is a declarative web service client. It
|
||||
=== How to Include Feign
|
||||
|
||||
To include Feign in your project use the starter with group `org.springframework.cloud`
|
||||
and artifact id `spring-cloud-starter-openfeign`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
|
||||
and artifact id `spring-cloud-starter-openfeign`. See the https://projects.spring.io/spring-cloud/[Spring Cloud Project page]
|
||||
for details on setting up your build system with the current Spring Cloud Release Train.
|
||||
|
||||
Example spring boot app
|
||||
@@ -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:
|
||||
|
||||
@@ -224,14 +224,14 @@ class FooController {
|
||||
private FooClient adminClient;
|
||||
|
||||
@Autowired
|
||||
public FooController(
|
||||
Decoder decoder, Encoder encoder, Client client, Contract contract) {
|
||||
public FooController(Decoder decoder, Encoder encoder, Client client, Contract contract) {
|
||||
this.fooClient = Feign.builder().client(client)
|
||||
.encoder(encoder)
|
||||
.decoder(decoder)
|
||||
.contract(contract)
|
||||
.contract(contract)
|
||||
.requestInterceptor(new BasicAuthRequestInterceptor("user", "user"))
|
||||
.target(FooClient.class, "http://PROD-SVC");
|
||||
|
||||
this.adminClient = Feign.builder().client(client)
|
||||
.encoder(encoder)
|
||||
.decoder(decoder)
|
||||
@@ -425,12 +425,4 @@ public class FooConfiguration {
|
||||
return Logger.Level.FULL;
|
||||
}
|
||||
}
|
||||
----
|
||||
OtherClass.someMethod(myprop.get());
|
||||
}
|
||||
}
|
||||
stripped). The proxy uses Ribbon to locate an instance to forward to
|
||||
via discovery, and all requests are executed in a
|
||||
<<hystrix-fallbacks-for-routes, hystrix command>>, so
|
||||
failures will show up in Hystrix metrics, and once the circuit is open
|
||||
the proxy will not try to contact the service.
|
||||
----
|
||||
@@ -8,7 +8,7 @@
|
||||
# "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
|
||||
# https://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
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.0.0.RC1</version>
|
||||
<version>2.0.5.BUILD-SNAPSHOT</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.RELEASE</version>
|
||||
<version>2.0.5.BUILD-SNAPSHOT</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.RC1</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.0.0.RC1</spring-cloud-netflix.version>
|
||||
<spring-cloud-commons.version>2.0.3.BUILD-SNAPSHOT</spring-cloud-commons.version>
|
||||
<spring-cloud-netflix.version>2.0.3.BUILD-SNAPSHOT</spring-cloud-netflix.version>
|
||||
|
||||
<!-- Plugin versions -->
|
||||
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-openfeign</artifactId>
|
||||
<version>2.0.0.RC1</version>
|
||||
<version>2.0.5.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<artifactId>spring-cloud-openfeign-core</artifactId>
|
||||
@@ -93,6 +93,10 @@
|
||||
<artifactId>feign-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign.form</groupId>
|
||||
<artifactId>feign-form-spring</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.openfeign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
@@ -163,6 +167,16 @@
|
||||
<artifactId>okhttp</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
@@ -188,6 +202,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
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -202,8 +202,8 @@ public class FeignAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(Client.class)
|
||||
public Client feignClient() {
|
||||
return new OkHttpClient(this.okHttpClient);
|
||||
public Client feignClient(okhttp3.OkHttpClient client) {
|
||||
return new OkHttpClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* A builder for creating Feign clients without using the {@link FeignClient} annotation.
|
||||
* <p>
|
||||
* This builder builds the Feign client exactly like it would be created by using the
|
||||
* {@link FeignClient} annotation.
|
||||
*
|
||||
* @author Sven Döring
|
||||
*/
|
||||
public class FeignClientBuilder {
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
public FeignClientBuilder(final ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public <T> Builder<T> forType(final Class<T> type, final String name) {
|
||||
return new Builder<>(applicationContext, type, name);
|
||||
}
|
||||
|
||||
public static class Builder<T> {
|
||||
|
||||
private FeignClientFactoryBean feignClientFactoryBean;
|
||||
|
||||
private Builder(final ApplicationContext applicationContext, final Class<T> type,
|
||||
final String name) {
|
||||
this.feignClientFactoryBean = new FeignClientFactoryBean();
|
||||
|
||||
this.feignClientFactoryBean.setApplicationContext(applicationContext);
|
||||
this.feignClientFactoryBean.setType(type);
|
||||
this.feignClientFactoryBean.setName(FeignClientsRegistrar.getName(name));
|
||||
// preset default values - these values resemble the default values on the
|
||||
// FeignClient annotation
|
||||
this.url("").path("").decode404(false).fallback(void.class)
|
||||
.fallbackFactory(void.class);
|
||||
}
|
||||
|
||||
public Builder url(final String url) {
|
||||
this.feignClientFactoryBean.setUrl(FeignClientsRegistrar.getUrl(url));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder path(final String path) {
|
||||
this.feignClientFactoryBean.setPath(FeignClientsRegistrar.getPath(path));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder decode404(final boolean decode404) {
|
||||
this.feignClientFactoryBean.setDecode404(decode404);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder fallback(final Class<T> fallback) {
|
||||
FeignClientsRegistrar.validateFallback(fallback);
|
||||
this.feignClientFactoryBean.setFallback(fallback);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder fallbackFactory(final Class<T> fallbackFactory) {
|
||||
FeignClientsRegistrar.validateFallbackFactory(fallbackFactory);
|
||||
this.feignClientFactoryBean.setFallbackFactory(fallbackFactory);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> the target type of the Feign client to be created
|
||||
* @return the created Feign client
|
||||
*/
|
||||
public <T> T build() {
|
||||
return this.feignClientFactoryBean.getTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-4
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -229,6 +229,14 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
return getTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> the target type of the Feign client
|
||||
* @return a {@link Feign} client created with the specified data and the context information
|
||||
*/
|
||||
<T> T getTarget() {
|
||||
FeignContext context = applicationContext.getBean(FeignContext.class);
|
||||
Feign.Builder builder = feign(context);
|
||||
|
||||
@@ -241,7 +249,7 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
|
||||
url = this.name;
|
||||
}
|
||||
url += cleanPath();
|
||||
return loadBalance(builder, context, new HardCodedTarget<>(this.type,
|
||||
return (T) loadBalance(builder, context, new HardCodedTarget<>(this.type,
|
||||
this.name, url));
|
||||
}
|
||||
if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
|
||||
@@ -251,14 +259,14 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
|
||||
Client client = getOptional(context, Client.class);
|
||||
if (client != null) {
|
||||
if (client instanceof LoadBalancerFeignClient) {
|
||||
// not lod balancing because we have a url,
|
||||
// not load balancing because we have a url,
|
||||
// but ribbon is on the classpath, so unwrap
|
||||
client = ((LoadBalancerFeignClient)client).getDelegate();
|
||||
}
|
||||
builder.client(client);
|
||||
}
|
||||
Targeter targeter = get(context, Targeter.class);
|
||||
return targeter.target(this, builder, context, new HardCodedTarget<>(
|
||||
return (T) targeter.target(this, builder, context, new HardCodedTarget<>(
|
||||
this.type, this.name, url));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+23
-4
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -198,12 +198,19 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
AnnotationAttributes annotation = AnnotationAttributes.fromMap(attributes);
|
||||
// This blows up if an aliased property is overspecified
|
||||
// FIXME annotation.getAliasedString("name", FeignClient.class, null);
|
||||
validateFallback(annotation.getClass("fallback"));
|
||||
validateFallbackFactory(annotation.getClass("fallbackFactory"));
|
||||
}
|
||||
|
||||
static void validateFallback(final Class clazz) {
|
||||
Assert.isTrue(
|
||||
!annotation.getClass("fallback").isInterface(),
|
||||
!clazz.isInterface(),
|
||||
"Fallback class must implement the interface annotated by @FeignClient"
|
||||
);
|
||||
Assert.isTrue(
|
||||
!annotation.getClass("fallbackFactory").isInterface(),
|
||||
}
|
||||
|
||||
static void validateFallbackFactory(final Class clazz) {
|
||||
Assert.isTrue(!clazz.isInterface(),
|
||||
"Fallback factory must produce instances of fallback classes that implement the interface annotated by @FeignClient"
|
||||
);
|
||||
}
|
||||
@@ -217,6 +224,10 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
name = (String) attributes.get("value");
|
||||
}
|
||||
name = resolve(name);
|
||||
return getName(name);
|
||||
}
|
||||
|
||||
static String getName(String name) {
|
||||
if (!StringUtils.hasText(name)) {
|
||||
return "";
|
||||
}
|
||||
@@ -247,6 +258,10 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
|
||||
private String getUrl(Map<String, Object> attributes) {
|
||||
String url = resolve((String) attributes.get("url"));
|
||||
return getUrl(url);
|
||||
}
|
||||
|
||||
static String getUrl(String url) {
|
||||
if (StringUtils.hasText(url) && !(url.startsWith("#{") && url.contains("}"))) {
|
||||
if (!url.contains("://")) {
|
||||
url = "http://" + url;
|
||||
@@ -263,6 +278,10 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
|
||||
private String getPath(Map<String, Object> attributes) {
|
||||
String path = resolve((String) attributes.get("path"));
|
||||
return getPath(path);
|
||||
}
|
||||
|
||||
static String getPath(String path) {
|
||||
if (StringUtils.hasText(path)) {
|
||||
path = path.trim();
|
||||
if (!path.startsWith("/")) {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-14
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -62,19 +62,6 @@ class HystrixTargeter implements Targeter {
|
||||
Class<?> fallbackFactoryClass) {
|
||||
FallbackFactory<? extends T> fallbackFactory = (FallbackFactory<? extends T>)
|
||||
getFromContext("fallbackFactory", feignClientName, context, fallbackFactoryClass, FallbackFactory.class);
|
||||
/* We take a sample fallback from the fallback factory to check if it returns a fallback
|
||||
that is compatible with the annotated feign interface. */
|
||||
Object exampleFallback = fallbackFactory.create(new RuntimeException());
|
||||
Assert.notNull(exampleFallback,
|
||||
String.format(
|
||||
"Incompatible fallbackFactory instance for feign client %s. Factory may not produce null!",
|
||||
feignClientName));
|
||||
if (!target.type().isAssignableFrom(exampleFallback.getClass())) {
|
||||
throw new IllegalStateException(
|
||||
String.format(
|
||||
"Incompatible fallbackFactory instance for feign client %s. Factory produces instances of '%s', but should produce instances of '%s'",
|
||||
feignClientName, exampleFallback.getClass(), target.type()));
|
||||
}
|
||||
return builder.target(target, fallbackFactory);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+2
-3
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -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
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+2
-3
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -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 {
|
||||
|
||||
+2
-3
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -79,9 +79,8 @@ public class FeignContentGzipEncodingInterceptor extends BaseRequestInterceptor
|
||||
final long length = Long.parseLong(strLen);
|
||||
return length > getProperties().getMinRequestSize();
|
||||
} catch (NumberFormatException ex) {
|
||||
// ignores the exception
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* * 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
|
||||
* * https://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,
|
||||
|
||||
+3
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -54,6 +54,7 @@ public class FeignRibbonClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
|
||||
public CachingSpringLoadBalancerFactory cachingLBClientFactory(
|
||||
SpringClientFactory factory) {
|
||||
@@ -62,6 +63,7 @@ public class FeignRibbonClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
|
||||
public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory(
|
||||
SpringClientFactory factory,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+13
-2
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -97,7 +97,18 @@ public class LoadBalancerFeignClient implements Client {
|
||||
}
|
||||
|
||||
static URI cleanUrl(String originalUrl, String host) {
|
||||
return URI.create(originalUrl.replaceFirst(host, ""));
|
||||
String newUrl = originalUrl;
|
||||
if(originalUrl.startsWith("https://")) {
|
||||
newUrl = originalUrl.substring(0, 8) + originalUrl.substring(8 + host.length());
|
||||
} else if(originalUrl.startsWith("http")) {
|
||||
newUrl = originalUrl.substring(0, 7) + originalUrl.substring(7 + host.length());
|
||||
}
|
||||
StringBuffer buffer = new StringBuffer(newUrl);
|
||||
if((newUrl.startsWith("https://") && newUrl.length() == 8) ||
|
||||
(newUrl.startsWith("http://") && newUrl.length() == 7)) {
|
||||
buffer.append("/");
|
||||
}
|
||||
return URI.create(buffer.toString());
|
||||
}
|
||||
|
||||
private FeignLoadBalancer lbClient(String clientName) {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
* * 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
|
||||
* * https://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,
|
||||
@@ -101,7 +101,7 @@ public class RetryableFeignLoadBalancer extends FeignLoadBalancer implements Ser
|
||||
feignRequest = request.toRequest();
|
||||
}
|
||||
Response response = request.client().execute(feignRequest, options);
|
||||
if (retryPolicy.retryableStatusCode(response.status())) {
|
||||
if (retryPolicy != null && retryPolicy.retryableStatusCode(response.status())) {
|
||||
byte[] byteArray = response.body() == null ? new byte[]{} : StreamUtils.copyToByteArray(response.body().asInputStream());
|
||||
response.close();
|
||||
throw new RibbonResponseStatusCodeException(RetryableFeignLoadBalancer.this.clientName, response,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* * 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
|
||||
* * https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+29
-4
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -22,7 +22,9 @@ 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 java.util.Objects;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -33,21 +35,27 @@ 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 org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
import feign.form.spring.SpringFormEncoder;
|
||||
|
||||
import static org.springframework.cloud.openfeign.support.FeignUtils.getHeaders;
|
||||
import static org.springframework.cloud.openfeign.support.FeignUtils.getHttpHeaders;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author ScienJus
|
||||
*/
|
||||
public class SpringEncoder implements Encoder {
|
||||
|
||||
private static final Log log = LogFactory.getLog(SpringEncoder.class);
|
||||
|
||||
private final SpringFormEncoder springFormEncoder = new SpringFormEncoder();
|
||||
|
||||
private ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
|
||||
public SpringEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||
@@ -68,6 +76,18 @@ public class SpringEncoder implements Encoder {
|
||||
requestContentType = MediaType.valueOf(type);
|
||||
}
|
||||
|
||||
if (bodyType != null && bodyType.equals(MultipartFile.class)) {
|
||||
if (Objects.equals(requestContentType, MediaType.MULTIPART_FORM_DATA)) {
|
||||
springFormEncoder.encode(requestBody, bodyType, request);
|
||||
return;
|
||||
} else {
|
||||
String message = "Content-Type \"" + MediaType.MULTIPART_FORM_DATA +
|
||||
"\" not set for request body of type " +
|
||||
requestBody.getClass().getSimpleName();
|
||||
throw new EncodeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters
|
||||
.getObject().getConverters()) {
|
||||
if (messageConverter.canWrite(requestType, requestContentType)) {
|
||||
@@ -99,12 +119,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;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
{"groups": [
|
||||
], "properties": [
|
||||
{
|
||||
"name": "feign.hystrix.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "If true, an OpenFeign client will be wrapped with a Hystrix circuit breaker.",
|
||||
"defaultValue": "false"
|
||||
},
|
||||
{
|
||||
"name": "feign.httpclient.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Enables the use of the Apache HTTP Client by Feign.",
|
||||
"defaultValue": "true"
|
||||
},
|
||||
{
|
||||
"name": "feign.okhttp.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Enables the use of the OK HTTP Client by Feign.",
|
||||
"defaultValue": "false"
|
||||
},
|
||||
{
|
||||
"name": "feign.compression.response.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Enables the response from Feign to be compressed.",
|
||||
"defaultValue": "false"
|
||||
},
|
||||
{
|
||||
"name": "feign.compression.request.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Enables the request sent by Feign to be compressed.",
|
||||
"defaultValue": "false"
|
||||
}
|
||||
]}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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
|
||||
*
|
||||
* https://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;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.ClosedFileSystemException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.openfeign.testclients.TestClient;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* @author Sven Döring
|
||||
*/
|
||||
public class FeignClientBuilderTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private FeignClientBuilder feignClientBuilder;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private static Object getDefaultValueFromFeignClientAnnotation(
|
||||
final String methodName) {
|
||||
final Method method = ReflectionUtils.findMethod(FeignClient.class, methodName);
|
||||
return method.getDefaultValue();
|
||||
}
|
||||
|
||||
private static void assertFactoryBeanField(final FeignClientBuilder.Builder builder,
|
||||
final String fieldName, final Object expectedValue) {
|
||||
final Field factoryBeanField = ReflectionUtils
|
||||
.findField(FeignClientBuilder.Builder.class, "feignClientFactoryBean");
|
||||
ReflectionUtils.makeAccessible(factoryBeanField);
|
||||
final FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) ReflectionUtils
|
||||
.getField(factoryBeanField, builder);
|
||||
|
||||
final Field field = ReflectionUtils.findField(FeignClientFactoryBean.class,
|
||||
fieldName);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
final Object value = ReflectionUtils.getField(field, factoryBean);
|
||||
Assert.assertEquals("Expected value for the field '" + fieldName + "':",
|
||||
expectedValue, value);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.applicationContext = Mockito.mock(ApplicationContext.class);
|
||||
this.feignClientBuilder = new FeignClientBuilder(applicationContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void safetyCheckForNewFieldsOnTheFeignClientAnnotation() {
|
||||
final List<String> methodNames = new ArrayList();
|
||||
for (final Method method : FeignClient.class.getMethods()) {
|
||||
methodNames.add(method.getName());
|
||||
}
|
||||
methodNames.removeAll(
|
||||
Arrays.asList("annotationType", "value", "serviceId", "qualifier",
|
||||
"configuration", "primary", "equals", "hashCode", "toString"));
|
||||
Collections.sort(methodNames);
|
||||
// If this safety check fails the Builder has to be updated.
|
||||
// (1) Either a field was removed from the FeignClient annotation and so it has to
|
||||
// be removed
|
||||
// on this builder class.
|
||||
// (2) Or a new field was added and the builder class has to be extended with this
|
||||
// new field.
|
||||
Assert.assertThat(methodNames, Matchers.contains("decode404", "fallback",
|
||||
"fallbackFactory", "name", "path", "url"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forType_preinitializedBuilder() {
|
||||
// when:
|
||||
final FeignClientBuilder.Builder builder = feignClientBuilder
|
||||
.forType(FeignClientBuilderTests.class, "TestClient");
|
||||
|
||||
// then:
|
||||
assertFactoryBeanField(builder, "applicationContext", applicationContext);
|
||||
assertFactoryBeanField(builder, "type", FeignClientBuilderTests.class);
|
||||
assertFactoryBeanField(builder, "name", "TestClient");
|
||||
|
||||
// and:
|
||||
assertFactoryBeanField(builder, "url",
|
||||
getDefaultValueFromFeignClientAnnotation("url"));
|
||||
assertFactoryBeanField(builder, "path",
|
||||
getDefaultValueFromFeignClientAnnotation("path"));
|
||||
assertFactoryBeanField(builder, "decode404",
|
||||
getDefaultValueFromFeignClientAnnotation("decode404"));
|
||||
assertFactoryBeanField(builder, "fallback",
|
||||
getDefaultValueFromFeignClientAnnotation("fallback"));
|
||||
assertFactoryBeanField(builder, "fallbackFactory",
|
||||
getDefaultValueFromFeignClientAnnotation("fallbackFactory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forType_allFieldsSetOnBuilder() {
|
||||
// when:
|
||||
final FeignClientBuilder.Builder builder = feignClientBuilder
|
||||
.forType(FeignClientBuilderTests.class, "TestClient").decode404(true)
|
||||
.fallback(Object.class).fallbackFactory(Object.class).path("Path/")
|
||||
.url("Url/");
|
||||
|
||||
// then:
|
||||
assertFactoryBeanField(builder, "applicationContext", applicationContext);
|
||||
assertFactoryBeanField(builder, "type", FeignClientBuilderTests.class);
|
||||
assertFactoryBeanField(builder, "name", "TestClient");
|
||||
|
||||
// and:
|
||||
assertFactoryBeanField(builder, "url", "http://Url/");
|
||||
assertFactoryBeanField(builder, "path", "/Path");
|
||||
assertFactoryBeanField(builder, "decode404", true);
|
||||
assertFactoryBeanField(builder, "fallback", Object.class);
|
||||
assertFactoryBeanField(builder, "fallbackFactory", Object.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forType_build() {
|
||||
// given:
|
||||
Mockito.when(applicationContext.getBean(FeignContext.class))
|
||||
.thenThrow(new ClosedFileSystemException()); // throw an unusual exception
|
||||
// in the
|
||||
// FeignClientFactoryBean
|
||||
final FeignClientBuilder.Builder builder = feignClientBuilder
|
||||
.forType(TestClient.class, "TestClient");
|
||||
|
||||
// expect: 'the build will fail right after calling build() with the mocked
|
||||
// unusual exception'
|
||||
thrown.expect(Matchers.isA(ClosedFileSystemException.class));
|
||||
builder.build();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+36
-3
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -31,8 +31,11 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.cloud.openfeign.FeignClientBuilder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -66,12 +69,24 @@ public class FeignClientTests {
|
||||
@Autowired
|
||||
private org.springframework.cloud.openfeign.beans.extra.TestClient extraClient;
|
||||
|
||||
@Qualifier("build-by-builder")
|
||||
@Autowired
|
||||
private TestClient buildByBuilder;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@EnableFeignClients
|
||||
@Import(FeignClientBuilder.class)
|
||||
protected static class Application {
|
||||
|
||||
@Bean("build-by-builder")
|
||||
public TestClient buildByBuilder(final FeignClientBuilder feignClientBuilder) {
|
||||
return feignClientBuilder
|
||||
.forType(TestClient.class, "builderapp")
|
||||
.build();
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
public Hello getHello() {
|
||||
return new Hello("hello world 1");
|
||||
@@ -112,7 +127,7 @@ public class FeignClientTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnnnotations() throws Exception {
|
||||
public void testAnnotations() {
|
||||
Map<String, Object> beans = this.context
|
||||
.getBeansWithAnnotation(FeignClient.class);
|
||||
assertTrue("Wrong clients: " + beans,
|
||||
@@ -122,13 +137,31 @@ public class FeignClientTests {
|
||||
@Test
|
||||
public void testClient() {
|
||||
assertNotNull("testClient was null", this.testClient);
|
||||
assertNotNull("testClient was null", this.extraClient);
|
||||
assertNotNull("extraClient was null", this.extraClient);
|
||||
assertTrue("testClient is not a java Proxy",
|
||||
Proxy.isProxyClass(this.testClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.testClient);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extraClient() {
|
||||
assertNotNull("extraClient was null", this.extraClient);
|
||||
assertTrue("extraClient is not a java Proxy",
|
||||
Proxy.isProxyClass(this.extraClient.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.extraClient);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildByBuilder() {
|
||||
assertNotNull("buildByBuilder was null", this.buildByBuilder);
|
||||
assertTrue("buildByBuilder is not a java Proxy",
|
||||
Proxy.isProxyClass(this.buildByBuilder.getClass()));
|
||||
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.buildByBuilder);
|
||||
assertNotNull("invocationHandler was null", invocationHandler);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class TestDefaultFeignConfig {
|
||||
}
|
||||
|
||||
+3
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -18,9 +18,11 @@ package org.springframework.cloud.openfeign.beans;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.cloud.openfeign.beans.FeignClientTests.Hello;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@Primary
|
||||
@FeignClient(value = "localapp")
|
||||
public interface TestClient {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/hello")
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+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
|
||||
*
|
||||
* https://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
|
||||
*
|
||||
* https://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
|
||||
*
|
||||
* https://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
|
||||
*
|
||||
* https://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
|
||||
*
|
||||
* https://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();
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-41
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -240,44 +240,4 @@ public class FeignClientValidationTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongFallbackFactoryGenericType() {
|
||||
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
|
||||
WrongFallbackFactoryGenericTypeConfiguration.class)) {
|
||||
this.expected.expectMessage("Incompatible fallbackFactory instance");
|
||||
assertNotNull(context.getBean(WrongFallbackFactoryGenericTypeConfiguration.Client.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(FeignAutoConfiguration.class)
|
||||
@EnableFeignClients(clients = WrongFallbackFactoryGenericTypeConfiguration.Client.class)
|
||||
protected static class WrongFallbackFactoryGenericTypeConfiguration {
|
||||
|
||||
@FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = ClientFallback.class)
|
||||
interface Client {
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/")
|
||||
String get();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ClientFallback dummy() {
|
||||
return new ClientFallback();
|
||||
}
|
||||
|
||||
class ClientFallback implements FallbackFactory<String> {
|
||||
|
||||
@Override
|
||||
public String create(Throwable cause) {
|
||||
return "tryinToTrickYa";
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Feign.Builder feignBuilder() {
|
||||
return HystrixFeign.builder();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+30
-8
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -37,7 +37,9 @@ import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.hamcrest.MockitoHamcrest.argThat;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
@@ -88,13 +90,33 @@ public class FeignRibbonClientTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remoteRequestIsSent() throws Exception {
|
||||
Request request = new RequestTemplate().method("GET").append("http://foo/")
|
||||
public void remoteRequestIsSentAtRoot() throws Exception {
|
||||
Request request = new RequestTemplate().method("GET").append("https://foo")
|
||||
.request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("http://foo.com:8000/");
|
||||
/*FIXME verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));*/
|
||||
RequestMatcher matcher = new RequestMatcher("https://foo.com:8000/");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void remoteRequestIsSent() throws Exception {
|
||||
Request request = new RequestTemplate().method("GET").append("https://foo/")
|
||||
.request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("https://foo.com:8000/");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyCleanUrl() throws Exception {
|
||||
Request request = new RequestTemplate().method("GET").append("https://tp/abc/bcd.json")
|
||||
.request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("https://foo.com:8000/abc/bcd.json");
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -103,8 +125,8 @@ public class FeignRibbonClientTests {
|
||||
.request();
|
||||
this.client.execute(request, new Options());
|
||||
RequestMatcher matcher = new RequestMatcher("https://foo.com:8000/");
|
||||
/*FIXME verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));*/
|
||||
verify(this.delegate).execute(argThat(matcher),
|
||||
any(Options.class));
|
||||
}
|
||||
|
||||
private final static class RequestMatcher extends CustomMatcher<Request> {
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
package org.springframework.cloud.openfeign.ribbon;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import javax.net.ssl.SSLContextSpi;
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
package org.springframework.cloud.netflix.feign.ribbon;
|
||||
package org.springframework.cloud.openfeign.ribbon;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* 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
|
||||
* https://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,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user