Compare commits

...
8 Commits
Author SHA1 Message Date
buildmaster 10c6992935 Update SNAPSHOT to 2.2.7.RELEASE 2021-02-11 14:14:19 +00:00
Hyeonmin Park d87375e835 Encode Pageable.Sort with percent encoded comma. Fixes gh-440. (#467)
* Encode Pageable.Sort with percent encoded comma. Fixes gh-440.

* Replace ifs with assert in FeignPageableEncodingTests
2021-02-08 18:33:12 +01:00
Hyeonmin Park cc9af41dfe Add configuration metadata for feign.autoconfiguration.jackson.enabled (#478) 2021-02-08 16:51:47 +01:00
Tim Peeters 9bb8b43d58 Import OpenFeign bom 2021-02-08 16:18:52 +01:00
Olga Maciaszek-Sharma 60558c46ef Reformat. 2021-02-02 15:31:06 +01:00
Olga Maciaszek-Sharma 89db04d7d0 Fix broken reference in docs. 2021-02-02 15:30:43 +01:00
Olga Maciaszek-Sharma 27a3967975 Support all non-deprecated Jackson naming strategies for page deserialization. Fixes gh-170. (#477) 2021-02-02 14:10:46 +01:00
spencergibb 0c4c19bfcd Better classpath protections for pageable modules.
Fixes gh-474

# Conflicts:
#	spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignAutoConfiguration.java
2021-01-29 12:29:33 +01:00
13 changed files with 136 additions and 110 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>2.2.7.BUILD-SNAPSHOT</version>
<version>2.2.7.RELEASE</version>
</parent>
<artifactId>spring-cloud-openfeign-docs</artifactId>
<packaging>pom</packaging>
+20 -19
View File
@@ -1,26 +1,27 @@
|===
|Name | Default | Description
|feign.circuitbreaker.enabled | false | If true, an OpenFeign client will be wrapped with a Spring Cloud CircuitBreaker circuit breaker.
|feign.autoconfiguration.jackson.enabled | `false` | If true, PageJacksonModule and SortJacksonModule bean will be provided for Jackson page decoding.
|feign.circuitbreaker.enabled | `false` | If true, an OpenFeign client will be wrapped with a Spring Cloud CircuitBreaker circuit breaker.
|feign.client.config | |
|feign.client.decode-slash | true | Feign clients do not encode slash `/` characters by default. To change this behavior, set the `decodeSlash` to `false`.
|feign.client.default-config | default |
|feign.client.default-to-properties | true |
|feign.compression.request.enabled | false | Enables the request sent by Feign to be compressed.
|feign.compression.request.mime-types | [text/xml, application/xml, application/json] | The list of supported mime types.
|feign.compression.request.min-request-size | 2048 | The minimum threshold content size.
|feign.compression.response.enabled | false | Enables the response from Feign to be compressed.
|feign.compression.response.useGzipDecoder | false | Enables the default gzip decoder to be used.
|feign.httpclient.connection-timeout | 2000 |
|feign.httpclient.connection-timer-repeat | 3000 |
|feign.httpclient.disable-ssl-validation | false |
|feign.httpclient.enabled | true | Enables the use of the Apache HTTP Client by Feign.
|feign.httpclient.follow-redirects | true |
|feign.httpclient.max-connections | 200 |
|feign.httpclient.max-connections-per-route | 50 |
|feign.httpclient.time-to-live | 900 |
|feign.client.decode-slash | `true` | Feign clients do not encode slash `/` characters by default. To change this behavior, set the `decodeSlash` to `false`.
|feign.client.default-config | `default` |
|feign.client.default-to-properties | `true` |
|feign.compression.request.enabled | `false` | Enables the request sent by Feign to be compressed.
|feign.compression.request.mime-types | `[text/xml, application/xml, application/json]` | The list of supported mime types.
|feign.compression.request.min-request-size | `2048` | The minimum threshold content size.
|feign.compression.response.enabled | `false` | Enables the response from Feign to be compressed.
|feign.compression.response.useGzipDecoder | `false` | Enables the default gzip decoder to be used.
|feign.httpclient.connection-timeout | `2000` |
|feign.httpclient.connection-timer-repeat | `3000` |
|feign.httpclient.disable-ssl-validation | `false` |
|feign.httpclient.enabled | `true` | Enables the use of the Apache HTTP Client by Feign.
|feign.httpclient.follow-redirects | `true` |
|feign.httpclient.max-connections | `200` |
|feign.httpclient.max-connections-per-route | `50` |
|feign.httpclient.time-to-live | `900` |
|feign.httpclient.time-to-live-unit | |
|feign.hystrix.enabled | false | If true, an OpenFeign client will be wrapped with a Hystrix circuit breaker.
|feign.okhttp.enabled | false | Enables the use of the OK HTTP Client by Feign.
|feign.hystrix.enabled | `false` | If true, an OpenFeign client will be wrapped with a Hystrix circuit breaker.
|feign.okhttp.enabled | `false` | Enables the use of the OK HTTP Client by Feign.
|===
@@ -459,14 +459,14 @@ Spring Cloud CircuitBreaker supports the notion of a fallback: a default code pa
[source,java,indent=0]
----
include::{core_path}/src/test/java/org/springframework/cloud/openfeign/circuitbreaker/CirciutBreakerTests.java[tags=client_with_fallback, indent=0]
include::{core_path}/src/test/java/org/springframework/cloud/openfeign/circuitbreaker/CircuitBreakerTests.java[tags=client_with_fallback, indent=0]
----
If one needs access to the cause that made the fallback trigger, one can use the `fallbackFactory` attribute inside `@FeignClient`.
[source,java,indent=0]
----
include::{core_path}/src/test/java/org/springframework/cloud/openfeign/circuitbreaker/CirciutBreakerTests.java[tags=client_with_fallback_factory, indent=0]
include::{core_path}/src/test/java/org/springframework/cloud/openfeign/circuitbreaker/CircuitBreakerTests.java[tags=client_with_fallback_factory, indent=0]
----
=== Feign and `@Primary`
+4 -4
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>2.2.7.BUILD-SNAPSHOT</version>
<version>2.2.7.RELEASE</version>
<packaging>pom</packaging>
<name>Spring Cloud OpenFeign</name>
<description>Spring Cloud OpenFeign</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>2.3.1.RELEASE</version>
<version>2.3.2.RELEASE</version>
<relativePath/>
</parent>
<scm>
@@ -26,8 +26,8 @@
<properties>
<main.basedir>${basedir}</main.basedir>
<jackson.version>2.11.3</jackson.version>
<spring-cloud-commons.version>2.2.7.BUILD-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-netflix.version>2.2.7.BUILD-SNAPSHOT</spring-cloud-netflix.version>
<spring-cloud-commons.version>2.2.7.RELEASE</spring-cloud-commons.version>
<spring-cloud-netflix.version>2.2.7.RELEASE</spring-cloud-netflix.version>
<!-- Plugin versions -->
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>2.2.7.BUILD-SNAPSHOT</version>
<version>2.2.7.RELEASE</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-openfeign-core</artifactId>
@@ -60,6 +60,8 @@ import org.springframework.cloud.openfeign.support.SortJacksonModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
/**
* @author Spencer Gibb
@@ -91,22 +93,24 @@ public class FeignAutoConfiguration {
return context;
}
@Bean
@ConditionalOnMissingBean(PageJacksonModule.class)
@ConditionalOnClass(name = "org.springframework.data.domain.Page")
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Module.class, Page.class, Sort.class })
@ConditionalOnProperty(value = "feign.autoconfiguration.jackson.enabled",
havingValue = "true")
public Module pageJacksonModule() {
return new PageJacksonModule();
}
protected static class FeignJacksonConfiguration {
@Bean
@ConditionalOnMissingBean(PageJacksonModule.class)
public PageJacksonModule pageJacksonModule() {
return new PageJacksonModule();
}
@Bean
@ConditionalOnMissingBean(SortJacksonModule.class)
public SortJacksonModule sortModule() {
return new SortJacksonModule();
}
@Bean
@ConditionalOnMissingBean(SortJacksonModule.class)
@ConditionalOnClass(name = "org.springframework.data.domain.Sort")
@ConditionalOnProperty(value = "feign.autoconfiguration.jackson.enabled",
havingValue = "true")
public Module sortModule() {
return new SortJacksonModule();
}
@Configuration(proxyBeanMethods = false)
@@ -20,6 +20,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.Version;
@@ -36,6 +37,7 @@ import org.springframework.data.domain.Sort;
* This Jackson module provides support to deserialize Spring {@link Page} objects.
*
* @author Pascal Büttiker
* @author Olga Maciaszek-Sharma
*/
public class PageJacksonModule extends Module {
@@ -65,7 +67,9 @@ public class PageJacksonModule extends Module {
SimplePageImpl(@JsonProperty("content") List<T> content,
@JsonProperty("number") int number, @JsonProperty("size") int size,
@JsonProperty("totalElements") long totalElements,
@JsonProperty("totalElements") @JsonAlias({ "total-elements",
"total_elements", "totalelements",
"TotalElements" }) long totalElements,
@JsonProperty("sort") Sort sort) {
PageRequest pageRequest;
if (sort != null) {
@@ -120,7 +120,7 @@ public class PageableSpringEncoder implements Encoder {
}
}
for (Sort.Order order : sort) {
sortQueries.add(order.getProperty() + "," + order.getDirection());
sortQueries.add(order.getProperty() + "%2C" + order.getDirection());
}
if (!sortQueries.isEmpty()) {
template.query(sortParameter, sortQueries);
@@ -8,6 +8,12 @@
"description": "If true, an OpenFeign client will be wrapped with a Hystrix circuit breaker.",
"defaultValue": "false"
},
{
"name": "feign.autoconfiguration.jackson.enabled",
"type": "java.lang.Boolean",
"description": "If true, PageJacksonModule and SortJacksonModule bean will be provided for Jackson page decoding.",
"defaultValue": "false"
},
{
"name": "feign.circuitbreaker.enabled",
"type": "java.lang.Boolean",
@@ -17,6 +17,7 @@
package org.springframework.cloud.openfeign.encoding;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import com.netflix.loadbalancer.BaseLoadBalancer;
@@ -54,6 +55,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
* Tests the pagination encoding.
*
* @author Charlie Mordant.
* @author Hyeonmin Park
*/
@SpringBootTest(classes = FeignPageableEncodingTests.Application.class,
webEnvironment = RANDOM_PORT,
@@ -93,6 +95,66 @@ public class FeignPageableEncodingTests {
}
@Test
public void testPageableWithDescDirection() {
// given
Pageable pageable = PageRequest.of(0, 10, Sort.Direction.DESC, "sortProperty");
// when
final ResponseEntity<Page<Invoice>> response = this.invoiceClient
.getInvoicesPaged(pageable);
// then
assertThat(response).isNotNull();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isNotNull();
assertThat(pageable.getPageSize()).isEqualTo(response.getBody().getSize());
Sort sort = response.getBody().getPageable().getSort();
assertThat(sort).hasSize(1);
assertThat(sort.get()).hasSize(1);
Optional<Sort.Order> optionalOrder = sort.get().findFirst();
assertThat(optionalOrder.isPresent()).isTrue();
Sort.Order order = optionalOrder.get();
assertThat(order.getDirection()).isEqualTo(Sort.Direction.DESC);
assertThat(order.getProperty()).isEqualTo("sortProperty");
}
@Test
public void testPageableWithMultipleSort() {
// given
Pageable pageable = PageRequest.of(0, 10, Sort
.by(Sort.Order.desc("sortProperty1"), Sort.Order.asc("sortProperty2")));
// when
final ResponseEntity<Page<Invoice>> response = this.invoiceClient
.getInvoicesPaged(pageable);
// then
assertThat(response).isNotNull();
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isNotNull();
assertThat(pageable.getPageSize()).isEqualTo(response.getBody().getSize());
Sort sort = response.getBody().getPageable().getSort();
assertThat(sort).hasSize(2);
List<Sort.Order> orderList = sort.toList();
assertThat(orderList).hasSize(2);
Sort.Order firstOrder = orderList.get(0);
assertThat(firstOrder.getDirection()).isEqualTo(Sort.Direction.DESC);
assertThat(firstOrder.getProperty()).isEqualTo("sortProperty1");
Sort.Order secondOrder = orderList.get(1);
assertThat(secondOrder.getDirection()).isEqualTo(Sort.Direction.ASC);
assertThat(secondOrder.getProperty()).isEqualTo("sortProperty2");
}
@EnableFeignClients(clients = InvoiceClient.class)
@RibbonClient(name = "local", configuration = LocalRibbonClientConfiguration.class)
@SpringBootApplication(
@@ -19,14 +19,18 @@ package org.springframework.cloud.openfeign.support;
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 static org.assertj.core.api.Assertions.assertThat;
/**
* Test for {@link PageJacksonModule}.
*
* @author Ruben Vervaeke
* @author Olga Maciaszek-Sharma
*/
public class PageJacksonModuleTests {
@@ -38,10 +42,13 @@ public class PageJacksonModuleTests {
objectMapper.registerModule(new PageJacksonModule());
}
@Test
public void deserializePage() throws JsonProcessingException {
@ParameterizedTest
@ValueSource(strings = { "totalElements", "total-elements", "total_elements",
"totalelements", "TotalElements" })
public void deserializePage(String totalElements) throws JsonProcessingException {
// Given
String pageJson = "{\"content\":[\"A name\"], \"number\":1, \"size\":2, \"totalElements\": 3}";
String pageJson = "{\"content\":[\"A name\"], \"number\":1, \"size\":2, \""
+ totalElements + "\": 3}";
// When
Page<?> result = objectMapper.readValue(pageJson, Page.class);
// Then
+5 -63
View File
@@ -6,11 +6,11 @@
<parent>
<artifactId>spring-cloud-dependencies-parent</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>2.3.2.BUILD-SNAPSHOT</version>
<version>2.3.2.RELEASE</version>
<relativePath/>
</parent>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>2.2.7.BUILD-SNAPSHOT</version>
<version>2.2.7.RELEASE</version>
<packaging>pom</packaging>
<name>spring-cloud-openfeign-dependencies</name>
<description>Spring Cloud OpenFeign Dependencies</description>
@@ -32,74 +32,16 @@
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<artifactId>feign-bom</artifactId>
<version>${feign.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>${feign-form.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hystrix</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson-jaxb</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jaxb</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jaxrs</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-ribbon</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-sax</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-mock</artifactId>
<version>${feign.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign</artifactId>
<version>2.2.7.BUILD-SNAPSHOT</version>
<version>2.2.7.RELEASE</version>
<relativePath>..</relativePath>
</parent>
<artifactId>spring-cloud-starter-openfeign</artifactId>