Compare commits

...
68 Commits
Author SHA1 Message Date
buildmaster 1b0626a345 Update SNAPSHOT to 3.1.0 2021-12-01 18:37:07 +00:00
Olga MaciaszekSharma b4f6f4ee30 Merge remote-tracking branch 'origin/3.0.x' 2021-11-29 16:47:58 +01:00
Been24 70a9002002 Update RetryableFeignBlockingLoadBalancerClient.java
fix log  class
2021-11-29 16:45:40 +01:00
Olga MaciaszekSharma ffbcf788bf Merge remote-tracking branch 'origin/3.0.x' 2021-11-29 16:38:36 +01:00
Nikita Konev ad892a23f0 Support size = 0 in PageJacksonModule 2021-11-29 16:30:20 +01:00
Olga Maciaszek-Sharma 85886c0cbb Add and configure duplicate finder. Remove duplicate classes. (#633) 2021-11-29 11:46:34 +01:00
buildmaster f7e4281002 Bumping versions 2021-11-27 00:23:06 +00:00
Olga MaciaszekSharma 65efa29da5 Refactor. 2021-11-09 17:40:01 +01:00
buildmaster 4e23e0cf58 Going back to snapshots 2021-11-03 11:31:10 +00:00
buildmaster d11e0d9dd4 Update SNAPSHOT to 3.1.0-RC1 2021-11-03 11:29:49 +00:00
Olga MaciaszekSharma e5deb642a2 Revert "Temporarily disable codecov."
This reverts commit ba7346573e.
2021-11-02 17:45:59 +01:00
Olga MaciaszekSharma ba7346573e Temporarily disable codecov. 2021-11-02 17:25:27 +01:00
Olga Maciaszek-Sharma 38ccf1be95 Use LB per-client properties. (#622) 2021-11-02 17:24:43 +01:00
spencergibb 5fee522f4c Uses new LoadBalancerClientsProperties class, take 2 2021-10-28 14:48:11 -04:00
spencergibb ce04947d92 Uses new LoadBalancerClientsProperties class 2021-10-28 14:38:26 -04:00
spencergibb 61f71e6ac7 formatting 2021-10-28 14:38:08 -04:00
Olga MaciaszekSharma 939f279a38 Merge remote-tracking branch 'origin/3.0.x' 2021-10-28 18:20:16 +02:00
Hyeonmin Park c0f314a5f0 GitHub workflows: Use Java version in matrix, cache functionality of actions/setup-java@v2 (#614)
* Fix GitHub workflows not using Java version in matrix

* Use cache functionality of actions/setup-java@v2
2021-10-28 18:15:02 +02:00
Sam Kruglov 0cd57b2ce7 cache support (#607) (#608) 2021-10-28 17:59:52 +02:00
spencergibb 1752dd9815 Upgrades openfeign to 11.7 2021-10-26 15:33:04 -04:00
Sam Kruglov b78eacd714 make FeignClientSpecification public (#594) (#609) 2021-10-21 16:47:10 +02:00
buildmaster 56dc4e07e4 Bumping versions to 3.0.6-SNAPSHOT after release 2021-10-21 11:48:48 +00:00
buildmaster 9167752bfb Going back to snapshots 2021-10-21 11:48:47 +00:00
buildmaster 127c866616 Update SNAPSHOT to 3.0.5 2021-10-21 11:46:52 +00:00
buildmaster 876778935c Going back to snapshots 2021-10-21 11:36:13 +00:00
buildmaster ae97365b6c Update SNAPSHOT to 3.1.0-M4 2021-10-21 11:34:56 +00:00
Olga MaciaszekSharma fd6c1290fe Merge remote-tracking branch 'origin/3.0.x' 2021-10-21 13:23:05 +02:00
Olga MaciaszekSharma 0e6b33f480 Merge remote-tracking branch 'origin/2.2.x' into 3.0.x 2021-10-21 13:04:57 +02:00
Olga MaciaszekSharma 17d0161faf Reformat. 2021-10-21 12:40:20 +02:00
Olga MaciaszekSharma d6783a6f1e Block clas-level request mapping on Feign clients. 2021-10-21 12:14:19 +02:00
buildmaster 7f03521b0d Bumping versions 2021-10-21 00:32:35 +00:00
Sam Kruglov 21adacbc43 allow @CollectionFormat on class level (#596) (#610) 2021-10-20 15:39:52 +02:00
buildmaster 3de4b98b3d Going back to snapshots 2021-10-20 02:18:15 +00:00
buildmaster a5e66077d6 Update SNAPSHOT to 3.1.0-M3 2021-10-20 02:16:47 +00:00
Olga MaciaszekSharma 02c0a1e0f6 Merge remote-tracking branch 'origin/3.0.x' 2021-10-11 18:47:07 +02:00
Olga MaciaszekSharma 98229d5ece Merge remote-tracking branch 'origin/3.0.x' 2021-10-11 18:45:46 +02:00
Olga MaciaszekSharma 548e4d55ef Revert default circuit breaker name prefix to target.type(). Fixes gh-606. 2021-10-11 18:40:21 +02:00
Olga MaciaszekSharma 9c0dda896f Use new Spring Hateoas API. 2021-10-11 13:24:59 +02:00
Szymon Linowski f018193b9f Merge branch '3.0.x' into switch-remaining-junit4-tests-to-junit-jupiter 2021-10-06 18:45:37 +02:00
Szymon Linowski 3432b7a965 Switch remaining jUnit4 tests to jUnit jupiter 2021-10-06 18:40:36 +02:00
Szymon Linowski 8d8d948f08 Merge branch 'main' into switch-remaining-junit4-tests-to-junit-jupiter 2021-10-05 16:19:59 +02:00
buildmaster c6ea224501 Going back to snapshots 2021-10-01 17:07:56 +00:00
buildmaster f5be046f90 Update SNAPSHOT to 3.1.0-M2 2021-10-01 17:06:36 +00:00
buildmaster 9018acfc40 Bumping versions 2021-09-30 00:23:25 +00:00
GongYi 6533389e16 Add a CookieValueParameterProcessor to support @CookieValue (#604) 2021-09-29 14:01:36 +02:00
buildmaster 1ff68c11d2 Bumping versions 2021-09-28 00:22:33 +00:00
buildmaster 55ceafae4d Bumping versions to 3.0.5-SNAPSHOT after release 2021-09-21 14:39:31 +00:00
buildmaster 0c87527ea5 Going back to snapshots 2021-09-21 14:39:31 +00:00
buildmaster a2c473db2a Update SNAPSHOT to 3.0.4 2021-09-21 14:37:38 +00:00
Can Bezmen ae33802a4b FIX gh-601 2021-09-20 15:35:28 +02:00
Szymon Linowski abdb699f1d Switch remaining jUnit4 tests to jUnit jupiter 2021-09-13 16:57:25 +02:00
Olga MaciaszekSharma 8b9254a008 Merge remote-tracking branch 'origin/3.0.x' 2021-09-09 17:59:25 +02:00
Olga MaciaszekSharma c761919bc9 Only add default query params and default headers if not already in template. Fixes gh-590. 2021-09-09 17:59:08 +02:00
Olga MaciaszekSharma 95a93dcc5c Merge remote-tracking branch 'origin/3.0.x' 2021-09-08 18:52:44 +02:00
Olga MaciaszekSharma 998baed0d3 Merge remote-tracking branch 'origin/3.0.x' into 3.0.x 2021-09-08 18:52:18 +02:00
Olga MaciaszekSharma 4fc80e6b01 Update docs. Fixes gh-585. 2021-09-08 18:52:11 +02:00
Szymon Linowski 685b42e85f Switch remaining jUnit4 tests to jUnit jupiter 2021-08-01 12:04:56 +02:00
buildmaster 8dd2c82968 Going back to snapshots 2021-07-30 18:17:15 +00:00
Olga MaciaszekSharma 1275875ddb Reformat. 2021-07-07 18:58:48 +02:00
Olga MaciaszekSharma c4b9492a9b Bumping versions to 2.2.10.BUILD-SNAPSHOT after release
This reverts commit f7e490c466.
2021-07-07 18:46:53 +02:00
Olga MaciaszekSharma 3acf5f9e92 Going back to snapshots
This reverts commit 6479db0a54.
2021-07-07 18:46:20 +02:00
buildmaster e9e38d0274 Bumping versions 2021-07-07 14:07:20 +00:00
Olga MaciaszekSharma 28b50401c5 Revert "Update SNAPSHOT to 2.2.9.RELEASE"
This reverts commit 1005749eb5.
2021-07-07 14:38:12 +02:00
Olga MaciaszekSharma 6479db0a54 Revert "Going back to snapshots"
This reverts commit 190f5a9083.
2021-07-07 14:37:39 +02:00
Olga MaciaszekSharma f7e490c466 Revert "Bumping versions to 2.2.10.BUILD-SNAPSHOT after release"
This reverts commit d60cda824d.
2021-07-07 14:37:03 +02:00
buildmaster d60cda824d Bumping versions to 2.2.10.BUILD-SNAPSHOT after release 2021-07-06 14:53:53 +00:00
buildmaster 190f5a9083 Going back to snapshots 2021-07-06 14:53:53 +00:00
buildmaster 1005749eb5 Update SNAPSHOT to 2.2.9.RELEASE 2021-07-06 14:52:01 +00:00
67 changed files with 1103 additions and 687 deletions
+5 -10
View File
@@ -20,17 +20,12 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v2
with:
java-version: 1.8
- name: Cache local Maven repository
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
distribution: 'zulu'
java-version: ${{ matrix.java }}
cache: 'maven'
- name: Build with Maven
run: ./mvnw clean install -B -U -P sonar
- uses: codecov/codecov-action@v1
+53 -16
View File
@@ -66,23 +66,9 @@ the `.mvn` configuration, so if you find you have to do it to make a
build succeed, please raise a ticket to get the settings added to
source control.
For hints on how to build the project look in `.travis.yml` if there
is one. There should be a "script" and maybe "install" command. Also
look at the "services" section to see if any services need to be
running locally (e.g. mongo or rabbit). Ignore the git-related bits
that you might find in "before_install" since they're related to setting git
credentials and you already have those.
The projects that require middleware (i.e. Redis) for testing generally
require that a local instance of [Docker](https://www.docker.com/get-started) is installed and running.
The projects that require middleware generally include a
`docker-compose.yml`, so consider using
https://docs.docker.com/compose/[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,
rabbit and redis.
NOTE: If all else fails, build with the command from `.travis.yml` (usually
`./mvnw install`).
=== Documentation
@@ -317,6 +303,57 @@ Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on t
IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources.
=== Duplicate Finder
Spring Cloud Build brings along the `basepom:duplicate-finder-maven-plugin`, that enables flagging duplicate and conflicting classes and resources on the java classpath.
==== Duplicate Finder configuration
Duplicate finder is *enabled by default* and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the projecst's `pom.xml`.
.pom.xml
[source,xml]
----
<build>
<plugins>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
----
For other properties, we have set defaults as listed in the https://github.com/basepom/duplicate-finder-maven-plugin/wiki[plugin documentation].
You can easily override them but setting the value of the selected property prefixed with `duplicate-finder-maven-plugin`. For example, set `duplicate-finder-maven-plugin.skip` to `true` in order to skip duplicates check in your build.
If you need to add `ignoredClassPatterns` or `ignoredResourcePatterns` to your setup, make sure to add them in the plugin configuration section of your project:
[source,xml]
----
<build>
<plugins>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
<configuration>
<ignoredClassPatterns>
<ignoredClassPattern>org.joda.time.base.BaseDateTime</ignoredClassPattern>
<ignoredClassPattern>.*module-info</ignoredClassPattern>
</ignoredClassPatterns>
<ignoredResourcePatterns>
<ignoredResourcePattern>changelog.txt</ignoredResourcePattern>
</ignoredResourcePatterns>
</configuration>
</plugin>
</plugins>
</build>
----
== License
The project license file is available https://raw.githubusercontent.com/spring-cloud/spring-cloud-openfeign/main/LICENSE.txt[here].
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>3.1.0-M1</version>
<version>3.1.0</version>
</parent>
<artifactId>spring-cloud-openfeign-docs</artifactId>
<packaging>jar</packaging>
@@ -69,12 +69,12 @@ The load-balancer client above will want to discover the physical addresses
for the "stores" service. If your application is a Eureka client then
it will resolve the service in the Eureka service registry. If you
don't want to use Eureka, you can configure a list of servers
in your external configuration using https://cloud.spring.io/spring-cloud-static/spring-cloud-commons/current/reference/html/#simplediscoveryclient[`SimpleDiscoveryClient`].
in your external configuration using https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#simplediscoveryclient[`SimpleDiscoveryClient`].
Spring Cloud OpenFeign supports all the features available for the blocking mode of Spring Cloud LoadBalancer. You can read more about them in the https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-loadbalancer[project documentation].
TIP: To use `@EnableFeignClients` annotation on `@Configuration`-annotated-classes, make sure to specify where the clients are located, for example:
`@EnableFeignClients(basePackages = "com.example.clients")`
`@EnableFeignClients(basePackages = "com.example.clients")`
or list them explicitly:
`@EnableFeignClients(clients = InventoryServiceFeignClient.class)`
@@ -122,6 +122,7 @@ Spring Cloud OpenFeign provides the following beans by default for feign (`BeanT
* `Encoder` feignEncoder: `SpringEncoder`
* `Logger` feignLogger: `Slf4jLogger`
* `MicrometerCapability` micrometerCapability: If `feign-micrometer` is on the classpath and `MeterRegistry` is available
* `CachingCapability` cachingCapability: If `@EnableCaching` annotation is used. Can be disabled via `feign.cache.enabled`.
* `Contract` feignContract: `SpringMvcContract`
* `Feign.Builder` feignBuilder: `FeignCircuitBreaker.Builder`
* `Client` feignClient: If Spring Cloud LoadBalancer is on the classpath, `FeignBlockingLoadBalancerClient` is used.
@@ -141,7 +142,7 @@ Spring Cloud OpenFeign _does not_ provide the following beans by default for fei
* `Collection<RequestInterceptor>`
* `SetterFactory`
* `QueryMapEncoder`
* `Capability` (`MicrometerCapability` is provided by default)
* `Capability` (`MicrometerCapability` and `CachingCapability` are provided by default)
A bean of `Retryer.NEVER_RETRY` with the type `Retryer` is created by default, which will disable retrying.
Notice this retrying behavior is different from the Feign default one, where it will automatically retry IOExceptions,
@@ -494,10 +495,7 @@ public interface UserClient extends UserService {
}
----
NOTE: It is generally not advisable to share an interface between a
server and a client. It introduces tight coupling, and also actually
doesn't work with Spring MVC in its current form (method parameter
mapping is not inherited).
WARNING: `@FeignClient` interfaces should not be shared between server and client and annotating `@FeignClient` interfaces with `@RequestMapping` on class level is no longer supported.
=== Feign request/response compression
@@ -605,6 +603,22 @@ public class FooConfiguration {
}
----
=== Feign Caching
If `@EnableCaching` annotation is used, a `CachingCapability` bean is created and registered so that your Feign client recognizes `@Cache*` annotations on its interface:
[source,java,indent=0]
----
public interface DemoClient {
@GetMapping("/demo/{filterParam}")
@Cacheable(cacheNames = "demo-cache", key = "#keyParam")
String demoEndpoint(String keyParam, @PathVariable String filterParam);
}
----
You can also disable the feature via property `feign.cache.enabled=false`.
=== Feign @QueryMap support
The OpenFeign `@QueryMap` annotation provides support for POJOs to be used as
@@ -692,20 +706,21 @@ public interface DemoTemplate {
----
=== Feign `CollectionFormat` support
We support `feign.CollectionFormat` by providing the `@CollectionFormat` annotation.You can annotate a Feign client method with it by passing the desired `feign.CollectionFormat` as annotation value.
We support `feign.CollectionFormat` by providing the `@CollectionFormat` annotation.
You can annotate a Feign client method (or the whole class to affect all methods) with it by passing the desired `feign.CollectionFormat` as annotation value.
In the following example, the `CSV` format is used instead of the default `EXPLODED` to process the method.
[source,java,indent=0]
----
@FeignClient(name = "demo")
protected interface PageableFeignClient {
protected interface PageableFeignClient {
@CollectionFormat(feign.CollectionFormat.CSV)
@GetMapping(path = "/page")
ResponseEntity performRequest(Pageable page);
@CollectionFormat(feign.CollectionFormat.CSV)
@GetMapping(path = "/page")
ResponseEntity performRequest(Pageable page);
}
}
----
TIP: Set the `CSV` format while sending `Pageable` as a query parameter in order for it to be encoded correctly.
+12 -3
View File
@@ -4,14 +4,14 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-openfeign</artifactId>
<version>3.1.0-M1</version>
<version>3.1.0</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>3.1.0-M1</version>
<version>3.1.0</version>
<relativePath/>
</parent>
<scm>
@@ -26,7 +26,7 @@
<properties>
<main.basedir>${basedir}</main.basedir>
<jackson.version>2.11.3</jackson.version>
<spring-cloud-commons.version>3.1.0-M1</spring-cloud-commons.version>
<spring-cloud-commons.version>3.1.0</spring-cloud-commons.version>
<!-- Plugin versions -->
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
@@ -79,6 +79,15 @@
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
<configuration>
<ignoredResourcePatterns>
<ignoredResourcePattern>mozilla/public-suffix-list.txt</ignoredResourcePattern>
</ignoredResourcePatterns>
</configuration>
</plugin>
</plugins>
</build>
+17 -6
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>3.1.0-M1</version>
<version>3.1.0</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-openfeign-core</artifactId>
@@ -70,6 +70,12 @@
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -133,6 +139,16 @@
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -149,11 +165,6 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-test-support</artifactId>
@@ -0,0 +1,42 @@
/*
* Copyright 2013-2021 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 feign.Capability;
import feign.InvocationHandlerFactory;
import org.springframework.cache.interceptor.CacheInterceptor;
/**
* Allows Spring's @Cache* annotations to be declared on the feign client's methods.
*
* @author Sam Kruglov
*/
public class CachingCapability implements Capability {
private final CacheInterceptor cacheInterceptor;
public CachingCapability(CacheInterceptor cacheInterceptor) {
this.cacheInterceptor = cacheInterceptor;
}
@Override
public InvocationHandlerFactory enrich(InvocationHandlerFactory invocationHandlerFactory) {
return new FeignCachingInvocationHandlerFactory(invocationHandlerFactory, cacheInterceptor);
}
}
@@ -25,9 +25,10 @@ import java.lang.annotation.Target;
* Indicates which collection format should be used while processing the annotated method.
*
* @author Olga Maciaszek-Sharma
* @author Sam Kruglov
* @see feign.CollectionFormat
*/
@Target(ElementType.METHOD)
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface CollectionFormat {
@@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
import com.fasterxml.jackson.databind.Module;
import feign.Capability;
import feign.Client;
import feign.Feign;
import feign.RequestInterceptor;
@@ -50,6 +51,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.interceptor.CacheInterceptor;
import org.springframework.cloud.client.actuator.HasFeatures;
import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
@@ -81,6 +83,7 @@ import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResour
* @author Nguyen Ky Thanh
* @author Andrii Bohutskyi
* @author Kwangyong Kim
* @author Sam Kruglov
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Feign.class)
@@ -105,6 +108,13 @@ public class FeignAutoConfiguration {
return context;
}
@Bean
@ConditionalOnProperty(value = "feign.cache.enabled", matchIfMissing = true)
@ConditionalOnBean(CacheInterceptor.class)
public Capability cachingCapability(CacheInterceptor cacheInterceptor) {
return new CachingCapability(cacheInterceptor);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Module.class, Page.class, Sort.class })
@ConditionalOnProperty(value = "feign.autoconfiguration.jackson.enabled", havingValue = "true")
@@ -167,7 +177,7 @@ public class FeignAutoConfiguration {
@Override
public String resolveCircuitBreakerName(String feignClientName, Target<?> target, Method method) {
return Feign.configKey(target.getClass(), method);
return Feign.configKey(target.type(), method);
}
}
@@ -0,0 +1,82 @@
/*
* Copyright 2013-2021 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.AccessibleObject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Optional;
import feign.InvocationHandlerFactory;
import feign.Target;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.cache.interceptor.CacheInterceptor;
/**
* Allows Spring's @Cache* annotations to be declared on the feign client's methods.
*
* @author Sam Kruglov
*/
public class FeignCachingInvocationHandlerFactory implements InvocationHandlerFactory {
private final InvocationHandlerFactory delegateFactory;
private final CacheInterceptor cacheInterceptor;
public FeignCachingInvocationHandlerFactory(InvocationHandlerFactory delegateFactory,
CacheInterceptor cacheInterceptor) {
this.delegateFactory = delegateFactory;
this.cacheInterceptor = cacheInterceptor;
}
@Override
public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {
final InvocationHandler delegateHandler = delegateFactory.create(target, dispatch);
return (proxy, method, argsNullable) -> {
Object[] args = Optional.ofNullable(argsNullable).orElseGet(() -> new Object[0]);
return cacheInterceptor.invoke(new MethodInvocation() {
@Override
public Method getMethod() {
return method;
}
@Override
public Object[] getArguments() {
return args;
}
@Override
public Object proceed() throws Throwable {
return delegateHandler.invoke(proxy, method, args);
}
@Override
public Object getThis() {
return target;
}
@Override
public AccessibleObject getStaticPart() {
return method;
}
});
};
}
}
@@ -17,6 +17,7 @@
package org.springframework.cloud.openfeign;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -276,13 +277,8 @@ public class FeignClientFactoryBean
builder.encoder(getOrInstantiate(config.getEncoder()));
}
if (Objects.nonNull(config.getDefaultRequestHeaders())) {
builder.requestInterceptor(requestTemplate -> requestTemplate.headers(config.getDefaultRequestHeaders()));
}
if (Objects.nonNull(config.getDefaultQueryParameters())) {
builder.requestInterceptor(requestTemplate -> requestTemplate.queries(config.getDefaultQueryParameters()));
}
addDefaultRequestHeaders(config, builder);
addDefaultQueryParams(config, builder);
if (Objects.nonNull(config.getDecoder())) {
builder.decoder(getOrInstantiate(config.getDecoder()));
@@ -301,6 +297,35 @@ public class FeignClientFactoryBean
}
}
private void addDefaultQueryParams(FeignClientProperties.FeignClientConfiguration config, Feign.Builder builder) {
Map<String, Collection<String>> defaultQueryParameters = config.getDefaultQueryParameters();
if (Objects.nonNull(defaultQueryParameters)) {
builder.requestInterceptor(requestTemplate -> {
Map<String, Collection<String>> queries = requestTemplate.queries();
defaultQueryParameters.keySet().forEach(key -> {
if (!queries.containsKey(key)) {
requestTemplate.query(key, defaultQueryParameters.get(key));
}
});
});
}
}
private void addDefaultRequestHeaders(FeignClientProperties.FeignClientConfiguration config,
Feign.Builder builder) {
Map<String, Collection<String>> defaultRequestHeaders = config.getDefaultRequestHeaders();
if (Objects.nonNull(defaultRequestHeaders)) {
builder.requestInterceptor(requestTemplate -> {
Map<String, Collection<String>> headers = requestTemplate.headers();
defaultRequestHeaders.keySet().forEach(key -> {
if (!headers.containsKey(key)) {
requestTemplate.header(key, defaultRequestHeaders.get(key));
}
});
});
}
}
private <T> T getOrInstantiate(Class<T> tClass) {
try {
return beanFactory != null ? beanFactory.getBean(tClass) : applicationContext.getBean(tClass);
@@ -25,7 +25,7 @@ import org.springframework.cloud.context.named.NamedContextFactory;
* @author Dave Syer
* @author Gregor Zurowski
*/
class FeignClientSpecification implements NamedContextFactory.Specification {
public class FeignClientSpecification implements NamedContextFactory.Specification {
private String name;
@@ -34,7 +34,7 @@ class FeignClientSpecification implements NamedContextFactory.Specification {
FeignClientSpecification() {
}
FeignClientSpecification(String name, Class<?>[] configuration) {
public FeignClientSpecification(String name, Class<?>[] configuration) {
this.name = name;
this.configuration = configuration;
}
@@ -0,0 +1,67 @@
/*
* Copyright 2013-2021 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.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import feign.MethodMetadata;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.CookieValue;
import static feign.Util.checkState;
import static feign.Util.emptyToNull;
/**
* @{link CookieValue} annotation processor.
* @author Gong Yi
*
*/
public class CookieValueParameterProcessor implements AnnotatedParameterProcessor {
private static final Class<CookieValue> ANNOTATION = CookieValue.class;
@Override
public Class<? extends Annotation> getAnnotationType() {
return ANNOTATION;
}
@Override
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
int parameterIndex = context.getParameterIndex();
MethodMetadata data = context.getMethodMetadata();
CookieValue cookie = ANNOTATION.cast(annotation);
String name = cookie.value().trim();
checkState(emptyToNull(name) != null, "Cookie.name() was empty on parameter %s", parameterIndex);
context.setParameterName(name);
String cookieExpression = data.template().headers().getOrDefault(HttpHeaders.COOKIE, Arrays.asList("")).stream()
.findFirst().orElse("");
if (cookieExpression.length() == 0) {
cookieExpression = String.format("%s={%s}", name, name);
}
else {
cookieExpression += String.format("; %s={%s}", name, name);
}
data.template().removeHeader(HttpHeaders.COOKIE);
data.template().header(HttpHeaders.COOKIE, cookieExpression);
return true;
}
}
@@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
@@ -39,15 +39,15 @@ import org.springframework.context.annotation.Configuration;
* @since 2.2.0
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(LoadBalancerProperties.class)
@EnableConfigurationProperties(LoadBalancerClientsProperties.class)
class DefaultFeignLoadBalancerConfiguration {
@Bean
@ConditionalOnMissingBean
@Conditional(OnRetryNotEnabledCondition.class)
public Client feignClient(LoadBalancerClient loadBalancerClient, LoadBalancerProperties properties,
public Client feignClient(LoadBalancerClient loadBalancerClient,
LoadBalancerClientFactory loadBalancerClientFactory) {
return new FeignBlockingLoadBalancerClient(new Client.Default(null, null), loadBalancerClient, properties,
return new FeignBlockingLoadBalancerClient(new Client.Default(null, null), loadBalancerClient,
loadBalancerClientFactory);
}
@@ -58,10 +58,9 @@ class DefaultFeignLoadBalancerConfiguration {
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true",
matchIfMissing = true)
public Client feignRetryClient(LoadBalancerClient loadBalancerClient,
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerProperties properties,
LoadBalancerClientFactory loadBalancerClientFactory) {
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
return new RetryableFeignBlockingLoadBalancerClient(new Client.Default(null, null), loadBalancerClient,
loadBalancedRetryFactory, properties, loadBalancerClientFactory);
loadBalancedRetryFactory, loadBalancerClientFactory);
}
}
@@ -60,15 +60,24 @@ public class FeignBlockingLoadBalancerClient implements Client {
private final LoadBalancerClient loadBalancerClient;
private final LoadBalancerProperties properties;
private final LoadBalancerClientFactory loadBalancerClientFactory;
/**
* @deprecated in favour of
* {@link FeignBlockingLoadBalancerClient#FeignBlockingLoadBalancerClient(Client, LoadBalancerClient, LoadBalancerClientFactory)}
*/
@Deprecated
public FeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
LoadBalancerProperties properties, LoadBalancerClientFactory loadBalancerClientFactory) {
this.delegate = delegate;
this.loadBalancerClient = loadBalancerClient;
this.properties = properties;
this.loadBalancerClientFactory = loadBalancerClientFactory;
}
public FeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
LoadBalancerClientFactory loadBalancerClientFactory) {
this.delegate = delegate;
this.loadBalancerClient = loadBalancerClient;
this.loadBalancerClientFactory = loadBalancerClientFactory;
}
@@ -116,6 +125,7 @@ public class FeignBlockingLoadBalancerClient implements Client {
}
private String getHint(String serviceId) {
LoadBalancerProperties properties = loadBalancerClientFactory.getProperties(serviceId);
String defaultHint = properties.getHint().getOrDefault("default", "default");
String hintPropertyValue = properties.getHint().get(serviceId);
return hintPropertyValue != null ? hintPropertyValue : defaultHint;
@@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.openfeign.clientconfig.HttpClient5FeignConfiguration;
import org.springframework.context.annotation.Bean;
@@ -46,16 +46,16 @@ import org.springframework.context.annotation.Import;
@ConditionalOnBean({ LoadBalancerClient.class, LoadBalancerClientFactory.class })
@ConditionalOnProperty(value = "feign.httpclient.hc5.enabled", havingValue = "true")
@Import(HttpClient5FeignConfiguration.class)
@EnableConfigurationProperties(LoadBalancerProperties.class)
@EnableConfigurationProperties(LoadBalancerClientsProperties.class)
class HttpClient5FeignLoadBalancerConfiguration {
@Bean
@ConditionalOnMissingBean
@Conditional(OnRetryNotEnabledCondition.class)
public Client feignClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient5,
LoadBalancerProperties properties, LoadBalancerClientFactory loadBalancerClientFactory) {
LoadBalancerClientFactory loadBalancerClientFactory) {
Client delegate = new ApacheHttp5Client(httpClient5);
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, properties, loadBalancerClientFactory);
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory);
}
@Bean
@@ -65,11 +65,10 @@ class HttpClient5FeignLoadBalancerConfiguration {
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true",
matchIfMissing = true)
public Client feignRetryClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient5,
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerProperties properties,
LoadBalancerClientFactory loadBalancerClientFactory) {
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
Client delegate = new ApacheHttp5Client(httpClient5);
return new RetryableFeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancedRetryFactory,
properties, loadBalancerClientFactory);
loadBalancerClientFactory);
}
}
@@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.openfeign.HttpClient5DisabledConditions;
import org.springframework.cloud.openfeign.clientconfig.HttpClientFeignConfiguration;
@@ -50,16 +50,16 @@ import org.springframework.context.annotation.Import;
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
@Conditional(HttpClient5DisabledConditions.class)
@Import(HttpClientFeignConfiguration.class)
@EnableConfigurationProperties(LoadBalancerProperties.class)
@EnableConfigurationProperties(LoadBalancerClientsProperties.class)
class HttpClientFeignLoadBalancerConfiguration {
@Bean
@ConditionalOnMissingBean
@Conditional(OnRetryNotEnabledCondition.class)
public Client feignClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient,
LoadBalancerProperties properties, LoadBalancerClientFactory loadBalancerClientFactory) {
LoadBalancerClientFactory loadBalancerClientFactory) {
ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, properties, loadBalancerClientFactory);
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory);
}
@Bean
@@ -69,11 +69,10 @@ class HttpClientFeignLoadBalancerConfiguration {
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true",
matchIfMissing = true)
public Client feignRetryClient(LoadBalancerClient loadBalancerClient, HttpClient httpClient,
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerProperties properties,
LoadBalancerClientFactory loadBalancerClientFactory) {
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
return new RetryableFeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancedRetryFactory,
properties, loadBalancerClientFactory);
loadBalancerClientFactory);
}
}
@@ -26,7 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.openfeign.clientconfig.OkHttpFeignConfiguration;
import org.springframework.context.annotation.Bean;
@@ -46,16 +46,16 @@ import org.springframework.context.annotation.Import;
@ConditionalOnProperty("feign.okhttp.enabled")
@ConditionalOnBean({ LoadBalancerClient.class, LoadBalancerClientFactory.class })
@Import(OkHttpFeignConfiguration.class)
@EnableConfigurationProperties(LoadBalancerProperties.class)
@EnableConfigurationProperties(LoadBalancerClientsProperties.class)
class OkHttpFeignLoadBalancerConfiguration {
@Bean
@ConditionalOnMissingBean
@Conditional(OnRetryNotEnabledCondition.class)
public Client feignClient(okhttp3.OkHttpClient okHttpClient, LoadBalancerClient loadBalancerClient,
LoadBalancerProperties properties, LoadBalancerClientFactory loadBalancerClientFactory) {
LoadBalancerClientFactory loadBalancerClientFactory) {
OkHttpClient delegate = new OkHttpClient(okHttpClient);
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, properties, loadBalancerClientFactory);
return new FeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancerClientFactory);
}
@Bean
@@ -65,11 +65,10 @@ class OkHttpFeignLoadBalancerConfiguration {
@ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true",
matchIfMissing = true)
public Client feignRetryClient(LoadBalancerClient loadBalancerClient, okhttp3.OkHttpClient okHttpClient,
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerProperties properties,
LoadBalancerClientFactory loadBalancerClientFactory) {
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
OkHttpClient delegate = new OkHttpClient(okHttpClient);
return new RetryableFeignBlockingLoadBalancerClient(delegate, loadBalancerClient, loadBalancedRetryFactory,
properties, loadBalancerClientFactory);
loadBalancerClientFactory);
}
}
@@ -70,7 +70,7 @@ import static org.springframework.cloud.openfeign.loadbalancer.LoadBalancerUtils
@SuppressWarnings({ "rawtypes", "unchecked" })
public class RetryableFeignBlockingLoadBalancerClient implements Client {
private static final Log LOG = LogFactory.getLog(FeignBlockingLoadBalancerClient.class);
private static final Log LOG = LogFactory.getLog(RetryableFeignBlockingLoadBalancerClient.class);
private final Client delegate;
@@ -78,17 +78,27 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
private final LoadBalancedRetryFactory loadBalancedRetryFactory;
private final LoadBalancerProperties properties;
private final LoadBalancerClientFactory loadBalancerClientFactory;
/**
* @deprecated in favour of
* {@link RetryableFeignBlockingLoadBalancerClient#RetryableFeignBlockingLoadBalancerClient(Client, LoadBalancerClient, LoadBalancedRetryFactory, LoadBalancerClientFactory)}
*/
@Deprecated
public RetryableFeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerProperties properties,
LoadBalancerClientFactory loadBalancerClientFactory) {
this.delegate = delegate;
this.loadBalancerClient = loadBalancerClient;
this.loadBalancedRetryFactory = loadBalancedRetryFactory;
this.properties = properties;
this.loadBalancerClientFactory = loadBalancerClientFactory;
}
public RetryableFeignBlockingLoadBalancerClient(Client delegate, LoadBalancerClient loadBalancerClient,
LoadBalancedRetryFactory loadBalancedRetryFactory, LoadBalancerClientFactory loadBalancerClientFactory) {
this.delegate = delegate;
this.loadBalancerClient = loadBalancerClient;
this.loadBalancedRetryFactory = loadBalancedRetryFactory;
this.loadBalancerClientFactory = loadBalancerClientFactory;
}
@@ -232,6 +242,7 @@ public class RetryableFeignBlockingLoadBalancerClient implements Client {
}
private String getHint(String serviceId) {
LoadBalancerProperties properties = loadBalancerClientFactory.getProperties(serviceId);
String defaultHint = properties.getHint().getOrDefault("default", "default");
String hintPropertyValue = properties.getHint().get(serviceId);
return hintPropertyValue != null ? hintPropertyValue : defaultHint;
@@ -38,6 +38,8 @@ import org.springframework.data.domain.Sort;
*
* @author Pascal Büttiker
* @author Olga Maciaszek-Sharma
* @author Pedro Mendes
* @author Nikita Konev
*/
public class PageJacksonModule extends Module {
@@ -69,18 +71,22 @@ public class PageJacksonModule extends Module {
@JsonProperty("size") int size, @JsonProperty("totalElements") @JsonAlias({ "total-elements",
"total_elements", "totalelements", "TotalElements" }) long totalElements,
@JsonProperty("sort") Sort sort) {
PageRequest pageRequest;
if (sort != null) {
pageRequest = PageRequest.of(number, size, sort);
if (size > 0) {
PageRequest pageRequest;
if (sort != null) {
pageRequest = PageRequest.of(number, size, sort);
}
else {
pageRequest = PageRequest.of(number, size);
}
delegate = new PageImpl<>(content, pageRequest, totalElements);
}
else {
pageRequest = PageRequest.of(number, size);
delegate = new PageImpl<>(content);
}
delegate = new PageImpl<>(content, pageRequest, totalElements);
}
@JsonProperty
@JsonIgnore
@Override
public int getTotalPages() {
return delegate.getTotalPages();
@@ -104,7 +110,7 @@ public class PageJacksonModule extends Module {
return delegate.getSize();
}
@JsonProperty
@JsonIgnore
@Override
public int getNumberOfElements() {
return delegate.getNumberOfElements();
@@ -128,13 +134,13 @@ public class PageJacksonModule extends Module {
return delegate.getSort();
}
@JsonProperty
@JsonIgnore
@Override
public boolean isFirst() {
return delegate.isFirst();
}
@JsonProperty
@JsonIgnore
@Override
public boolean isLast() {
return delegate.isLast();
@@ -176,6 +182,18 @@ public class PageJacksonModule extends Module {
return delegate.iterator();
}
@JsonIgnore
@Override
public Pageable getPageable() {
return delegate.getPageable();
}
@JsonIgnore
@Override
public boolean isEmpty() {
return delegate.isEmpty();
}
}
}
@@ -35,9 +35,12 @@ import feign.Feign;
import feign.MethodMetadata;
import feign.Param;
import feign.Request;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.cloud.openfeign.CollectionFormat;
import org.springframework.cloud.openfeign.annotation.CookieValueParameterProcessor;
import org.springframework.cloud.openfeign.annotation.MatrixVariableParameterProcessor;
import org.springframework.cloud.openfeign.annotation.PathVariableParameterProcessor;
import org.springframework.cloud.openfeign.annotation.QueryMapParameterProcessor;
@@ -79,9 +82,12 @@ import static org.springframework.core.annotation.AnnotatedElementUtils.findMerg
* @author Artyom Romanenko
* @author Darren Foong
* @author Ram Anaswara
* @author Sam Kruglov
*/
public class SpringMvcContract extends Contract.BaseContract implements ResourceLoaderAware {
private static final Log LOG = LogFactory.getLog(SpringMvcContract.class);
private static final String ACCEPT = "Accept";
private static final String CONTENT_TYPE = "Content-Type";
@@ -169,47 +175,22 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
@Override
protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
if (clz.getInterfaces().length == 0) {
RequestMapping classAnnotation = findMergedAnnotation(clz, RequestMapping.class);
if (classAnnotation != null) {
// Prepend path from class annotation if specified
if (classAnnotation.value().length > 0) {
String pathValue = emptyToNull(classAnnotation.value()[0]);
pathValue = resolve(pathValue);
if (!pathValue.startsWith("/")) {
pathValue = "/" + pathValue;
}
data.template().uri(pathValue);
if (data.template().decodeSlash() != decodeSlash) {
data.template().decodeSlash(decodeSlash);
}
}
}
RequestMapping classAnnotation = findMergedAnnotation(clz, RequestMapping.class);
if (classAnnotation != null) {
LOG.error("Cannot process class: " + clz.getName()
+ ". @RequestMapping annotation is not allowed on @FeignClient interfaces.");
throw new IllegalArgumentException("@RequestMapping annotation not allowed on @FeignClient interfaces");
}
CollectionFormat collectionFormat = findMergedAnnotation(clz, CollectionFormat.class);
if (collectionFormat != null) {
data.template().collectionFormat(collectionFormat.value());
}
}
@Override
public MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
processedMethods.put(Feign.configKey(targetType, method), method);
MethodMetadata md = super.parseAndValidateMetadata(targetType, method);
RequestMapping classAnnotation = findMergedAnnotation(targetType, RequestMapping.class);
if (classAnnotation != null) {
// produces - use from class annotation only if method has not specified this
if (!md.template().headers().containsKey(ACCEPT)) {
parseProduces(md, method, classAnnotation);
}
// consumes -- use from class annotation only if method has not specified this
if (!md.template().headers().containsKey(CONTENT_TYPE)) {
parseConsumes(md, method, classAnnotation);
}
// headers -- class annotation is inherited to methods, always write these if
// present
parseHeaders(md, method, classAnnotation);
}
return md;
return super.parseAndValidateMetadata(targetType, method);
}
@Override
@@ -360,6 +341,7 @@ public class SpringMvcContract extends Contract.BaseContract implements Resource
annotatedArgumentResolvers.add(new RequestHeaderParameterProcessor());
annotatedArgumentResolvers.add(new QueryMapParameterProcessor());
annotatedArgumentResolvers.add(new RequestPartParameterProcessor());
annotatedArgumentResolvers.add(new CookieValueParameterProcessor());
return annotatedArgumentResolvers;
}
@@ -17,8 +17,7 @@
package org.springframework.cloud.openfeign;
import feign.codec.Encoder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -26,22 +25,19 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.openfeign.support.PageableSpringEncoder;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = EnableFeignClientsSpringDataTests.PlainConfiguration.class)
@DirtiesContext
public class EnableFeignClientsSpringDataTests {
class EnableFeignClientsSpringDataTests {
@Autowired
private FeignContext feignContext;
@Test
public void encoderDefaultCorrect() {
void encoderDefaultCorrect() {
PageableSpringEncoder.class.cast(this.feignContext.getInstance("foo", Encoder.class));
}
@@ -23,17 +23,15 @@ import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.optionals.OptionalDecoder;
import feign.slf4j.Slf4jLogger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.cloud.test.ClassPathExclusions;
import org.springframework.cloud.test.ModifiedClassPathRunner;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -41,48 +39,47 @@ import org.springframework.context.annotation.Import;
/**
* @author Spencer Gibb
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "spring-data-commons-*.jar" })
public class EnableFeignClientsTests {
class EnableFeignClientsTests {
private ConfigurableApplicationContext context;
@Before
public void setUp() {
@BeforeEach
void setUp() {
context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
.properties("debug=true", "feign.httpclient.enabled=false")
.sources(EnableFeignClientsTests.PlainConfiguration.class).run();
}
@After
public void tearDown() {
@AfterEach
void tearDown() {
if (context != null) {
context.close();
}
}
@Test
public void decoderDefaultCorrect() {
void decoderDefaultCorrect() {
OptionalDecoder.class.cast(this.context.getBeansOfType(Decoder.class).get(0));
}
@Test
public void encoderDefaultCorrect() {
void encoderDefaultCorrect() {
SpringEncoder.class.cast(this.context.getBeansOfType(Encoder.class).get(0));
}
@Test
public void loggerDefaultCorrect() {
void loggerDefaultCorrect() {
Slf4jLogger.class.cast(this.context.getBeansOfType(Logger.class).get(0));
}
@Test
public void contractDefaultCorrect() {
void contractDefaultCorrect() {
SpringMvcContract.class.cast(this.context.getBeansOfType(Contract.class).get(0));
}
@Test
public void builderDefaultCorrect() {
void builderDefaultCorrect() {
Feign.Builder.class.cast(this.context.getBeansOfType(Feign.Builder.class).get(0));
}
@@ -20,7 +20,7 @@ import java.lang.reflect.Field;
import feign.Feign;
import feign.Logger;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -35,10 +35,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Matt King
* @author Sam Kruglov
*/
public class FeignBuilderCustomizerTests {
class FeignBuilderCustomizerTests {
@Test
public void testBuilderCustomizer() {
void testBuilderCustomizer() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
FeignBuilderCustomizerTests.SampleConfiguration2.class);
@@ -61,7 +61,7 @@ public class FeignBuilderCustomizerTests {
}
@Test
public void testBuildCustomizerOrdered() {
void testBuildCustomizerOrdered() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
FeignBuilderCustomizerTests.SampleConfiguration3.class);
@@ -76,7 +76,7 @@ public class FeignBuilderCustomizerTests {
}
@Test
public void testBuildCustomizerOrderedWithAdditional() {
void testBuildCustomizerOrderedWithAdditional() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
FeignBuilderCustomizerTests.SampleConfiguration3.class);
@@ -25,11 +25,8 @@ import java.util.Collections;
import java.util.List;
import feign.Feign;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.cloud.openfeign.testclients.TestClient;
@@ -37,15 +34,14 @@ import org.springframework.context.ApplicationContext;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Sven Döring
* @author Sam Kruglov
* @author Szymon Linowski
*/
public class FeignClientBuilderTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
class FeignClientBuilderTests {
private FeignClientBuilder feignClientBuilder;
@@ -75,14 +71,14 @@ public class FeignClientBuilderTests {
return (T) ReflectionUtils.getField(field, factoryBean);
}
@Before
public void setUp() {
@BeforeEach
void setUp() {
this.applicationContext = Mockito.mock(ApplicationContext.class);
this.feignClientBuilder = new FeignClientBuilder(this.applicationContext);
}
@Test
public void safetyCheckForNewFieldsOnTheFeignClientAnnotation() {
void safetyCheckForNewFieldsOnTheFeignClientAnnotation() {
final List<String> methodNames = new ArrayList();
for (final Method method : FeignClient.class.getMethods()) {
methodNames.add(method.getName());
@@ -101,7 +97,7 @@ public class FeignClientBuilderTests {
}
@Test
public void forType_preinitializedBuilder() {
void forType_preinitializedBuilder() {
// when:
final FeignClientBuilder.Builder builder = this.feignClientBuilder.forType(TestFeignClient.class, "TestClient");
@@ -120,7 +116,7 @@ public class FeignClientBuilderTests {
}
@Test
public void forType_allFieldsSetOnBuilder() {
void forType_allFieldsSetOnBuilder() {
// when:
final FeignClientBuilder.Builder builder = this.feignClientBuilder.forType(TestFeignClient.class, "TestClient")
.decode404(true).url("Url/").path("/Path").contextId("TestContext");
@@ -139,7 +135,7 @@ public class FeignClientBuilderTests {
}
@Test
public void forType_clientFactoryBeanProvided() {
void forType_clientFactoryBeanProvided() {
// when:
final FeignClientBuilder.Builder builder = this.feignClientBuilder
.forType(TestFeignClient.class, new FeignClientFactoryBean(), "TestClient").decode404(true)
@@ -160,21 +156,19 @@ public class FeignClientBuilderTests {
}
@Test
public void forType_build() {
void forType_build() {
// given:
Mockito.when(this.applicationContext.getBean(FeignContext.class)).thenThrow(new ClosedFileSystemException()); // throw
// an
// unusual
// exception
// in
// the
// FeignClientFactoryBean
// an
// unusual
// exception
// in
// the
// FeignClientFactoryBean
final FeignClientBuilder.Builder builder = this.feignClientBuilder.forType(TestClient.class, "TestClient");
// expect: 'the build will fail right after calling build() with the mocked
// unusual exception'
this.thrown.expect(Matchers.isA(ClosedFileSystemException.class));
builder.build();
assertThatExceptionOfType(ClosedFileSystemException.class).isThrownBy(() -> builder.build());
}
private interface TestFeignClient {
@@ -0,0 +1,123 @@
/*
* Copyright 2020-2020 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.net.UnknownHostException;
import feign.Contract;
import feign.RequestLine;
import feign.RetryableException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.SimpleKey;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Sam Kruglov
*/
@SpringBootTest(classes = FeignClientCacheTests.TestConfiguration.class)
@DirtiesContext
public class FeignClientCacheTests {
private static final String CACHE_NAME = "foo-cache";
@Autowired
private FooClient foo;
@Test
void cacheExists(@Autowired CacheManager cacheManager) {
assertThat(cacheManager.getCache(CACHE_NAME)).isNotNull();
}
@Test
void interceptedCallsReal() {
assertThatExceptionOfType(RetryableException.class).isThrownBy(foo::getWithCache)
.withRootCauseInstanceOf(UnknownHostException.class);
}
@Test
void nonInterceptedCallsReal() {
assertThatExceptionOfType(RetryableException.class).isThrownBy(foo::getWithoutCache)
.withRootCauseInstanceOf(UnknownHostException.class);
}
@Nested
class givenCached {
String cachedValue = "cached";
@BeforeEach
void setUp(@Autowired CacheManager cacheManager) {
cacheManager.getCache(CACHE_NAME).put(SimpleKey.EMPTY, cachedValue);
}
@Test
void interceptedReturnsCached() {
assertThat(foo.getWithCache()).isSameAs(cachedValue);
}
@Test
void nonInterceptedCallsReal() {
assertThatExceptionOfType(RetryableException.class).isThrownBy(foo::getWithoutCache)
.withRootCauseInstanceOf(UnknownHostException.class);
}
}
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = FooClient.class)
@EnableAutoConfiguration
@EnableCaching
protected static class TestConfiguration {
}
@FeignClient(name = "foo", url = "http://foo", configuration = FooConfiguration.class)
interface FooClient {
@RequestLine("GET /with-cache")
@Cacheable(cacheNames = CACHE_NAME)
String getWithCache();
@RequestLine("GET /without-cache")
String getWithoutCache();
}
public static class FooConfiguration {
@Bean
Contract feignContract() {
return new Contract.Default();
}
}
}
@@ -24,8 +24,7 @@ import feign.Feign;
import feign.Logger;
import feign.RequestInterceptor;
import feign.micrometer.MicrometerCapability;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@@ -35,7 +34,6 @@ import org.springframework.cloud.openfeign.clientconfig.FeignClientConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -45,12 +43,11 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Jonatan Ivanov
*/
@DirtiesContext
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = FeignClientUsingConfigurerTest.Application.class, value = {
"feign.client.config.default.loggerLevel=full",
"feign.client.config.default.requestInterceptors[0]=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.FooRequestInterceptor",
"feign.client.config.default.requestInterceptors[1]=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.BarRequestInterceptor" })
public class FeignClientUsingConfigurerTest {
class FeignClientUsingConfigurerTest {
private static final String BEAN_NAME_PREFIX = "org.springframework.cloud.openfeign.FeignClientUsingConfigurerTest$";
@@ -61,7 +58,7 @@ public class FeignClientUsingConfigurerTest {
private FeignContext context;
@Test
public void testFeignClient() {
void testFeignClient() {
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) beanFactory
.getBeanDefinition(BEAN_NAME_PREFIX + "TestFeignClient")
.getAttribute("feignClientsRegistrarFactoryBean");
@@ -84,7 +81,7 @@ public class FeignClientUsingConfigurerTest {
}
@Test
public void testNoInheritFeignClient() {
void testNoInheritFeignClient() {
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) beanFactory
.getBeanDefinition(BEAN_NAME_PREFIX + "NoInheritFeignClient")
.getAttribute("feignClientsRegistrarFactoryBean");
@@ -100,7 +97,7 @@ public class FeignClientUsingConfigurerTest {
}
@Test
public void testNoInheritFeignClient_ignoreProperties() {
void testNoInheritFeignClient_ignoreProperties() {
FeignClientFactoryBean factoryBean = (FeignClientFactoryBean) beanFactory
.getBeanDefinition(BEAN_NAME_PREFIX + "NoInheritFeignClient")
.getAttribute("feignClientsRegistrarFactoryBean");
@@ -18,7 +18,7 @@ package org.springframework.cloud.openfeign;
import java.util.Collections;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -29,48 +29,50 @@ import org.springframework.web.bind.annotation.GetMapping;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Spencer Gibb
* @author Gang Li
* @author Michal Domagala
* @author Szymon Linowski
*/
public class FeignClientsRegistrarTests {
class FeignClientsRegistrarTests {
@Test(expected = IllegalStateException.class)
public void badNameHttpPrefix() {
testGetName("https://bad_hostname");
}
@Test(expected = IllegalStateException.class)
public void badNameHttpsPrefix() {
testGetName("https://bad_hostname");
}
@Test(expected = IllegalStateException.class)
public void badName() {
testGetName("bad_hostname");
}
@Test(expected = IllegalStateException.class)
public void badNameStartsWithHttp() {
testGetName("http_bad_hostname");
@Test
void badNameHttpPrefix() {
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> testGetName("http://bad_hostname"));
}
@Test
public void goodName() {
void badNameHttpsPrefix() {
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> testGetName("https://bad_hostname"));
}
@Test
void badName() {
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> testGetName("bad_hostname"));
}
@Test
void badNameStartsWithHttp() {
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> testGetName("http_bad_hostname"));
}
@Test
void goodName() {
String name = testGetName("good-name");
assertThat(name).as("name was wrong").isEqualTo("good-name");
}
@Test
public void goodNameHttpPrefix() {
void goodNameHttpPrefix() {
String name = testGetName("https://good-name");
assertThat(name).as("name was wrong").isEqualTo("https://good-name");
}
@Test
public void goodNameHttpsPrefix() {
void goodNameHttpsPrefix() {
String name = testGetName("https://goodname");
assertThat(name).as("name was wrong").isEqualTo("https://goodname");
}
@@ -81,18 +83,20 @@ public class FeignClientsRegistrarTests {
return registrar.getName(Collections.singletonMap("name", name));
}
@Test(expected = IllegalArgumentException.class)
public void testFallback() {
new AnnotationConfigApplicationContext(FallbackTestConfig.class);
}
@Test(expected = IllegalArgumentException.class)
public void testFallbackFactory() {
new AnnotationConfigApplicationContext(FallbackFactoryTestConfig.class);
@Test
void testFallback() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new AnnotationConfigApplicationContext(FallbackTestConfig.class));
}
@Test
public void shouldPassSubLevelFeignClient() {
void testFallbackFactory() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new AnnotationConfigApplicationContext(FallbackFactoryTestConfig.class));
}
@Test
void shouldPassSubLevelFeignClient() {
AnnotationConfigApplicationContext config = new AnnotationConfigApplicationContext();
((DefaultListableBeanFactory) config.getBeanFactory()).setAllowBeanDefinitionOverriding(false);
config.register(TopLevelSubLevelTestConfig.class);
@@ -21,8 +21,7 @@ import java.util.Map;
import feign.Client;
import feign.RequestInterceptor;
import feign.httpclient.ApacheHttpClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@@ -32,8 +31,6 @@ import org.springframework.cloud.openfeign.encoding.FeignAcceptGzipEncodingAutoC
import org.springframework.cloud.openfeign.encoding.FeignAcceptGzipEncodingInterceptor;
import org.springframework.cloud.openfeign.encoding.FeignContentGzipEncodingAutoConfiguration;
import org.springframework.cloud.openfeign.encoding.FeignContentGzipEncodingInterceptor;
import org.springframework.cloud.test.ClassPathExclusions;
import org.springframework.cloud.test.ModifiedClassPathRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -43,12 +40,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Ryan Baxter
* @author Biju Kunjummen
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "ribbon-loadbalancer-{version:\\d.*}.jar" })
public class FeignCompressionTests {
class FeignCompressionTests {
@Test
public void testInterceptors() {
void testInterceptors() {
new ApplicationContextRunner()
.withPropertyValues("feign.compression.response.enabled=true", "feign.compression.request.enabled=true",
"feign.okhttp.enabled=false")
@@ -21,7 +21,7 @@ import java.util.Collection;
import feign.Logger;
import feign.RequestInterceptor;
import org.assertj.core.util.Lists;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -30,10 +30,10 @@ import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat;
public class FeignContextTest {
class FeignContextTest {
@Test
public void getInstanceWithoutAncestors_verifyNullForMissing() {
void getInstanceWithoutAncestors_verifyNullForMissing() {
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
parent.refresh();
@@ -51,7 +51,7 @@ public class FeignContextTest {
}
@Test
public void getInstancesWithoutAncestors_verifyEmptyForMissing() {
void getInstancesWithoutAncestors_verifyEmptyForMissing() {
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
parent.refresh();
@@ -66,7 +66,7 @@ public class FeignContextTest {
}
@Test
public void getInstanceWithoutAncestors() {
void getInstanceWithoutAncestors() {
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
parent.refresh();
@@ -80,7 +80,7 @@ public class FeignContextTest {
}
@Test
public void getInstancesWithoutAncestors() {
void getInstancesWithoutAncestors() {
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
parent.refresh();
@@ -18,7 +18,7 @@ package org.springframework.cloud.openfeign;
import feign.Response;
import feign.codec.ErrorDecoder;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -30,10 +30,10 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Michael Cramer
*/
public class FeignErrorDecoderFactoryTests {
class FeignErrorDecoderFactoryTests {
@Test
public void testNoDefaultFactory() {
void testNoDefaultFactory() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration1.class);
String[] beanNamesForType = context.getBeanNamesForType(FeignErrorDecoderFactory.class);
assertThat(beanNamesForType).isEmpty();
@@ -41,7 +41,7 @@ public class FeignErrorDecoderFactoryTests {
}
@Test
public void testCustomErrorDecoderFactory() {
void testCustomErrorDecoderFactory() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration2.class);
FeignErrorDecoderFactory errorDecoderFactory = context.getBean(FeignErrorDecoderFactory.class);
assertThat(errorDecoderFactory).isNotNull();
@@ -52,7 +52,7 @@ public class FeignErrorDecoderFactoryTests {
}
@Test
public void testCustomErrorDecoderFactoryNotOverwritingErrorDecoder() {
void testCustomErrorDecoderFactoryNotOverwritingErrorDecoder() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration3.class);
FeignErrorDecoderFactory errorDecoderFactory = context.getBean(FeignErrorDecoderFactory.class);
assertThat(errorDecoderFactory).isNotNull();
@@ -22,14 +22,12 @@ import feign.httpclient.ApacheHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.cloud.test.ClassPathExclusions;
import org.springframework.cloud.test.ModifiedClassPathRunner;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@@ -37,7 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Nguyen Ky Thanh
*/
public class FeignHttpClient5ConfigurationTests {
class FeignHttpClient5ConfigurationTests {
private static void verifyHc4BeansAvailable(ConfigurableApplicationContext context) {
org.apache.http.impl.client.CloseableHttpClient httpClient4 = context
@@ -59,62 +57,55 @@ public class FeignHttpClient5ConfigurationTests {
assertThat(client).isInstanceOf(ApacheHttp5Client.class);
}
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions("ribbon-loadbalancer-{version:\\d.*}.jar")
public static class WithoutLoadBalancerInClasspath {
@Test
void verifyHttpClient5AutoConfig() {
ConfigurableApplicationContext context = new SpringApplicationBuilder()
.properties("feign.httpclient.hc5.enabled=true", "feign.httpclient.enabled=false")
.web(WebApplicationType.NONE).sources(HttpClientConfiguration.class, FeignAutoConfiguration.class)
.run();
@Test
public void verifyHttpClient5AutoConfig() {
ConfigurableApplicationContext context = new SpringApplicationBuilder()
.properties("feign.httpclient.hc5.enabled=true", "feign.httpclient.enabled=false")
.web(WebApplicationType.NONE).sources(HttpClientConfiguration.class, FeignAutoConfiguration.class)
.run();
verifyHc5BeansAvailable(context);
verifyHc5BeansAvailable(context);
if (context != null) {
context.close();
}
if (context != null) {
context.close();
}
@Test
public void hc5ShouldWinIfTheBothVersionsAvailable() {
ConfigurableApplicationContext context = new SpringApplicationBuilder()
.properties("feign.httpclient.hc5.enabled=true", "feign.httpclient.enabled=true")
.web(WebApplicationType.NONE).sources(HttpClientConfiguration.class, FeignAutoConfiguration.class)
.run();
Client client = context.getBean(Client.class);
assertThat(client).isInstanceOf(ApacheHttp5Client.class);
if (context != null) {
context.close();
}
}
@Test
public void hc4ShouldBeTheDefaultIfHc5NotEnabled() {
ConfigurableApplicationContext context = new SpringApplicationBuilder()
.properties("feign.httpclient.hc5.enabled=false", "feign.httpclient.enabled=true")
.web(WebApplicationType.NONE).sources(HttpClientConfiguration.class, FeignAutoConfiguration.class)
.run();
verifyHc4BeansAvailable(context);
if (context != null) {
context.close();
}
}
}
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "ribbon-loadbalancer-{version:\\d.*}.jar", "feign-hc5-{version:\\d.*}.jar",
"httpclient5-{version:\\d.*}.jar", "httpcore5-{version:\\d.*}.jar", "httpcore5-h2-{version:\\d.*}.jar" })
public static class WithoutLoadBalancerAndHc5InClasspath {
@Test
void hc5ShouldWinIfTheBothVersionsAvailable() {
ConfigurableApplicationContext context = new SpringApplicationBuilder()
.properties("feign.httpclient.hc5.enabled=true", "feign.httpclient.enabled=true")
.web(WebApplicationType.NONE).sources(HttpClientConfiguration.class, FeignAutoConfiguration.class)
.run();
Client client = context.getBean(Client.class);
assertThat(client).isInstanceOf(ApacheHttp5Client.class);
if (context != null) {
context.close();
}
}
@Test
void hc4ShouldBeTheDefaultIfHc5NotEnabled() {
ConfigurableApplicationContext context = new SpringApplicationBuilder()
.properties("feign.httpclient.hc5.enabled=false", "feign.httpclient.enabled=true")
.web(WebApplicationType.NONE).sources(HttpClientConfiguration.class, FeignAutoConfiguration.class)
.run();
verifyHc4BeansAvailable(context);
if (context != null) {
context.close();
}
}
@ClassPathExclusions({ "feign-hc5-{version:\\d.*}.jar", "httpclient5-{version:\\d.*}.jar",
"httpcore5-{version:\\d.*}.jar", "httpcore5-h2-{version:\\d.*}.jar" })
static class WithoutLoadBalancerAndHc5InClasspath {
@Test
public void hc4ShouldWinEvenHc5ConfigEnabled() {
void hc4ShouldWinEvenHc5ConfigEnabled() {
ConfigurableApplicationContext context = new SpringApplicationBuilder()
.properties("feign.httpclient.hc5.enabled=true").web(WebApplicationType.NONE)
.sources(HttpClientConfiguration.class, FeignAutoConfiguration.class).run();
@@ -127,7 +118,7 @@ public class FeignHttpClient5ConfigurationTests {
}
@Test
public void hc4ShouldBeTheDefault() {
void hc4ShouldBeTheDefault() {
ConfigurableApplicationContext context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
.sources(HttpClientConfiguration.class, FeignAutoConfiguration.class).run();
@@ -26,16 +26,13 @@ import org.apache.http.config.Lookup;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.impl.conn.DefaultHttpClientConnectionOperator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.cloud.test.ClassPathExclusions;
import org.springframework.cloud.test.ModifiedClassPathRunner;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.ReflectionUtils;
@@ -44,28 +41,26 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "ribbon-loadbalancer-{version:\\d.*}.jar" })
public class FeignHttpClientConfigurationTests {
class FeignHttpClientConfigurationTests {
private ConfigurableApplicationContext context;
@Before
public void setUp() {
@BeforeEach
void setUp() {
this.context = new SpringApplicationBuilder()
.properties("debug=true", "feign.httpclient.disableSslValidation=true").web(WebApplicationType.NONE)
.sources(HttpClientConfiguration.class, FeignAutoConfiguration.class).run();
}
@After
public void tearDown() {
@AfterEach
void tearDown() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void disableSslTest() throws Exception {
void disableSslTest() {
try {
HttpClientConnectionManager connectionManager = this.context.getBean(HttpClientConnectionManager.class);
Lookup<ConnectionSocketFactory> socketFactoryRegistry = getConnectionSocketFactoryLookup(connectionManager);
@@ -48,9 +48,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Olga Maciaszek-Sharma
*/
@SpringBootTest(classes = FeignHttpClientUrlTestsWithRetryableLoadBalancer.TestConfig.class,
webEnvironment = DEFINED_PORT,
value = { "spring.application.name=feignclienturlwithretryableloadbalancertest", "feign.hystrix.enabled=false",
"feign.okhttp.enabled=false", "spring.cloud.loadbalancer.ribbon.enabled=false" })
webEnvironment = DEFINED_PORT, value = { "spring.application.name=feignclienturlwithretryableloadbalancertest",
"feign.hystrix.enabled=false", "feign.okhttp.enabled=false" })
@DirtiesContext
class FeignHttpClientUrlTestsWithRetryableLoadBalancer {
@@ -18,7 +18,7 @@ package org.springframework.cloud.openfeign;
import feign.Logger;
import feign.slf4j.Slf4jLogger;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -30,10 +30,10 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Venil Noronha
*/
public class FeignLoggerFactoryTests {
class FeignLoggerFactoryTests {
@Test
public void testDefaultLogger() {
void testDefaultLogger() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration1.class);
FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class);
assertThat(loggerFactory).isNotNull();
@@ -44,7 +44,7 @@ public class FeignLoggerFactoryTests {
}
@Test
public void testCustomLogger() {
void testCustomLogger() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration2.class);
FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class);
assertThat(loggerFactory).isNotNull();
@@ -55,7 +55,7 @@ public class FeignLoggerFactoryTests {
}
@Test
public void testCustomLoggerFactory() {
void testCustomLoggerFactory() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleConfiguration3.class);
FeignLoggerFactory loggerFactory = context.getBean(FeignLoggerFactory.class);
assertThat(loggerFactory).isNotNull();
@@ -21,17 +21,14 @@ import java.lang.reflect.Field;
import javax.net.ssl.HostnameVerifier;
import okhttp3.OkHttpClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
import org.springframework.cloud.test.ClassPathExclusions;
import org.springframework.cloud.test.ModifiedClassPathRunner;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.ReflectionUtils;
@@ -40,14 +37,12 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "ribbon-loadbalancer-{version:\\d.*}.jar" })
public class FeignOkHttpConfigurationTests {
class FeignOkHttpConfigurationTests {
private ConfigurableApplicationContext context;
@Before
public void setUp() {
@BeforeEach
void setUp() {
this.context = new SpringApplicationBuilder()
.properties("debug=true", "feign.httpclient.disableSslValidation=true", "feign.okhttp.enabled=true",
"feign.httpclient.enabled=false")
@@ -55,18 +50,18 @@ public class FeignOkHttpConfigurationTests {
.run();
}
@After
public void tearDown() {
@AfterEach
void tearDown() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void disableSslTest() throws Exception {
void disableSslTest() {
OkHttpClient httpClient = this.context.getBean(OkHttpClient.class);
HostnameVerifier hostnameVerifier = (HostnameVerifier) this.getField(httpClient, "hostnameVerifier");
assertThat(OkHttpClientFactory.TrustAllHostnames.class.isInstance(hostnameVerifier)).isTrue();
assertThat(hostnameVerifier instanceof OkHttpClientFactory.TrustAllHostnames).isTrue();
}
protected <T> Object getField(Object target, String name) {
@@ -18,8 +18,7 @@ package org.springframework.cloud.openfeign;
import java.util.Objects;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -31,7 +30,6 @@ import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -41,14 +39,13 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Jaesik Kim
* @author Olga Maciaszek-Sharma
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = GzipDecodingTests.Application.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
value = { "spring.application.name=defaultGzipDecoderTests", "feign.compression.response.enabled=true",
"feign.client.config.default.loggerLevel=none", "feign.metrics.enabled=false",
"logging.level.org.springframework.cloud.openfeign=DEBUG" })
@DirtiesContext
public class GzipDecodingTests extends FeignClientFactoryBean {
class GzipDecodingTests extends FeignClientFactoryBean {
@Autowired
FeignContext context;
@@ -56,7 +53,7 @@ public class GzipDecodingTests extends FeignClientFactoryBean {
@Value("${local.server.port}")
private int port = 0;
public GzipDecodingTests() {
GzipDecodingTests() {
setName("tests");
setContextId("test");
}
@@ -67,7 +64,7 @@ public class GzipDecodingTests extends FeignClientFactoryBean {
}
@Test
public void testBodyDecompress() {
void testBodyDecompress() {
ResponseEntity<Hello> response = testClient().getGzipResponse();
assertThat(response).as("response was null").isNotNull();
assertThat(response.getStatusCode()).as("wrong status code").isEqualTo(HttpStatus.OK);
@@ -77,7 +74,7 @@ public class GzipDecodingTests extends FeignClientFactoryBean {
}
@Test
public void testNullBodyDecompress() {
void testNullBodyDecompress() {
ResponseEntity<Hello> response = testClient().getNullResponse();
assertThat(response).as("response was null").isNotNull();
assertThat(response.getStatusCode()).as("wrong status code").isEqualTo(HttpStatus.OK);
@@ -87,7 +84,7 @@ public class GzipDecodingTests extends FeignClientFactoryBean {
}
@Test
public void testCharsetDecompress() {
void testCharsetDecompress() {
ResponseEntity<Hello> response = testClient().getUtf8Response();
assertThat(response).as("response was null").isNotNull();
assertThat(response.getStatusCode()).as("wrong status code").isEqualTo(HttpStatus.OK);
@@ -21,8 +21,8 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -37,7 +37,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -46,12 +45,12 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
* @author Olga Maciaszek-Sharma
* @author Szymon Linowski
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringDecoderTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT,
value = { "spring.application.name=springdecodertest", "spring.jmx.enabled=false" })
@DirtiesContext
public class SpringDecoderTests extends FeignClientFactoryBean {
class SpringDecoderTests extends FeignClientFactoryBean {
@Autowired
FeignContext context;
@@ -59,7 +58,7 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
@LocalServerPort
private int port = 0;
public SpringDecoderTests() {
SpringDecoderTests() {
setName("test");
setContextId("test");
}
@@ -75,7 +74,7 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
}
@Test
public void testResponseEntity() {
void testResponseEntity() {
ResponseEntity<Hello> response = testClient().getHelloResponse();
assertThat(response).as("response was null").isNotNull();
assertThat(response.getStatusCode()).as("wrong status code").isEqualTo(HttpStatus.OK);
@@ -85,14 +84,14 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
}
@Test
public void testSimpleType() {
void testSimpleType() {
Hello hello = testClient().getHello();
assertThat(hello).as("hello was null").isNotNull();
assertThat(hello).as("first hello didn't match").isEqualTo(new Hello("hello world 1"));
}
@Test
public void testUserParameterizedTypeDecode() {
void testUserParameterizedTypeDecode() {
List<Hello> hellos = testClient().getHellos();
assertThat(hellos).as("hellos was null").isNotNull();
assertThat(hellos.size()).as("hellos was not the right size").isEqualTo(2);
@@ -100,7 +99,7 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
}
@Test
public void testSimpleParameterizedTypeDecode() {
void testSimpleParameterizedTypeDecode() {
List<String> hellos = testClient().getHelloStrings();
assertThat(hellos).as("hellos was null").isNotNull();
assertThat(hellos.size()).as("hellos was not the right size").isEqualTo(2);
@@ -109,7 +108,7 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
@Test
@SuppressWarnings("unchecked")
public void testWildcardTypeDecode() {
void testWildcardTypeDecode() {
ResponseEntity<?> wildcard = testClient().getWildcard();
assertThat(wildcard).as("wildcard was null").isNotNull();
assertThat(wildcard.getStatusCode()).as("wrong status code").isEqualTo(HttpStatus.OK);
@@ -121,7 +120,7 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
}
@Test
public void testResponseEntityVoid() {
void testResponseEntityVoid() {
ResponseEntity<Void> response = testClient().getHelloVoid();
assertThat(response).as("response was null").isNotNull();
List<String> headerVals = response.getHeaders().get("x-test-header");
@@ -131,13 +130,13 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
assertThat(header).as("header was wrong").isEqualTo("myval");
}
@Test(expected = RuntimeException.class)
public void test404() {
testClient().getNotFound();
@Test
void test404() {
Assertions.assertThatExceptionOfType(RuntimeException.class).isThrownBy(() -> testClient().getNotFound());
}
@Test
public void testDecodes404() {
void testDecodes404() {
final ResponseEntity<String> response = testClient(true).getNotFound();
assertThat(response).as("response was null").isNotNull();
assertThat(response.getBody()).as("response body was not null").isNull();
@@ -145,7 +144,7 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
@Test
// Issue: https://github.com/spring-cloud/spring-cloud-openfeign/issues/456
public void testResponseEntityHeaders() {
void testResponseEntityHeaders() {
ResponseEntity<String> response = testClient().getContentType();
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON);
}
@@ -182,10 +181,10 @@ public class SpringDecoderTests extends FeignClientFactoryBean {
private String message;
public Hello() {
Hello() {
}
public Hello(String message) {
Hello(String message) {
this.message = message;
}
@@ -21,8 +21,7 @@ import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.Objects;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -38,7 +37,6 @@ 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.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -52,7 +50,6 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Halvdan Hoem Grelland
* @author Aaron Whiteside
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = BeansFeignClientTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT,
value = { "spring.application.name=feignclienttest",
"logging.level.org.springframework.cloud.openfeign.valid=DEBUG", "feign.httpclient.enabled=false",
@@ -78,13 +75,13 @@ public class BeansFeignClientTests {
private TestClient buildByBuilder;
@Test
public void testAnnotations() {
void testAnnotations() {
Map<String, Object> beans = this.context.getBeansWithAnnotation(FeignClient.class);
assertThat(beans.containsKey(TestClient.class.getName())).as("Wrong clients: " + beans).isTrue();
}
@Test
public void testClient() {
void testClient() {
assertThat(this.testClient).as("testClient was null").isNotNull();
assertThat(this.extraClient).as("extraClient was null").isNotNull();
assertThat(Proxy.isProxyClass(this.testClient.getClass())).as("testClient is not a java Proxy").isTrue();
@@ -93,7 +90,7 @@ public class BeansFeignClientTests {
}
@Test
public void extraClient() {
void extraClient() {
assertThat(this.extraClient).as("extraClient was null").isNotNull();
assertThat(Proxy.isProxyClass(this.extraClient.getClass())).as("extraClient is not a java Proxy").isTrue();
InvocationHandler invocationHandler = Proxy.getInvocationHandler(this.extraClient);
@@ -101,7 +98,7 @@ public class BeansFeignClientTests {
}
@Test
public void buildByBuilder() {
void buildByBuilder() {
assertThat(this.buildByBuilder).as("buildByBuilder was null").isNotNull();
assertThat(Proxy.isProxyClass(this.buildByBuilder.getClass())).as("buildByBuilder is not a java Proxy")
.isTrue();
@@ -132,10 +129,10 @@ public class BeansFeignClientTests {
private String message;
public Hello() {
Hello() {
}
public Hello(String message) {
Hello(String message) {
this.message = message;
}
@@ -20,11 +20,10 @@ import java.util.function.Function;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -43,7 +42,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.SocketUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -53,11 +51,10 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = CircuitBreakerTests.Application.class, webEnvironment = WebEnvironment.DEFINED_PORT, value = {
"spring.application.name=springcircuittest", "spring.jmx.enabled=false", "feign.circuitbreaker.enabled=true" })
@DirtiesContext
public class CircuitBreakerTests {
class CircuitBreakerTests {
@Autowired
MyCircuitBreaker myCircuitBreaker;
@@ -69,22 +66,22 @@ public class CircuitBreakerTests {
TestClientWithFactory testClientWithFactory;
@BeforeAll
public static void beforeClass() {
static void beforeClass() {
System.setProperty("server.port", String.valueOf(SocketUtils.findAvailableTcpPort()));
}
@AfterAll
public static void afterClass() {
static void afterClass() {
System.clearProperty("server.port");
}
@Before
public void setup() {
@BeforeEach
void setup() {
this.myCircuitBreaker.clear();
}
@Test
public void testSimpleTypeWithFallback() {
void testSimpleTypeWithFallback() {
Hello hello = testClient.getHello();
assertThat(hello).as("hello was null").isNotNull();
@@ -93,12 +90,12 @@ public class CircuitBreakerTests {
}
@Test
public void test404WithFallback() {
void test404WithFallback() {
assertThat(testClient.getException()).isEqualTo("Fixed response");
}
@Test
public void testSimpleTypeWithFallbackFactory() {
void testSimpleTypeWithFallbackFactory() {
Hello hello = testClientWithFactory.getHello();
assertThat(hello).as("hello was null").isNotNull();
@@ -107,7 +104,7 @@ public class CircuitBreakerTests {
}
@Test
public void test404WithFallbackFactory() {
void test404WithFallbackFactory() {
assertThat(testClientWithFactory.getException()).isEqualTo("Fixed response");
}
@@ -18,8 +18,7 @@ package org.springframework.cloud.openfeign.encoding;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -39,7 +38,6 @@ import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -51,15 +49,14 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
*/
@SpringBootTest(classes = FeignAcceptEncodingTests.Application.class, webEnvironment = RANDOM_PORT,
value = { "feign.compression.response.enabled=true" })
@RunWith(SpringRunner.class)
@DirtiesContext
public class FeignAcceptEncodingTests {
class FeignAcceptEncodingTests {
@Autowired
private InvoiceClient invoiceClient;
@Test
public void compressedResponse() {
void compressedResponse() {
// when
final ResponseEntity<List<Invoice>> invoices = this.invoiceClient.getInvoices();
@@ -18,8 +18,7 @@ package org.springframework.cloud.openfeign.encoding;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -38,7 +37,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -49,15 +47,14 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Jakub Narloch
*/
@SpringBootTest(classes = FeignContentEncodingTests.Application.class, webEnvironment = RANDOM_PORT,
value = { "feign.compression.request.enabled=true", "ribbon.OkToRetryOnAllOperations=false" })
@RunWith(SpringJUnit4ClassRunner.class)
public class FeignContentEncodingTests {
value = { "feign.compression.request.enabled=true" })
class FeignContentEncodingTests {
@Autowired
private InvoiceClient invoiceClient;
@Test
public void compressedResponse() {
void compressedResponse() {
// given
final List<Invoice> invoices = Invoices.createInvoiceList(50);
@@ -19,8 +19,7 @@ package org.springframework.cloud.openfeign.encoding;
import java.util.List;
import java.util.Optional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -45,7 +44,6 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.web.config.EnableSpringDataWebSupport;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -58,14 +56,13 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
*/
@SpringBootTest(classes = FeignPageableEncodingTests.Application.class, webEnvironment = RANDOM_PORT,
value = { "feign.compression.request.enabled=true", "feign.autoconfiguration.jackson.enabled=true" })
@RunWith(SpringJUnit4ClassRunner.class)
public class FeignPageableEncodingTests {
class FeignPageableEncodingTests {
@Autowired
private InvoiceClient invoiceClient;
@Test
public void testPageable() {
void testPageable() {
// given
Pageable pageable = PageRequest.of(0, 10, Sort.Direction.ASC, "sortProperty");
@@ -87,7 +84,7 @@ public class FeignPageableEncodingTests {
}
@Test
public void testPageableWithDescDirection() {
void testPageableWithDescDirection() {
// given
Pageable pageable = PageRequest.of(0, 10, Sort.Direction.DESC, "sortProperty");
@@ -113,7 +110,7 @@ public class FeignPageableEncodingTests {
}
@Test
public void testPageableWithMultipleSort() {
void testPageableWithMultipleSort() {
// given
Pageable pageable = PageRequest.of(0, 10,
Sort.by(Sort.Order.desc("sortProperty1"), Sort.Order.asc("sortProperty2")));
@@ -143,7 +140,7 @@ public class FeignPageableEncodingTests {
}
@Test
public void testPageableWithoutSort() {
void testPageableWithoutSort() {
// given
Pageable pageable = PageRequest.of(0, 10);
@@ -162,7 +159,7 @@ public class FeignPageableEncodingTests {
}
@Test
public void testPageableWithoutSortWithBody() {
void testPageableWithoutSortWithBody() {
// given
Pageable pageable = PageRequest.of(0, 10);
@@ -184,7 +181,7 @@ public class FeignPageableEncodingTests {
}
@Test
public void testPageableWithBody() {
void testPageableWithBody() {
// given
Pageable pageable = PageRequest.of(0, 10,
Sort.by(Sort.Order.desc("sortProperty1"), Sort.Order.asc("sortProperty2")));
@@ -221,7 +218,7 @@ public class FeignPageableEncodingTests {
}
@Test
public void testUnpagedWithBody() {
void testUnpagedWithBody() {
// given
Pageable unpaged = Pageable.unpaged();
@@ -242,7 +239,7 @@ public class FeignPageableEncodingTests {
}
@Test
public void testSortWithBody() {
void testSortWithBody() {
// given
Sort sort = Sort.by(Sort.Order.desc("amount"));
@@ -17,14 +17,12 @@
package org.springframework.cloud.openfeign.encoding.proto;
import feign.RequestTemplate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
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;
import static feign.Request.HttpMethod.POST;
@@ -34,12 +32,11 @@ import static feign.Request.HttpMethod.POST;
*
* @author ScienJus
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions("protobuf-*.jar")
public class ProtobufNotInClasspathTest {
class ProtobufNotInClasspathTest {
@Test
public void testEncodeWhenProtobufNotInClasspath() {
void testEncodeWhenProtobufNotInClasspath() {
ObjectFactory<HttpMessageConverters> converters = () -> new HttpMessageConverters(
new StringHttpMessageConverter());
RequestTemplate requestTemplate = new RequestTemplate();
@@ -18,7 +18,6 @@ package org.springframework.cloud.openfeign.encoding.proto;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
@@ -35,12 +34,12 @@ 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.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentMatchers;
import org.mockito.BDDMockito;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;
import org.springframework.beans.factory.ObjectFactory;
@@ -58,8 +57,8 @@ import static org.assertj.core.api.Assertions.fail;
*
* @author ScienJus
*/
@RunWith(MockitoJUnitRunner.class)
public class ProtobufSpringEncoderTest {
@ExtendWith(MockitoExtension.class)
class ProtobufSpringEncoderTest {
@Mock
private HttpClient httpClient;
@@ -70,7 +69,7 @@ public class ProtobufSpringEncoderTest {
.setMsg("Erlang/OTP 最初是爱立信为开发电信设备系统设计的编程语言平台," + "电信设备(路由器、接入网关、…)典型设计是通过背板连接主控板卡与多块业务板卡的分布式系统。").build();
@Test
public void testProtobuf() throws IOException {
void testProtobuf() throws IOException {
// protobuf convert to request by feign and ProtobufHttpMessageConverter
RequestTemplate requestTemplate = newRequestTemplate();
newEncoder().encode(this.request, Request.class, requestTemplate);
@@ -84,7 +83,7 @@ public class ProtobufSpringEncoderTest {
}
@Test
public void testProtobufWithCharsetWillFail() throws IOException, URISyntaxException {
void testProtobufWithCharsetWillFail() throws IOException {
// protobuf convert to request by feign and ProtobufHttpMessageConverter
RequestTemplate requestTemplate = newRequestTemplate();
newEncoder().encode(this.request, Request.class, requestTemplate);
@@ -18,8 +18,7 @@ package org.springframework.cloud.openfeign.hateoas;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -31,7 +30,6 @@ import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.PagedModel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -42,15 +40,14 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Hector Espert
*/
@SpringBootTest(classes = FeignHalApplication.class, webEnvironment = RANDOM_PORT, value = "debug=true")
@RunWith(SpringRunner.class)
@DirtiesContext
public class FeignHalTests {
class FeignHalTests {
@Autowired
private FeignHalClient feignHalClient;
@Test
public void testEntityModel() {
void testEntityModel() {
EntityModel<MarsRover> entity = feignHalClient.entity();
assertThat(entity).isNotNull();
@@ -65,7 +62,7 @@ public class FeignHalTests {
}
@Test
public void testCollectionModel() {
void testCollectionModel() {
CollectionModel<MarsRover> collectionModel = feignHalClient.collection();
assertThat(collectionModel).isNotNull();
assertThat(collectionModel).isNotEmpty();
@@ -84,7 +81,7 @@ public class FeignHalTests {
}
@Test
public void testPagedModel() {
void testPagedModel() {
PagedModel<MarsRover> paged = feignHalClient.paged();
assertThat(paged).isNotNull();
assertThat(paged).isNotEmpty();
@@ -21,7 +21,7 @@ import org.springframework.beans.factory.annotation.Value;
/**
* @author Hector Espert
*/
public class FeignHalRibbonConfiguration {
public class FeignHalConfiguration {
@Value("${local.server.port}")
private int serverPort = 0;
@@ -35,25 +35,25 @@ public class FeignHalController {
public EntityModel<MarsRover> getEntity() {
MarsRover marsRover = new MarsRover();
marsRover.setName("Sojourner");
Link link = new Link("/entity", "self");
return new EntityModel<>(marsRover, link);
Link link = Link.of("/entity", "self");
return EntityModel.of(marsRover, link);
}
@GetMapping("/collection")
public CollectionModel<MarsRover> getCollection() {
MarsRover marsRover = new MarsRover();
marsRover.setName("Opportunity");
Link link = new Link("/collection", "self");
return new CollectionModel<>(Collections.singleton(marsRover), link);
Link link = Link.of("/collection", "self");
return CollectionModel.of(Collections.singleton(marsRover), link);
}
@GetMapping("/paged")
public CollectionModel<MarsRover> getPaged() {
MarsRover marsRover = new MarsRover();
marsRover.setName("Curiosity");
Link link = new Link("/paged", "self");
Link link = Link.of("/paged", "self");
PagedModel.PageMetadata metadata = new PagedModel.PageMetadata(1, 1, 1);
return new PagedModel<>(Collections.singleton(marsRover), metadata, link);
return PagedModel.of(Collections.singleton(marsRover), metadata, link);
}
}
@@ -16,9 +16,7 @@
package org.springframework.cloud.openfeign.invalid;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.jupiter.api.Test;
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
@@ -31,17 +29,16 @@ import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.GetMapping;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Dave Syer
* @author Szymon Linowski
*/
public class FeignClientValidationTests {
@Rule
public ExpectedException expected = ExpectedException.none();
class FeignClientValidationTests {
@Test
public void testServiceIdAndValue() {
void testServiceIdAndValue() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
LoadBalancerAutoConfiguration.class, NameAndServiceIdConfiguration.class);
assertThat(context.getBean(NameAndServiceIdConfiguration.Client.class)).isNotNull();
@@ -49,7 +46,7 @@ public class FeignClientValidationTests {
}
@Test
public void testDuplicatedClientNames() {
void testDuplicatedClientNames() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.setAllowBeanDefinitionOverriding(false);
context.register(LoadBalancerAutoConfiguration.class, DuplicatedFeignClientNamesConfiguration.class);
@@ -60,9 +57,10 @@ public class FeignClientValidationTests {
}
@Test
public void testNotLegalHostname() {
this.expected.expectMessage("not legal hostname (foo_bar)");
new AnnotationConfigApplicationContext(BadHostnameConfiguration.class);
void testNotLegalHostname() {
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> new AnnotationConfigApplicationContext(BadHostnameConfiguration.class))
.withMessage("Service id not legal hostname (foo_bar)");
}
@Configuration(proxyBeanMethods = false)
@@ -31,6 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
import feign.Client;
import feign.Request;
import feign.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
@@ -71,16 +72,21 @@ import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class FeignBlockingLoadBalancerClientTests {
private Client delegate = mock(Client.class);
private final Client delegate = mock(Client.class);
private BlockingLoadBalancerClient loadBalancerClient = mock(BlockingLoadBalancerClient.class);
private final BlockingLoadBalancerClient loadBalancerClient = mock(BlockingLoadBalancerClient.class);
private final LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class);
private final LoadBalancerProperties loadBalancerProperties = new LoadBalancerProperties();
private FeignBlockingLoadBalancerClient feignBlockingLoadBalancerClient = new FeignBlockingLoadBalancerClient(
delegate, loadBalancerClient, loadBalancerProperties, loadBalancerClientFactory);
private final FeignBlockingLoadBalancerClient feignBlockingLoadBalancerClient = new FeignBlockingLoadBalancerClient(
delegate, loadBalancerClient, loadBalancerClientFactory);
@BeforeEach
void setUp() {
when(loadBalancerClientFactory.getProperties(any(String.class))).thenReturn(loadBalancerProperties);
}
@Test
void shouldExtractServiceIdFromRequestUrl() throws IOException {
@@ -76,23 +76,24 @@ import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class RetryableFeignBlockingLoadBalancerClientTests {
private Client delegate = mock(Client.class);
private final Client delegate = mock(Client.class);
private LoadBalancedRetryFactory retryFactory = mock(LoadBalancedRetryFactory.class);
private final LoadBalancedRetryFactory retryFactory = mock(LoadBalancedRetryFactory.class);
private BlockingLoadBalancerClient loadBalancerClient = mock(BlockingLoadBalancerClient.class);
private final BlockingLoadBalancerClient loadBalancerClient = mock(BlockingLoadBalancerClient.class);
private final LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class);
private LoadBalancerProperties properties = new LoadBalancerProperties();
private final LoadBalancerProperties properties = new LoadBalancerProperties();
private RetryableFeignBlockingLoadBalancerClient feignBlockingLoadBalancerClient = new RetryableFeignBlockingLoadBalancerClient(
private final RetryableFeignBlockingLoadBalancerClient feignBlockingLoadBalancerClient = new RetryableFeignBlockingLoadBalancerClient(
delegate, loadBalancerClient, retryFactory, properties, loadBalancerClientFactory);
private ServiceInstance serviceInstance = new DefaultServiceInstance("test-a", "test", "testhost", 80, false);
private final ServiceInstance serviceInstance = new DefaultServiceInstance("test-a", "test", "testhost", 80, false);
@BeforeEach
void setUp() {
when(loadBalancerClientFactory.getProperties(any(String.class))).thenReturn(properties);
when(retryFactory.createRetryPolicy(any(), eq(loadBalancerClient)))
.thenReturn(new BlockingLoadBalancedRetryPolicy(properties));
when(loadBalancerClient.choose(eq("test"), any())).thenReturn(serviceInstance);
@@ -21,9 +21,9 @@ import java.util.Map;
import feign.Request.HttpMethod;
import feign.RequestTemplate;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
@@ -32,55 +32,60 @@ import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedExc
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasSize;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* @author João Pedro Evangelista
* @author Tim Ysewyn
* @author Szymon Linowski
*/
public class OAuth2FeignRequestInterceptorTests {
class OAuth2FeignRequestInterceptorTests {
private OAuth2FeignRequestInterceptor oAuth2FeignRequestInterceptor;
private RequestTemplate requestTemplate;
@Before
public void setUp() {
@BeforeEach
void setUp() {
oAuth2FeignRequestInterceptor = new OAuth2FeignRequestInterceptor(new MockOAuth2ClientContext("Fancy"),
new BaseOAuth2ProtectedResourceDetails());
requestTemplate = new RequestTemplate().method(HttpMethod.GET);
}
@Test
public void applyAuthorizationHeader() {
void applyAuthorizationHeader() {
oAuth2FeignRequestInterceptor.apply(requestTemplate);
Map<String, Collection<String>> headers = requestTemplate.headers();
Assert.assertTrue("RequestTemplate must have a Authorization header", headers.containsKey("Authorization"));
Assert.assertThat("Authorization must have a extract of Fancy", headers.get("Authorization"),
contains("Bearer Fancy"));
assertThat(headers.containsKey("Authorization")).describedAs("RequestTemplate must have a Authorization header")
.isTrue();
Assertions.assertThat(headers.get("Authorization")).describedAs("Authorization must have a extract of Fancy")
.contains("Bearer Fancy");
}
@Test(expected = OAuth2AccessDeniedException.class)
public void tryToAcquireToken() {
@Test
void tryToAcquireToken() {
oAuth2FeignRequestInterceptor = new OAuth2FeignRequestInterceptor(new DefaultOAuth2ClientContext(),
new BaseOAuth2ProtectedResourceDetails());
OAuth2AccessToken oAuth2AccessToken = oAuth2FeignRequestInterceptor.getToken();
Assert.assertTrue(oAuth2AccessToken.getValue() + " Must be null", oAuth2AccessToken.getValue() == null);
Assertions.assertThatExceptionOfType(OAuth2AccessDeniedException.class)
.isThrownBy(() -> oAuth2FeignRequestInterceptor.getToken()).withMessage(
"Unable to obtain a new access token for resource 'null'. The provider manager is not configured to support it.");
}
@Test
public void configureAccessTokenProvider() {
void configureAccessTokenProvider() {
OAuth2AccessToken mockedToken = new MockOAuth2AccessToken("MOCKED_TOKEN");
oAuth2FeignRequestInterceptor.setAccessTokenProvider(new MockAccessTokenProvider(mockedToken));
Assert.assertEquals("Should return same mocked token instance", mockedToken,
oAuth2FeignRequestInterceptor.acquireAccessToken());
assertThat(oAuth2FeignRequestInterceptor.acquireAccessToken())
.describedAs("Should return same mocked token instance").isEqualTo(mockedToken);
}
@Test
public void applyAuthorizationHeaderOnlyOnce() {
void applyAuthorizationHeaderOnlyOnce() {
OAuth2ClientContext oAuth2ClientContext = mock(OAuth2ClientContext.class);
when(oAuth2ClientContext.getAccessToken()).thenReturn(new MockOAuth2AccessToken("MOCKED_TOKEN"));
@@ -103,10 +108,11 @@ public class OAuth2FeignRequestInterceptorTests {
oAuth2FeignRequestInterceptor.apply(requestTemplate);
Map<String, Collection<String>> headers = requestTemplate.headers();
Assert.assertTrue("RequestTemplate must have a Authorization header", headers.containsKey("Authorization"));
Assert.assertThat("Authorization must have a extract of Fancy", headers.get("Authorization"), hasSize(1));
Assert.assertThat("Authorization must have a extract of Fancy", headers.get("Authorization"),
contains("Bearer Fancy"));
assertThat(headers.containsKey("Authorization")).describedAs("RequestTemplate must have a Authorization header")
.isTrue();
assertThat(headers.get("Authorization")).describedAs("Authorization must have a extract of Fancy").hasSize(1);
assertThat(headers.get("Authorization")).describedAs("Authorization must have a extract of Fancy")
.contains("Bearer Fancy");
}
}
@@ -18,9 +18,8 @@ package org.springframework.cloud.openfeign.support;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -31,7 +30,6 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.openfeign.support.FeignHttpClientProperties.Hc5Properties.DEFAULT_SOCKET_TIMEOUT;
@@ -41,21 +39,20 @@ import static org.springframework.cloud.openfeign.support.FeignHttpClientPropert
* @author Ryan Baxter
* @author Nguyen Ky Thanh
*/
@RunWith(SpringRunner.class)
@DirtiesContext
public class FeignHttpClientPropertiesTests {
class FeignHttpClientPropertiesTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@After
public void clear() {
@AfterEach
void clear() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void testDefaults() {
void testDefaults() {
setupContext();
assertThat(getProperties().getConnectionTimeout())
.isEqualTo(FeignHttpClientProperties.DEFAULT_CONNECTION_TIMEOUT);
@@ -73,7 +70,7 @@ public class FeignHttpClientPropertiesTests {
}
@Test
public void testCustomization() {
void testCustomization() {
TestPropertyValues
.of("feign.httpclient.maxConnections=2", "feign.httpclient.connectionTimeout=2",
"feign.httpclient.maxConnectionsPerRoute=2", "feign.httpclient.timeToLive=2",
@@ -16,13 +16,18 @@
package org.springframework.cloud.openfeign.support;
import java.util.ArrayList;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import static org.assertj.core.api.Assertions.assertThat;
@@ -31,6 +36,8 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Ruben Vervaeke
* @author Olga Maciaszek-Sharma
* @author Pedro Mendes
* @author Nikita Konev
*/
public class PageJacksonModuleTests {
@@ -40,6 +47,7 @@ public class PageJacksonModuleTests {
public static void initialize() {
objectMapper = new ObjectMapper();
objectMapper.registerModule(new PageJacksonModule());
objectMapper.registerModule(new SortJacksonModule());
}
@ParameterizedTest
@@ -58,4 +66,40 @@ public class PageJacksonModuleTests {
assertThat(result.getPageable().getPageNumber()).isEqualTo(1);
}
@Test
public void serializeAndDeserializeEmpty() throws JsonProcessingException {
// Given
PageImpl<Object> objects = new PageImpl<>(new ArrayList<>());
String pageJson = objectMapper.writeValueAsString(objects);
// When
Page<?> result = objectMapper.readValue(pageJson, Page.class);
// Then
assertThat(result).isNotNull();
assertThat(result.getTotalElements()).isEqualTo(0);
assertThat(result.getContent()).hasSize(0);
}
@Test
public void serializeAndDeserializeFilledMultiple() throws JsonProcessingException {
// Given
ArrayList<Object> strings0 = new ArrayList<>();
strings0.add("first element");
strings0.add("second element");
PageImpl<Object> objects = new PageImpl<>(strings0, PageRequest.of(6, 2), 100);
assertThat(objects.getContent()).hasSize(2);
assertThat(objects.getPageable().getPageSize()).isEqualTo(2);
String pageJson = objectMapper.writeValueAsString(objects);
// When
Page<?> result = objectMapper.readValue(pageJson, Page.class);
// Then
assertThat(result).isNotNull();
assertThat(result.getTotalElements()).isEqualTo(100);
assertThat(result.getContent()).hasSize(2);
assertThat(result.getContent().get(0)).isEqualTo("first element");
assertThat(result.getContent().get(1)).isEqualTo("second element");
assertThat(result.getPageable().getPageSize()).isEqualTo(2);
assertThat(result.getPageable().getPageNumber()).isEqualTo(6);
}
}
@@ -18,8 +18,7 @@ package org.springframework.cloud.openfeign.support;
import feign.RequestTemplate;
import feign.codec.Encoder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -28,7 +27,6 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -39,11 +37,10 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Charlie Mordant.
* @author Yanming Zhou
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringEncoderTests.Application.class, webEnvironment = RANDOM_PORT,
value = { "spring.application.name=springencodertest", "spring.jmx.enabled=false" })
@DirtiesContext
public class PageableEncoderTests {
class PageableEncoderTests {
public static final int PAGE = 1;
@@ -69,7 +66,7 @@ public class PageableEncoderTests {
}
@Test
public void testPaginationAndSortingRequest() {
void testPaginationAndSortingRequest() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -90,7 +87,7 @@ public class PageableEncoderTests {
}
@Test
public void testPaginationRequest() {
void testPaginationRequest() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -109,7 +106,7 @@ public class PageableEncoderTests {
}
@Test
public void testSortingRequest() {
void testSortingRequest() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -126,7 +123,7 @@ public class PageableEncoderTests {
}
@Test
public void testUnpagedRequest() {
void testUnpagedRequest() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -20,8 +20,7 @@ import java.util.List;
import java.util.Map;
import feign.QueryMapEncoder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -30,7 +29,6 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@@ -40,11 +38,10 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
*
* @author Yanming Zhou
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringEncoderTests.Application.class, webEnvironment = RANDOM_PORT,
value = { "spring.application.name=springencodertest", "spring.jmx.enabled=false" })
@DirtiesContext
public class PageableSpringQueryMapEncoderTests {
class PageableSpringQueryMapEncoderTests {
public static final int PAGE = 1;
@@ -70,7 +67,7 @@ public class PageableSpringQueryMapEncoderTests {
}
@Test
public void testPaginationAndSortingRequest() {
void testPaginationAndSortingRequest() {
QueryMapEncoder encoder = this.context.getInstance("foo", QueryMapEncoder.class);
assertThat(encoder).isNotNull();
@@ -86,7 +83,7 @@ public class PageableSpringQueryMapEncoderTests {
}
@Test
public void testPaginationRequest() {
void testPaginationRequest() {
QueryMapEncoder encoder = this.context.getInstance("foo", QueryMapEncoder.class);
assertThat(encoder).isNotNull();
@@ -102,7 +99,7 @@ public class PageableSpringQueryMapEncoderTests {
}
@Test
public void testSortingRequest() {
void testSortingRequest() {
QueryMapEncoder encoder = this.context.getInstance("foo", QueryMapEncoder.class);
assertThat(encoder).isNotNull();
@@ -116,7 +113,7 @@ public class PageableSpringQueryMapEncoderTests {
}
@Test
public void testUnpagedRequest() {
void testUnpagedRequest() {
QueryMapEncoder encoder = this.context.getInstance("foo", QueryMapEncoder.class);
assertThat(encoder).isNotNull();
@@ -26,8 +26,8 @@ import java.util.List;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -52,7 +52,6 @@ import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@@ -70,12 +69,12 @@ import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE;
* @author Olga Maciaszek-Sharma
* @author Ahmad Mozafarnia
* @author Can Bezmen
* @author Szymon Linowski
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringEncoderTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT,
value = { "spring.application.name=springencodertest", "spring.jmx.enabled=false" })
@DirtiesContext
public class SpringEncoderTests {
class SpringEncoderTests {
@Autowired
private FeignContext context;
@@ -92,7 +91,7 @@ public class SpringEncoderTests {
private GenericHttpMessageConverter<?> myGenericConverter;
@Test
public void testCustomHttpMessageConverter() {
void testCustomHttpMessageConverter() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -112,7 +111,7 @@ public class SpringEncoderTests {
// gh-225
@Test
public void testCustomGenericHttpMessageConverter() {
void testCustomGenericHttpMessageConverter() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -135,7 +134,7 @@ public class SpringEncoderTests {
}
@Test
public void testBinaryData() {
void testBinaryData() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
@@ -147,19 +146,21 @@ public class SpringEncoderTests {
.isEqualTo(APPLICATION_OCTET_STREAM_VALUE);
}
@Test(expected = EncodeException.class)
public void testMultipartFile1() {
@Test
void testMultipartFile1() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
MultipartFile multipartFile = new MockMultipartFile("test_multipart_file", "hi".getBytes());
encoder.encode(multipartFile, MultipartFile.class, request);
Assertions.assertThatExceptionOfType(EncodeException.class)
.isThrownBy(() -> encoder.encode(multipartFile, MultipartFile.class, request));
}
// gh-105, gh-107
@Test
public void testMultipartFile2() {
void testMultipartFile2() {
Encoder encoder = this.context.getInstance("foo", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -182,7 +183,7 @@ public class SpringEncoderTests {
}
@Test
public void testFromURLEncodedValue() {
void testFromURLEncodedValue() {
Encoder encoder = context.getInstance("formUrlEncoded", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -193,7 +194,7 @@ public class SpringEncoderTests {
}
@Test
public void testNoCharsetForBinaryFiles() {
void testNoCharsetForBinaryFiles() {
Encoder encoder = context.getInstance("test", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -206,7 +207,7 @@ public class SpringEncoderTests {
}
@Test
public void testUTF8CharsetForTextFiles() {
void testUTF8CharsetForTextFiles() {
Encoder encoder = context.getInstance("test", Encoder.class);
assertThat(encoder).isNotNull();
RequestTemplate request = new RequestTemplate();
@@ -31,8 +31,8 @@ import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import feign.MethodMetadata;
import feign.Param;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.cloud.openfeign.CollectionFormat;
import org.springframework.cloud.openfeign.SpringQueryMap;
@@ -45,6 +45,7 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.MatrixVariable;
@@ -61,9 +62,12 @@ import org.springframework.web.multipart.MultipartFile;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
import static feign.CollectionFormat.CSV;
import static feign.CollectionFormat.SSV;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assume.assumeTrue;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
/**
* @author chadjaros
@@ -72,8 +76,10 @@ import static org.junit.Assume.assumeTrue;
* @author Aaron Whiteside
* @author Artyom Romanenko
* @author Olga Maciaszek-Sharma
* @author Szymon Linowski
* @author Sam Kruglov
*/
public class SpringMvcContractTests {
class SpringMvcContractTests {
private static final Class<?> EXECUTABLE_TYPE;
@@ -113,13 +119,13 @@ public class SpringMvcContractTests {
return false;
}
@Before
public void setup() {
@BeforeEach
void setup() {
contract = new SpringMvcContract(Collections.emptyList(), getConversionService());
}
@Test
public void testProcessAnnotationOnMethod_Simple() throws Exception {
void testProcessAnnotationOnMethod_Simple() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -131,7 +137,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotationOnMethod_Simple_RegexPathVariable() throws Exception {
void testProcessAnnotationOnMethod_Simple_RegexPathVariable() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTestWithDigitalId", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -141,7 +147,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotationOnMethod_Simple_SlashEncoded() throws Exception {
void testProcessAnnotationOnMethod_Simple_SlashEncoded() throws Exception {
contract = new SpringMvcContract(Collections.emptyList(), getConversionService(), false);
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest", String.class);
@@ -153,7 +159,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_Simple() throws Exception {
void testProcessAnnotations_Simple() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -166,7 +172,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_SimpleGetMapping() throws Exception {
void testProcessAnnotations_SimpleGetMapping() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("getMappingTest", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -179,24 +185,20 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_Class_AnnotationsGetSpecificTest() throws Exception {
Method method = TestTemplate_Class_Annotations.class.getDeclaredMethod("getSpecificTest", String.class,
String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo("/prepend/{classId}/test/{testId}");
assertThat(data.template().method()).isEqualTo("GET");
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("classId");
assertThat(data.indexToName().get(1).iterator().next()).isEqualTo("testId");
void testProcessAnnotations_Class_Annotations_RequestMapping() {
assertThatIllegalArgumentException().isThrownBy(() -> {
Method method = TestTemplate_Class_RequestMapping.class.getDeclaredMethod("getSpecificTest", String.class,
String.class);
contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
});
}
@Test
public void testProcessAnnotations_Class_AnnotationsGetAllTests() throws Exception {
void testProcessAnnotations_Class_AnnotationsGetAllTests() throws Exception {
Method method = TestTemplate_Class_Annotations.class.getDeclaredMethod("getAllTests", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo("/prepend/{classId}");
assertThat(data.template().url()).isEqualTo("/");
assertThat(data.template().method()).isEqualTo("GET");
assertThat(data.indexToName().get(0).iterator().next()).isEqualTo("classId");
@@ -204,19 +206,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_Class_AnnotationsGetAllTests_EncodeSlash() throws Exception {
contract = new SpringMvcContract(Collections.emptyList(), getConversionService(), false);
Method method = TestTemplate_Class_Annotations.class.getDeclaredMethod("getAllTests", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo("/prepend/{classId}");
assertThat(data.template().decodeSlash()).isFalse();
}
@Test
public void testProcessAnnotations_ExtendedInterface() throws Exception {
void testProcessAnnotations_ExtendedInterface() throws Exception {
Method extendedMethod = TestTemplate_Extended.class.getMethod("getAllTests", String.class);
MethodMetadata extendedData = contract.parseAndValidateMetadata(extendedMethod.getDeclaringClass(),
extendedMethod);
@@ -232,23 +222,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_ExtendedInterface_EncodeSlash() throws Exception {
contract = new SpringMvcContract(Collections.emptyList(), getConversionService(), false);
Method extendedMethod = TestTemplate_Extended.class.getMethod("getAllTests", String.class);
MethodMetadata extendedData = contract.parseAndValidateMetadata(extendedMethod.getDeclaringClass(),
extendedMethod);
Method method = TestTemplate_Class_Annotations.class.getDeclaredMethod("getAllTests", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo(extendedData.template().url());
assertThat(data.template().method()).isEqualTo(extendedData.template().method());
assertThat(data.template().decodeSlash()).isFalse();
}
@Test
public void testProcessAnnotations_SimplePost() throws Exception {
void testProcessAnnotations_SimplePost() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("postTest", TestObject.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -260,7 +234,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_SimplePostMapping() throws Exception {
void testProcessAnnotations_SimplePostMapping() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("postMappingTest", TestObject.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -272,19 +246,19 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotationsOnMethod_Advanced() throws Exception {
void testProcessAnnotationsOnMethod_Advanced() throws Exception {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest", String.class, String.class,
Integer.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo("/advanced/test/{id}?amount=" + "{amount}");
assertThat(data.template().url()).isEqualTo("/test/{id}?amount=" + "{amount}");
assertThat(data.template().method()).isEqualTo("PUT");
assertThat(data.template().headers().get("Accept").iterator().next())
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
}
@Test
public void testProcessAnnotationsOnMethod_Advanced_UnknownAnnotation() throws Exception {
void testProcessAnnotationsOnMethod_Advanced_UnknownAnnotation() throws Exception {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest", String.class, String.class,
Integer.class);
contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -293,7 +267,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotationsOnMethod_CollectionFormat() throws NoSuchMethodException {
void testProcessAnnotationsOnMethod_CollectionFormat() throws NoSuchMethodException {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getWithCollectionFormat");
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -302,12 +276,21 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_Advanced() throws Exception {
void processAnnotationOnClass_CollectionFormat() throws NoSuchMethodException {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getWithoutCollectionFormat");
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().collectionFormat()).isEqualTo(CSV);
}
@Test
void testProcessAnnotations_Advanced() throws Exception {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest", String.class, String.class,
Integer.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo("/advanced/test/{id}?amount=" + "{amount}");
assertThat(data.template().url()).isEqualTo("/test/{id}?amount=" + "{amount}");
assertThat(data.template().method()).isEqualTo("PUT");
assertThat(data.template().headers().get("Accept").iterator().next())
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
@@ -322,11 +305,11 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_Aliased() throws Exception {
void testProcessAnnotations_Aliased() throws Exception {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest2", String.class, Integer.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo("/advanced/test2?amount=" + "{amount}");
assertThat(data.template().url()).isEqualTo("/test2?amount=" + "{amount}");
assertThat(data.template().method()).isEqualTo("PUT");
assertThat(data.template().headers().get("Accept").iterator().next())
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
@@ -339,7 +322,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_DateTimeFormatParam() throws Exception {
void testProcessAnnotations_DateTimeFormatParam() throws Exception {
Method method = TestTemplate_DateTimeFormatParameter.class.getDeclaredMethod("getTest", LocalDateTime.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -356,7 +339,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_NumberFormatParam() throws Exception {
void testProcessAnnotations_NumberFormatParam() throws Exception {
Method method = TestTemplate_NumberFormatParameter.class.getDeclaredMethod("getTest", BigDecimal.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -374,18 +357,18 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_Advanced2() throws Exception {
void testProcessAnnotations_Advanced2() throws Exception {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest");
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo("/advanced");
assertThat(data.template().url()).isEqualTo("/");
assertThat(data.template().method()).isEqualTo("GET");
assertThat(data.template().headers().get("Accept").iterator().next())
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
}
@Test
public void testProcessAnnotations_Advanced3() throws Exception {
void testProcessAnnotations_Advanced3() throws Exception {
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest");
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -397,7 +380,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_Advanced3_DecodeSlashFlagNotModified() throws Exception {
void testProcessAnnotations_Advanced3_DecodeSlashFlagNotModified() throws Exception {
contract = new SpringMvcContract(Collections.emptyList(), getConversionService(), false);
Method method = TestTemplate_Simple.class.getDeclaredMethod("getTest");
@@ -409,7 +392,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_ListParams() throws Exception {
void testProcessAnnotations_ListParams() throws Exception {
Method method = TestTemplate_ListParams.class.getDeclaredMethod("getTest", List.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -420,7 +403,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_ListParamsWithoutName() throws Exception {
void testProcessAnnotations_ListParamsWithoutName() throws Exception {
Method method = TestTemplate_ListParamsWithoutName.class.getDeclaredMethod("getTest", List.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -431,7 +414,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_MapParams() throws Exception {
void testProcessAnnotations_MapParams() throws Exception {
Method method = TestTemplate_MapParams.class.getDeclaredMethod("getTest", Map.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -442,7 +425,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessHeaders() throws Exception {
void testProcessHeaders() throws Exception {
Method method = TestTemplate_Headers.class.getDeclaredMethod("getTest", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -452,7 +435,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessHeadersWithoutValues() throws Exception {
void testProcessHeadersWithoutValues() throws Exception {
Method method = TestTemplate_HeadersWithoutValues.class.getDeclaredMethod("getTest", String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -462,15 +445,15 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessAnnotations_Fallback() throws Exception {
void testProcessAnnotations_Fallback() throws Exception {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTestFallback", String.class, String.class,
Integer.class);
assumeTrue("does not have java 8 parameter names", hasJava8ParameterNames(method));
assumeTrue(hasJava8ParameterNames(method), "does not have java 8 parameter names");
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().url()).isEqualTo("/advanced/testfallback/{id}?amount=" + "{amount}");
assertThat(data.template().url()).isEqualTo("/testfallback/{id}?amount=" + "{amount}");
assertThat(data.template().method()).isEqualTo("PUT");
assertThat(data.template().headers().get("Accept").iterator().next())
.isEqualTo(MediaType.APPLICATION_JSON_VALUE);
@@ -484,7 +467,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessHeaderMap() throws Exception {
void testProcessHeaderMap() throws Exception {
Method method = TestTemplate_HeaderMap.class.getDeclaredMethod("headerMap", MultiValueMap.class, String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -495,15 +478,16 @@ public class SpringMvcContractTests {
assertThat(headers.get("aHeader").iterator().next()).isEqualTo("{aHeader}");
}
@Test(expected = IllegalStateException.class)
public void testProcessHeaderMapMoreThanOnce() throws Exception {
@Test
void testProcessHeaderMapMoreThanOnce() throws Exception {
Method method = TestTemplate_HeaderMap.class.getDeclaredMethod("headerMapMoreThanOnce", MultiValueMap.class,
MultiValueMap.class);
contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> contract.parseAndValidateMetadata(method.getDeclaringClass(), method));
}
@Test
public void testProcessQueryMap() throws Exception {
void testProcessQueryMap() throws Exception {
Method method = TestTemplate_QueryMap.class.getDeclaredMethod("queryMap", MultiValueMap.class, String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -515,7 +499,7 @@ public class SpringMvcContractTests {
}
@Test
public void testProcessQueryMapObject() throws Exception {
void testProcessQueryMapObject() throws Exception {
Method method = TestTemplate_QueryMap.class.getDeclaredMethod("queryMapObject", TestObject.class, String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -526,15 +510,16 @@ public class SpringMvcContractTests {
assertThat(params.get("aParam").iterator().next()).isEqualTo("{aParam}");
}
@Test(expected = IllegalStateException.class)
public void testProcessQueryMapMoreThanOnce() throws Exception {
@Test
void testProcessQueryMapMoreThanOnce() throws Exception {
Method method = TestTemplate_QueryMap.class.getDeclaredMethod("queryMapMoreThanOnce", MultiValueMap.class,
MultiValueMap.class);
contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> contract.parseAndValidateMetadata(method.getDeclaringClass(), method));
}
@Test
public void testMatrixVariable_MapParam() throws Exception {
void testMatrixVariable_MapParam() throws Exception {
Method method = TestTemplate_MatrixVariable.class.getDeclaredMethod("matrixVariable", Map.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -547,7 +532,7 @@ public class SpringMvcContractTests {
}
@Test
public void testMatrixVariable_ObjectParam() throws Exception {
void testMatrixVariable_ObjectParam() throws Exception {
Method method = TestTemplate_MatrixVariable.class.getDeclaredMethod("matrixVariableObject", Object.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -557,7 +542,7 @@ public class SpringMvcContractTests {
}
@Test
public void testMatrixVariableWithNoName() throws NoSuchMethodException {
void testMatrixVariableWithNoName() throws NoSuchMethodException {
Method method = TestTemplate_MatrixVariable.class.getDeclaredMethod("matrixVariableNotNamed", Map.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
Map<String, String> testMap = new HashMap<>();
@@ -570,7 +555,7 @@ public class SpringMvcContractTests {
}
@Test
public void testAddingTemplatedParameterWithTheSameKey() throws NoSuchMethodException {
void testAddingTemplatedParameterWithTheSameKey() throws NoSuchMethodException {
Method method = TestTemplate_Advanced.class.getDeclaredMethod("testAddingTemplatedParamForExistingKey",
String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
@@ -579,7 +564,7 @@ public class SpringMvcContractTests {
}
@Test
public void testMultipleRequestPartAnnotations() throws NoSuchMethodException {
void testMultipleRequestPartAnnotations() throws NoSuchMethodException {
Method method = TestTemplate_RequestPart.class.getDeclaredMethod("requestWithMultipleParts",
MultipartFile.class, String.class);
@@ -587,6 +572,24 @@ public class SpringMvcContractTests {
assertThat(data.formParams()).contains("file", "id");
}
@Test
void testSingleCookieAnnotation() throws NoSuchMethodException {
Method method = TestTemplate_Cookies.class.getDeclaredMethod("singleCookie", String.class, String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().headers().get("cookie").iterator().next()).isEqualTo("cookie1={cookie1}");
}
@Test
void testMultipleCookiesAnnotation() throws NoSuchMethodException {
Method method = TestTemplate_Cookies.class.getDeclaredMethod("multipleCookies", String.class, String.class,
String.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);
assertThat(data.template().headers().get("cookie").iterator().next())
.isEqualTo("cookie1={cookie1}; cookie2={cookie2}");
}
private ConversionService getConversionService() {
FormattingConversionServiceFactoryBean conversionServiceFactoryBean = new FormattingConversionServiceFactoryBean();
conversionServiceFactoryBean.afterPropertiesSet();
@@ -616,6 +619,13 @@ public class SpringMvcContractTests {
}
@RequestMapping("/prepend/{classId}")
public interface TestTemplate_Class_RequestMapping {
@RequestMapping(value = "/test/{testId}", method = RequestMethod.GET)
TestObject getSpecificTest(@PathVariable("classId") String classId, @PathVariable("testId") String testId);
}
public interface TestTemplate_Class_Annotations {
@GetMapping("/test/{testId}")
@@ -637,6 +647,17 @@ public class SpringMvcContractTests {
}
public interface TestTemplate_Cookies {
@GetMapping("/test/{id}")
ResponseEntity<TestObject> singleCookie(@PathVariable("id") String id, @CookieValue("cookie1") String cookie1);
@GetMapping("/test/{id}")
ResponseEntity<TestObject> multipleCookies(@PathVariable("id") String id,
@CookieValue("cookie1") String cookie1, @CookieValue("cookie2") String cookie2);
}
public interface TestTemplate_HeadersWithoutValues {
@GetMapping(value = "/test/{id}", headers = { "X-Foo", "!X-Bar", "X-Baz!=fooBar" })
@@ -713,13 +734,16 @@ public class SpringMvcContractTests {
}
@JsonAutoDetect
@RequestMapping("/advanced")
@CollectionFormat(CSV)
public interface TestTemplate_Advanced {
@CollectionFormat(SSV)
@GetMapping
ResponseEntity<TestObject> getWithCollectionFormat();
@GetMapping
ResponseEntity<TestObject> getWithoutCollectionFormat();
@ExceptionHandler
@PutMapping(path = "/test/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<TestObject> getTest(@RequestHeader("Authorization") String auth, @PathVariable("id") String id,
@@ -768,10 +792,10 @@ public class SpringMvcContractTests {
public Double number;
public TestObject() {
TestObject() {
}
public TestObject(String something, Double number) {
TestObject(String something, Double number) {
this.something = something;
this.number = number;
}
@@ -47,8 +47,7 @@ import static org.mockito.Mockito.mockingDetails;
* @author Olga Maciaszek-Sharma
*/
@SpringBootTest(properties = { "feign.okhttp.enabled: true", "spring.cloud.httpclientfactories.ok.enabled: true",
"ribbon.eureka.enabled = false", "ribbon.okhttp.enabled: true", "feign.okhttp.enabled: true",
"ribbon.httpclient.enabled: false", "feign.httpclient.enabled: false",
"feign.okhttp.enabled: true", "feign.httpclient.enabled: false",
"spring.cloud.loadbalancer.retry.enabled=false" })
@DirtiesContext
class OkHttpClientConfigurationTests {
@@ -19,8 +19,7 @@ package org.springframework.cloud.openfeign.valid;
import java.util.List;
import feign.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -36,7 +35,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -47,13 +45,12 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* @author Spencer Gibb
* @author Jakub Narloch
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = FeignClientNotPrimaryTests.Application.class, webEnvironment = RANDOM_PORT,
value = { "spring.application.name=feignclientnotprimarytest",
"logging.level.org.springframework.cloud.openfeign.valid=DEBUG", "feign.httpclient.enabled=false",
"feign.okhttp.enabled=false" })
@DirtiesContext
public class FeignClientNotPrimaryTests {
class FeignClientNotPrimaryTests {
public static final String HELLO_WORLD_1 = "hello world 1";
@@ -64,17 +61,17 @@ public class FeignClientNotPrimaryTests {
private List<TestClient> testClients;
@Test
public void testClientType() {
void testClientType() {
assertThat(this.testClient).as("testClient was of wrong type").isInstanceOf(PrimaryTestClient.class);
}
@Test
public void testClientCount() {
void testClientCount() {
assertThat(this.testClients).as("testClients was wrong").hasSize(2);
}
@Test
public void testSimpleType() {
void testSimpleType() {
Hello hello = this.testClient.getHello();
assertThat(hello).as("hello was null").isNull();
}
@@ -120,10 +117,10 @@ public class FeignClientNotPrimaryTests {
private String message;
public Hello() {
Hello() {
}
public Hello(String message) {
Hello(String message) {
this.message = message;
}
@@ -16,7 +16,7 @@
package org.springframework.cloud.openfeign.valid;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
@@ -34,17 +34,17 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Dave Syer
*/
public class FeignClientValidationTests {
class FeignClientValidationTests {
@Test
public void validNotLoadBalanced() {
void validNotLoadBalanced() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(GoodUrlConfiguration.class);
assertThat(context.getBean(GoodUrlConfiguration.Client.class)).isNotNull();
context.close();
}
@Test
public void validPlaceholder() {
void validPlaceholder() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
PlaceholderUrlConfiguration.class);
assertThat(context.getBean(PlaceholderUrlConfiguration.Client.class)).isNotNull();
@@ -52,7 +52,7 @@ public class FeignClientValidationTests {
}
@Test
public void validLoadBalanced() {
void validLoadBalanced() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
LoadBalancerAutoConfiguration.class,
org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration.class,
@@ -18,8 +18,7 @@ package org.springframework.cloud.openfeign.valid;
import io.vavr.collection.HashSet;
import io.vavr.collection.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -37,7 +36,6 @@ 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.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@@ -47,19 +45,18 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = IterableParameterTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT,
value = { "spring.application.name=iterableparametertest",
"logging.level.org.springframework.cloud.openfeign.valid=DEBUG", "feign.httpclient.enabled=false",
"feign.okhttp.enabled=false", "feign.circuitbreaker.enabled=false" })
@DirtiesContext
public class IterableParameterTests {
class IterableParameterTests {
@Autowired
private TestClient testClient;
@Test
public void testClient() {
void testClient() {
assertThat(this.testClient).as("testClient was null").isNotNull();
String results = this.testClient.echo(HashSet.of("a", "b"));
assertThat(results).isEqualTo("a,b");
@@ -77,7 +74,7 @@ public class IterableParameterTests {
@EnableAutoConfiguration
@RestController
@EnableFeignClients(clients = TestClient.class)
@LoadBalancerClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class)
@LoadBalancerClient(name = "localapp", configuration = LocalLoadBalancerConfiguration.class)
@Import(NoSecurityConfiguration.class)
protected static class Application {
@@ -89,7 +86,7 @@ public class IterableParameterTests {
}
// Load balancer with fixed server list for "local" pointing to localhost
public static class LocalRibbonClientConfiguration {
public static class LocalLoadBalancerConfiguration {
@LocalServerPort
private int port = 0;
@@ -16,8 +16,7 @@
package org.springframework.cloud.openfeign.valid.scanning;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -34,7 +33,6 @@ 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.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -44,18 +42,17 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
/**
* @author Ryan Baxter
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = FeignClientEnvVarTests.Application.class, webEnvironment = RANDOM_PORT,
value = { "spring.application.name=feignclienttest", "feign.httpclient.enabled=false",
"basepackage=org.springframework.cloud.openfeign.testclients" })
@DirtiesContext
public class FeignClientEnvVarTests {
class FeignClientEnvVarTests {
@Autowired
private TestClient testClient;
@Test
public void testSimpleType() {
void testSimpleType() {
String hello = this.testClient.getHello();
assertThat(hello).as("hello was null").isNotNull();
assertThat(hello).as("first hello didn't match").isEqualTo("hello world 1");
@@ -17,8 +17,7 @@
package org.springframework.cloud.openfeign.valid.scanning;
import feign.Client;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -36,7 +35,6 @@ 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.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -46,11 +44,10 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = FeignClientScanningTests.Application.class, webEnvironment = RANDOM_PORT,
value = { "spring.application.name=feignclienttest", "feign.httpclient.enabled=false" })
@DirtiesContext
public class FeignClientScanningTests {
class FeignClientScanningTests {
@Value("${local.server.port}")
private int port = 0;
@@ -66,14 +63,14 @@ public class FeignClientScanningTests {
private Client feignClient;
@Test
public void testSimpleType() {
void testSimpleType() {
String hello = this.testClient.getHello();
assertThat(hello).as("hello was null").isNotNull();
assertThat(hello).as("first hello didn't match").isEqualTo("hello world 1");
}
@Test
public void testSimpleTypeByKey() {
void testSimpleTypeByKey() {
String hello = this.testClientByKey.getHello();
assertThat(hello).as("hello was null").isNotNull();
assertThat(hello).as("first hello didn't match").isEqualTo("hello world 1");
@@ -13,19 +13,6 @@ eureka:
client:
registerWithEureka: false
fetchRegistry: false
#error:
# path: /myerror
ribbon:
ConnectTimeout: 3001
ReadTimeout: 60001
foo:
ribbon:
ConnectTimeout: 7
ReadTimeout: 17
badClients:
ribbon:
MaxAutoRetriesNextServer: 10
ReadTimeout: 200
endpoints:
health:
sensitive: false
+3 -3
View File
@@ -6,16 +6,16 @@
<parent>
<artifactId>spring-cloud-dependencies-parent</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>3.1.0-M1</version>
<version>3.1.0</version>
<relativePath/>
</parent>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>3.1.0-M1</version>
<version>3.1.0</version>
<packaging>pom</packaging>
<name>spring-cloud-openfeign-dependencies</name>
<description>Spring Cloud OpenFeign Dependencies</description>
<properties>
<feign.version>11.6</feign.version>
<feign.version>11.7</feign.version>
<feign-form.version>3.8.0</feign-form.version>
<spring-security-oauth2-autoconfigure.version>2.1.2.RELEASE</spring-security-oauth2-autoconfigure.version>
</properties>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>3.1.0-M1</version>
<version>3.1.0</version>
<relativePath>..</relativePath>
</parent>
<artifactId>spring-cloud-starter-openfeign</artifactId>