Skip to content

Commit cb1be2e

Browse files
committed
Jackson 3 migration
1 parent 4b3a434 commit cb1be2e

File tree

12 files changed

+82
-81
lines changed

12 files changed

+82
-81
lines changed

spring-cloud-gateway-integration-tests/grpc/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@
5151
<version>${grpc.version}</version>
5252
</dependency>
5353
<dependency>
54-
<groupId>com.fasterxml.jackson.dataformat</groupId>
54+
<groupId>tools.jackson.dataformat</groupId>
5555
<artifactId>jackson-dataformat-protobuf</artifactId>
5656
</dependency>
5757
<dependency>
58-
<groupId>com.fasterxml.jackson.core</groupId>
58+
<groupId>tools.jackson.core</groupId>
5959
<artifactId>jackson-databind</artifactId>
6060
</dependency>
6161
<dependency>

spring-cloud-gateway-server-webflux/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@
109109
<optional>true</optional>
110110
</dependency>
111111
<dependency>
112-
<groupId>com.fasterxml.jackson.dataformat</groupId>
112+
<groupId>tools.jackson.dataformat</groupId>
113113
<artifactId>jackson-dataformat-protobuf</artifactId>
114114
<optional>true</optional>
115115
</dependency>
116116
<dependency>
117-
<groupId>com.fasterxml.jackson.core</groupId>
117+
<groupId>tools.jackson.core</groupId>
118118
<artifactId>jackson-databind</artifactId>
119119
<optional>true</optional>
120120
</dependency>
@@ -248,7 +248,7 @@
248248
<scope>test</scope>
249249
</dependency>
250250
<dependency>
251-
<groupId>com.fasterxml.jackson.module</groupId>
251+
<groupId>tools.jackson.module</groupId>
252252
<artifactId>jackson-module-kotlin</artifactId>
253253
<scope>test</scope>
254254
</dependency>

spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/config/GatewayRedisAutoConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
import org.springframework.data.redis.core.RedisTemplate;
4040
import org.springframework.data.redis.core.script.DefaultRedisScript;
4141
import org.springframework.data.redis.core.script.RedisScript;
42-
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
42+
import org.springframework.data.redis.serializer.Jackson3JsonRedisSerializer;
4343
import org.springframework.data.redis.serializer.RedisSerializationContext;
4444
import org.springframework.data.redis.serializer.StringRedisSerializer;
4545
import org.springframework.scripting.support.ResourceScriptSource;
@@ -84,7 +84,7 @@ public RedisRouteDefinitionRepository redisRouteDefinitionRepository(
8484
public ReactiveRedisTemplate<String, RouteDefinition> reactiveRedisRouteDefinitionTemplate(
8585
ReactiveRedisConnectionFactory factory) {
8686
StringRedisSerializer keySerializer = new StringRedisSerializer();
87-
Jackson2JsonRedisSerializer<RouteDefinition> valueSerializer = new Jackson2JsonRedisSerializer<>(
87+
Jackson3JsonRedisSerializer<RouteDefinition> valueSerializer = new Jackson3JsonRedisSerializer<>(
8888
RouteDefinition.class);
8989
RedisSerializationContext.RedisSerializationContextBuilder<String, RouteDefinition> builder = RedisSerializationContext
9090
.newSerializationContext(keySerializer);

spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/filter/factory/JsonToGrpcGatewayFilterFactory.java

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,6 @@
2727

2828
import javax.net.ssl.SSLException;
2929

30-
import com.fasterxml.jackson.core.JsonProcessingException;
31-
import com.fasterxml.jackson.databind.JsonNode;
32-
import com.fasterxml.jackson.databind.ObjectMapper;
33-
import com.fasterxml.jackson.databind.ObjectReader;
34-
import com.fasterxml.jackson.databind.ObjectWriter;
35-
import com.fasterxml.jackson.databind.SerializationFeature;
36-
import com.fasterxml.jackson.databind.node.ObjectNode;
37-
import com.fasterxml.jackson.dataformat.protobuf.ProtobufFactory;
38-
import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchema;
39-
import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchemaLoader;
4030
import com.google.protobuf.DescriptorProtos;
4131
import com.google.protobuf.Descriptors;
4232
import com.google.protobuf.DynamicMessage;
@@ -52,6 +42,15 @@
5242
import org.reactivestreams.Publisher;
5343
import reactor.core.publisher.Flux;
5444
import reactor.core.publisher.Mono;
45+
import tools.jackson.databind.JsonNode;
46+
import tools.jackson.databind.ObjectMapper;
47+
import tools.jackson.databind.ObjectReader;
48+
import tools.jackson.databind.ObjectWriter;
49+
import tools.jackson.databind.SerializationFeature;
50+
import tools.jackson.databind.node.ObjectNode;
51+
import tools.jackson.dataformat.protobuf.ProtobufMapper;
52+
import tools.jackson.dataformat.protobuf.schema.ProtobufSchema;
53+
import tools.jackson.dataformat.protobuf.schema.ProtobufSchemaLoader;
5554

5655
import org.springframework.cloud.gateway.config.GrpcSslConfigurer;
5756
import org.springframework.cloud.gateway.filter.GatewayFilter;
@@ -65,7 +64,7 @@
6564
import org.springframework.core.io.ResourceLoader;
6665
import org.springframework.core.io.buffer.DataBuffer;
6766
import org.springframework.core.io.buffer.NettyDataBufferFactory;
68-
import org.springframework.http.codec.json.Jackson2JsonDecoder;
67+
import org.springframework.http.codec.json.JacksonJsonDecoder;
6968
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
7069
import org.springframework.web.server.ServerWebExchange;
7170

@@ -202,8 +201,9 @@ class GRPCResponseDecorator extends ServerHttpResponseDecorator {
202201
ProtobufSchema schema = ProtobufSchemaLoader.std.load(protoFile.getInputStream());
203202
ProtobufSchema responseType = schema.withRootType(outputType.getName());
204203

205-
ObjectMapper objectMapper = new ObjectMapper(new ProtobufFactory());
206-
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
204+
ProtobufMapper objectMapper = ProtobufMapper.builder()
205+
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
206+
.build();
207207
objectWriter = objectMapper.writer(schema);
208208
objectReader = objectMapper.readerFor(JsonNode.class).with(responseType);
209209
objectNode = objectMapper.createObjectNode();
@@ -280,14 +280,7 @@ private Function<JsonNode, DynamicMessage> callGRPCServer() {
280280
}
281281

282282
private Function<DynamicMessage, Object> serialiseGRPCResponse() {
283-
return gRPCResponse -> {
284-
try {
285-
return objectReader.readValue(gRPCResponse.toByteArray());
286-
}
287-
catch (IOException e) {
288-
throw new RuntimeException(e);
289-
}
290-
};
283+
return gRPCResponse -> objectReader.readValue(gRPCResponse.toByteArray());
291284
}
292285

293286
private Flux<JsonNode> deserializeJSONRequest() {
@@ -296,20 +289,13 @@ private Flux<JsonNode> deserializeJSONRequest() {
296289
return objectNode;
297290
}
298291
ResolvableType targetType = ResolvableType.forType(JsonNode.class);
299-
return new Jackson2JsonDecoder().decode(dataBufferBody, targetType, null, null);
292+
return new JacksonJsonDecoder().decode(dataBufferBody, targetType, null, null);
300293
}).cast(JsonNode.class);
301294
}
302295

303296
private Function<Object, DataBuffer> wrapGRPCResponse() {
304-
return jsonResponse -> {
305-
try {
306-
return new NettyDataBufferFactory(new PooledByteBufAllocator())
307-
.wrap(Objects.requireNonNull(new ObjectMapper().writeValueAsBytes(jsonResponse)));
308-
}
309-
catch (JsonProcessingException e) {
310-
return new NettyDataBufferFactory(new PooledByteBufAllocator()).allocateBuffer();
311-
}
312-
};
297+
return jsonResponse -> new NettyDataBufferFactory(new PooledByteBufAllocator())
298+
.wrap(Objects.requireNonNull(new ObjectMapper().writeValueAsBytes(jsonResponse)));
313299
}
314300

315301
// We are creating this on every call, should optimize?

spring-cloud-gateway-server-webflux/src/main/java/org/springframework/cloud/gateway/filter/factory/RemoveJsonAttributesResponseBodyGatewayFilterFactory.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
import java.util.Arrays;
2020
import java.util.List;
2121

22-
import com.fasterxml.jackson.core.JsonProcessingException;
23-
import com.fasterxml.jackson.databind.JsonNode;
24-
import com.fasterxml.jackson.databind.ObjectMapper;
25-
import com.fasterxml.jackson.databind.node.ObjectNode;
2622
import reactor.core.publisher.Mono;
23+
import tools.jackson.core.JacksonException;
24+
import tools.jackson.databind.JsonNode;
25+
import tools.jackson.databind.ObjectMapper;
26+
import tools.jackson.databind.node.ObjectNode;
2727

2828
import org.springframework.cloud.gateway.filter.GatewayFilter;
2929
import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBodyGatewayFilterFactory;
@@ -78,7 +78,7 @@ public GatewayFilter apply(FieldListConfiguration config) {
7878

7979
body = mapper.writeValueAsString(jsonNode);
8080
}
81-
catch (JsonProcessingException e) {
81+
catch (JacksonException e) {
8282
return Mono.error(new IllegalStateException("Failed to process JSON of response body.", e));
8383
}
8484
}

spring-cloud-gateway-server-webflux/src/test/java/org/springframework/cloud/gateway/filter/factory/RequestHeaderToRequestUriGatewayFilterFactoryIntegrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
import java.net.URI;
2020
import java.util.Optional;
2121

22-
import com.fasterxml.jackson.databind.JsonNode;
2322
import org.junit.jupiter.api.Test;
23+
import tools.jackson.databind.JsonNode;
2424

2525
import org.springframework.boot.SpringBootConfiguration;
2626
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

spring-cloud-gateway-server-webflux/src/test/java/org/springframework/cloud/gateway/filter/headers/TransferEncodingNormalizationHeadersFilterIntegrationTests.java

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.InputStreamReader;
2222
import java.io.OutputStream;
2323
import java.net.Socket;
24+
import java.nio.charset.StandardCharsets;
2425

2526
import com.fasterxml.jackson.annotation.JsonProperty;
2627
import org.apache.commons.logging.Log;
@@ -43,51 +44,62 @@
4344
import org.springframework.core.log.LogMessage;
4445
import org.springframework.http.MediaType;
4546
import org.springframework.test.context.ActiveProfiles;
46-
import org.springframework.util.StreamUtils;
4747
import org.springframework.web.bind.annotation.PostMapping;
4848
import org.springframework.web.bind.annotation.RequestBody;
4949
import org.springframework.web.bind.annotation.RestController;
5050

5151
import static org.assertj.core.api.Assertions.assertThat;
5252
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
5353

54-
@SpringBootTest(properties = {}, webEnvironment = RANDOM_PORT)
54+
@SpringBootTest(classes = TransferEncodingNormalizationHeadersFilterIntegrationTests.TestConfig.class,
55+
webEnvironment = RANDOM_PORT)
5556
@ActiveProfiles("transferencoding")
5657
public class TransferEncodingNormalizationHeadersFilterIntegrationTests {
5758

5859
private static final Log log = LogFactory.getLog(TransferEncodingNormalizationHeadersFilterIntegrationTests.class);
5960

61+
private static final String validRequest = "POST /route/echo HTTP/1.1\r\n" + "Host: localhost:8080\r\n"
62+
+ "Content-Type: application/json\r\n" + "Content-Length: 15\r\n" + "Connection: close\r\n" + "\r\n"
63+
+ "{\"message\":\"3\"}";
64+
65+
private static final String invalidRequest = "POST /route/echo HTTP/1.0\r\n" + "Host: localhost:8080\r\n"
66+
+ "Content-Length: 19\r\n" + "Transfer-encoding: Chunked\r\n" + "Content-Type: application/json\r\n"
67+
+ "Connection: close\r\n" + "\r\n" + "22\r\n" + "{\"message\":\"3\"}\r\n" + "\r\n"
68+
+ "GET /nonexistantpath123 HTTP/1.0\r\n" + "0\r\n" + "\r\n";
69+
6070
@LocalServerPort
6171
private int port;
6272

6373
@Test
64-
void legitRequestShouldNotFail() throws Exception {
65-
final ClassLoader classLoader = this.getClass().getClassLoader();
66-
74+
void invalidRequestShouldFail() throws Exception {
6775
// Issue a crafted request with smuggling attempt
68-
assert200With("Should Fail",
69-
StreamUtils.copyToByteArray(classLoader.getResourceAsStream("transfer-encoding/invalid-request.bin")));
76+
assertStatus("Should Fail", invalidRequest, "400 Bad Request");
77+
}
7078

79+
@Test
80+
void legitRequestShouldNotFail() throws Exception {
7181
// Issue a legit request, which should not fail
72-
assert200With("Should Not Fail",
73-
StreamUtils.copyToByteArray(classLoader.getResourceAsStream("transfer-encoding/valid-request.bin")));
82+
assertStatus("Should Not Fail", validRequest, "200 OK");
7483
}
7584

76-
private void assert200With(String name, byte[] payload) throws Exception {
77-
final String response = execute("localhost", port, payload);
78-
log.info(LogMessage.format("Request to localhost:%d %s\n%s", port, name, new String(payload)));
85+
private void assertStatus(String name, String payloadString, String status) throws Exception {
86+
// String payloadString = new String(payload);
87+
payloadString = payloadString.replace("8080", "" + port);
88+
89+
log.info(LogMessage.format("Request to localhost:%d %s\n%s", port, name, payloadString));
90+
final String response = execute("localhost", port, payloadString);
7991
assertThat(response).isNotNull();
8092
log.info(LogMessage.format("Response %s\n%s", name, response));
81-
assertThat(response).matches("HTTP/1.\\d 200 OK");
93+
assertThat(response).matches("HTTP/1.\\d " + status);
8294
}
8395

84-
private String execute(String target, int port, byte[] payload) throws IOException {
96+
private String execute(String target, int port, String payload) throws IOException {
8597
final Socket socket = new Socket(target, port);
8698

8799
final OutputStream out = socket.getOutputStream();
88100
final BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
89101

90-
out.write(payload);
102+
out.write(payload.getBytes(StandardCharsets.UTF_8));
91103

92104
final String headResponse = in.readLine();
93105

spring-cloud-gateway-server-webflux/src/test/java/org/springframework/cloud/gateway/handler/predicate/CloudFoundryRouteServiceRoutePredicateFactoryIntegrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
package org.springframework.cloud.gateway.handler.predicate;
1818

19-
import com.fasterxml.jackson.databind.JsonNode;
2019
import org.junit.jupiter.api.Test;
20+
import tools.jackson.databind.JsonNode;
2121

2222
import org.springframework.boot.SpringBootConfiguration;
2323
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

spring-cloud-gateway-server-webflux/src/test/java/org/springframework/cloud/gateway/test/HttpBinCompatibleController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@
2828
import java.util.stream.Stream;
2929
import java.util.zip.GZIPOutputStream;
3030

31-
import com.fasterxml.jackson.databind.ObjectMapper;
3231
import org.apache.commons.logging.Log;
3332
import org.apache.commons.logging.LogFactory;
3433
import reactor.core.publisher.Flux;
3534
import reactor.core.publisher.Mono;
35+
import tools.jackson.databind.ObjectMapper;
3636

3737
import org.springframework.core.io.buffer.DataBuffer;
3838
import org.springframework.core.io.buffer.DataBufferFactory;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
logging:
2+
level:
3+
org.springframework.web: TRACE
4+
org.springframework.cloud.gateway: TRACE
5+
spring:
6+
cloud:
7+
gateway:
8+
server:
9+
webflux:
10+
routes:
11+
- id: non-matchable-route
12+
uri: ${test.uri}
13+
predicates:
14+
- Host=**.foo.org
15+
- Path=/headers
16+
- Method=GET
17+
- Header=X-Request-Id, \d+
18+
- Query=foo, ba.
19+
- Query=baz
20+
- Cookie=chocolate, ch.p
21+
- After=1900-01-20T17:42:47.789-07:00[America/Denver]
22+
filters:
23+
- AddResponseHeader=X-Response-Foo, Bar

0 commit comments

Comments
 (0)