From 4a5ced201bb72a57dd369fae0079ab66cfcdbf30 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 9 Apr 2026 11:08:22 +0200 Subject: [PATCH 01/14] moved serde annotations to core module --- core/pom.xml | 6 ++++++ .../java/com/arangodb/serde/annotation}/From.java | 2 +- .../java/com/arangodb/serde/annotation}/Id.java | 2 +- .../java/com/arangodb/serde/annotation}/Key.java | 2 +- .../java/com/arangodb/serde/annotation}/Rev.java | 2 +- .../java/com/arangodb/serde/annotation}/To.java | 2 +- .../main/java/com/arangodb/serde/jackson/From.java | 14 -------------- .../main/java/com/arangodb/serde/jackson/Id.java | 14 -------------- .../main/java/com/arangodb/serde/jackson/Key.java | 14 -------------- .../main/java/com/arangodb/serde/jackson/Rev.java | 14 -------------- .../main/java/com/arangodb/serde/jackson/To.java | 14 -------------- .../ArangoSerdeAnnotationIntrospector.java | 1 + .../java/com/arangodb/serde/jackson3/From.java | 14 -------------- .../main/java/com/arangodb/serde/jackson3/Id.java | 14 -------------- .../main/java/com/arangodb/serde/jackson3/Key.java | 14 -------------- .../main/java/com/arangodb/serde/jackson3/Rev.java | 14 -------------- .../main/java/com/arangodb/serde/jackson3/To.java | 14 -------------- .../ArangoSerdeAnnotationIntrospector.java | 1 + jsonb-serde/pom.xml | 1 - pom.xml | 11 ++++++++--- .../com/arangodb/ArangoCollectionAsyncTest.java | 4 +--- .../java/com/arangodb/ArangoCollectionTest.java | 4 +--- .../mapping/annotations/AnnotatedEntity.java | 1 + .../com/arangodb/serde/CustomTypeHintTest.java | 2 +- .../arangodb/serde/JacksonInterferenceTest.java | 1 + .../src/test/java/example/graph/Circle.java | 4 +--- .../src/test/java/example/graph/CircleEdge.java | 2 +- .../src/test/java/serde/Jackson3Person.java | 2 +- .../src/test/java/serde/JacksonPerson.java | 2 +- .../src/test/java/serde/JsonBPerson.java | 2 +- 30 files changed, 31 insertions(+), 163 deletions(-) rename {jsonb-serde/src/main/java/com/arangodb/serde/jsonb => core/src/main/java/com/arangodb/serde/annotation}/From.java (92%) rename {jsonb-serde/src/main/java/com/arangodb/serde/jsonb => core/src/main/java/com/arangodb/serde/annotation}/Id.java (92%) rename {jsonb-serde/src/main/java/com/arangodb/serde/jsonb => core/src/main/java/com/arangodb/serde/annotation}/Key.java (92%) rename {jsonb-serde/src/main/java/com/arangodb/serde/jsonb => core/src/main/java/com/arangodb/serde/annotation}/Rev.java (92%) rename {jsonb-serde/src/main/java/com/arangodb/serde/jsonb => core/src/main/java/com/arangodb/serde/annotation}/To.java (92%) delete mode 100644 jackson-serde-json/src/main/java/com/arangodb/serde/jackson/From.java delete mode 100644 jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Id.java delete mode 100644 jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Key.java delete mode 100644 jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Rev.java delete mode 100644 jackson-serde-json/src/main/java/com/arangodb/serde/jackson/To.java delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/From.java delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Id.java delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Key.java delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Rev.java delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/To.java diff --git a/core/pom.xml b/core/pom.xml index 3eabaeb7f..fb3ce1162 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -49,6 +49,12 @@ jsr305 provided + + jakarta.json.bind + jakarta.json.bind-api + provided + true + diff --git a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/From.java b/core/src/main/java/com/arangodb/serde/annotation/From.java similarity index 92% rename from jsonb-serde/src/main/java/com/arangodb/serde/jsonb/From.java rename to core/src/main/java/com/arangodb/serde/annotation/From.java index 057be2105..cdac89973 100644 --- a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/From.java +++ b/core/src/main/java/com/arangodb/serde/annotation/From.java @@ -1,4 +1,4 @@ -package com.arangodb.serde.jsonb; +package com.arangodb.serde.annotation; import jakarta.json.bind.annotation.JsonbAnnotation; import jakarta.json.bind.annotation.JsonbProperty; diff --git a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Id.java b/core/src/main/java/com/arangodb/serde/annotation/Id.java similarity index 92% rename from jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Id.java rename to core/src/main/java/com/arangodb/serde/annotation/Id.java index f2c4f8462..6e5185097 100644 --- a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Id.java +++ b/core/src/main/java/com/arangodb/serde/annotation/Id.java @@ -1,4 +1,4 @@ -package com.arangodb.serde.jsonb; +package com.arangodb.serde.annotation; import jakarta.json.bind.annotation.JsonbAnnotation; import jakarta.json.bind.annotation.JsonbProperty; diff --git a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Key.java b/core/src/main/java/com/arangodb/serde/annotation/Key.java similarity index 92% rename from jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Key.java rename to core/src/main/java/com/arangodb/serde/annotation/Key.java index e5ff89558..6c12b095b 100644 --- a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Key.java +++ b/core/src/main/java/com/arangodb/serde/annotation/Key.java @@ -1,4 +1,4 @@ -package com.arangodb.serde.jsonb; +package com.arangodb.serde.annotation; import jakarta.json.bind.annotation.JsonbAnnotation; import jakarta.json.bind.annotation.JsonbProperty; diff --git a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Rev.java b/core/src/main/java/com/arangodb/serde/annotation/Rev.java similarity index 92% rename from jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Rev.java rename to core/src/main/java/com/arangodb/serde/annotation/Rev.java index 86a7a5ee1..bf0b5c2c0 100644 --- a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/Rev.java +++ b/core/src/main/java/com/arangodb/serde/annotation/Rev.java @@ -1,4 +1,4 @@ -package com.arangodb.serde.jsonb; +package com.arangodb.serde.annotation; import jakarta.json.bind.annotation.JsonbAnnotation; import jakarta.json.bind.annotation.JsonbProperty; diff --git a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/To.java b/core/src/main/java/com/arangodb/serde/annotation/To.java similarity index 92% rename from jsonb-serde/src/main/java/com/arangodb/serde/jsonb/To.java rename to core/src/main/java/com/arangodb/serde/annotation/To.java index 89b4ef7d2..9163254f1 100644 --- a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/To.java +++ b/core/src/main/java/com/arangodb/serde/annotation/To.java @@ -1,4 +1,4 @@ -package com.arangodb.serde.jsonb; +package com.arangodb.serde.annotation; import jakarta.json.bind.annotation.JsonbAnnotation; import jakarta.json.bind.annotation.JsonbProperty; diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/From.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/From.java deleted file mode 100644 index 8a5b12021..000000000 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/From.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface From { -} diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Id.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Id.java deleted file mode 100644 index da57af859..000000000 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Id.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Id { -} diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Key.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Key.java deleted file mode 100644 index a066db02b..000000000 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Key.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Key { -} diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Rev.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Rev.java deleted file mode 100644 index 71dcac153..000000000 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/Rev.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Rev { -} diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/To.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/To.java deleted file mode 100644 index 8886a1ef4..000000000 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/To.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface To { -} diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java index d91fb31f6..b1d6465ed 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java @@ -1,5 +1,6 @@ package com.arangodb.serde.jackson.internal; +import com.arangodb.serde.annotation.*; import com.arangodb.serde.jackson.*; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.PropertyName; diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/From.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/From.java deleted file mode 100644 index d41d2dd7f..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/From.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson3; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface From { -} diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Id.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Id.java deleted file mode 100644 index ae8977f58..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Id.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson3; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Id { -} diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Key.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Key.java deleted file mode 100644 index 1bfdd7331..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Key.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson3; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Key { -} diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Rev.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Rev.java deleted file mode 100644 index e3b8e7e69..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/Rev.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson3; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Rev { -} diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/To.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/To.java deleted file mode 100644 index 335cdbe98..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/To.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson3; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -public @interface To { -} diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java index d11cc435d..b53c1916b 100644 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java +++ b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java @@ -1,5 +1,6 @@ package com.arangodb.serde.jackson3.internal; +import com.arangodb.serde.annotation.*; import com.arangodb.serde.jackson3.*; import com.fasterxml.jackson.annotation.JsonInclude; import tools.jackson.databind.PropertyName; diff --git a/jsonb-serde/pom.xml b/jsonb-serde/pom.xml index 77313fe35..3e048f211 100644 --- a/jsonb-serde/pom.xml +++ b/jsonb-serde/pom.xml @@ -27,7 +27,6 @@ jakarta.json.bind jakarta.json.bind-api - 3.0.0 compile diff --git a/pom.xml b/pom.xml index 604b0bdc5..0dd058c0b 100644 --- a/pom.xml +++ b/pom.xml @@ -31,9 +31,9 @@ - 8 - 8 - 8 + 21 + 21 + 21 UTF-8 https://sonarcloud.io arangodb-1 @@ -265,6 +265,11 @@ jakarta.json-api 2.1.3 + + jakarta.json.bind + jakarta.json.bind-api + 3.0.0 + com.arangodb arangodb-java-driver diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 6af96a7cd..57f7ced00 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -24,10 +24,8 @@ import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.model.*; import com.arangodb.model.DocumentImportOptions.OnDuplicate; -import com.arangodb.serde.jackson.Id; +import com.arangodb.serde.annotation.*; import com.arangodb.serde.jackson.JacksonSerde; -import com.arangodb.serde.jackson.Key; -import com.arangodb.serde.jackson.Rev; import com.arangodb.util.*; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonTypeInfo; diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java index 9e43f7a64..3491e1a96 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -24,10 +24,8 @@ import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.model.*; import com.arangodb.model.DocumentImportOptions.OnDuplicate; -import com.arangodb.serde.jackson.Id; +import com.arangodb.serde.annotation.*; import com.arangodb.serde.jackson.JacksonSerde; -import com.arangodb.serde.jackson.Key; -import com.arangodb.serde.jackson.Rev; import com.arangodb.util.*; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonTypeInfo; diff --git a/test-functional/src/test/java/com/arangodb/mapping/annotations/AnnotatedEntity.java b/test-functional/src/test/java/com/arangodb/mapping/annotations/AnnotatedEntity.java index f26fb6f25..d3726c912 100644 --- a/test-functional/src/test/java/com/arangodb/mapping/annotations/AnnotatedEntity.java +++ b/test-functional/src/test/java/com/arangodb/mapping/annotations/AnnotatedEntity.java @@ -1,5 +1,6 @@ package com.arangodb.mapping.annotations; +import com.arangodb.serde.annotation.*; import com.arangodb.serde.jackson.*; import java.util.Objects; diff --git a/test-functional/src/test/java/com/arangodb/serde/CustomTypeHintTest.java b/test-functional/src/test/java/com/arangodb/serde/CustomTypeHintTest.java index 06d0bfc35..536fb95e6 100644 --- a/test-functional/src/test/java/com/arangodb/serde/CustomTypeHintTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/CustomTypeHintTest.java @@ -26,7 +26,7 @@ import com.arangodb.ArangoDatabase; import com.arangodb.config.ConfigUtils; import com.arangodb.model.DocumentCreateOptions; -import com.arangodb.serde.jackson.Key; +import com.arangodb.serde.annotation.*; import com.fasterxml.jackson.annotation.JsonTypeInfo; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; diff --git a/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java b/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java index d5a3a969c..8cfa3720c 100644 --- a/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java @@ -1,5 +1,6 @@ package com.arangodb.serde; +import com.arangodb.serde.annotation.*; import com.arangodb.serde.jackson.*; import com.arangodb.serde.jackson.json.JacksonJsonSerdeProvider; import com.fasterxml.jackson.databind.JsonNode; diff --git a/test-non-functional/src/test/java/example/graph/Circle.java b/test-non-functional/src/test/java/example/graph/Circle.java index a607998aa..fe200f80a 100644 --- a/test-non-functional/src/test/java/example/graph/Circle.java +++ b/test-non-functional/src/test/java/example/graph/Circle.java @@ -20,9 +20,7 @@ package example.graph; -import com.arangodb.serde.jackson.Id; -import com.arangodb.serde.jackson.Key; -import com.arangodb.serde.jackson.Rev; +import com.arangodb.serde.annotation.*; /** * @author a-brandt diff --git a/test-non-functional/src/test/java/example/graph/CircleEdge.java b/test-non-functional/src/test/java/example/graph/CircleEdge.java index 72c3a4afa..00bbe3560 100644 --- a/test-non-functional/src/test/java/example/graph/CircleEdge.java +++ b/test-non-functional/src/test/java/example/graph/CircleEdge.java @@ -20,7 +20,7 @@ package example.graph; -import com.arangodb.serde.jackson.*; +import com.arangodb.serde.annotation.*; /** * @author a-brandt diff --git a/test-non-functional/src/test/java/serde/Jackson3Person.java b/test-non-functional/src/test/java/serde/Jackson3Person.java index fd28e47c1..46cb97993 100644 --- a/test-non-functional/src/test/java/serde/Jackson3Person.java +++ b/test-non-functional/src/test/java/serde/Jackson3Person.java @@ -1,6 +1,6 @@ package serde; -import com.arangodb.serde.jackson3.Key; +import com.arangodb.serde.annotation.*; import com.fasterxml.jackson.annotation.JsonProperty; public record Jackson3Person( diff --git a/test-non-functional/src/test/java/serde/JacksonPerson.java b/test-non-functional/src/test/java/serde/JacksonPerson.java index e9589403d..8b59f21cf 100644 --- a/test-non-functional/src/test/java/serde/JacksonPerson.java +++ b/test-non-functional/src/test/java/serde/JacksonPerson.java @@ -1,6 +1,6 @@ package serde; -import com.arangodb.serde.jackson.Key; +import com.arangodb.serde.annotation.*; import com.fasterxml.jackson.annotation.JsonProperty; public record JacksonPerson( diff --git a/test-non-functional/src/test/java/serde/JsonBPerson.java b/test-non-functional/src/test/java/serde/JsonBPerson.java index 52598c229..32c1eab9a 100644 --- a/test-non-functional/src/test/java/serde/JsonBPerson.java +++ b/test-non-functional/src/test/java/serde/JsonBPerson.java @@ -1,7 +1,7 @@ package serde; -import com.arangodb.serde.jsonb.Key; +import com.arangodb.serde.annotation.*; import jakarta.json.bind.annotation.JsonbProperty; import java.util.Objects; From 2d65082fe666cb9e2ad39cdca0e41fd35bb40b14 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 10 Apr 2026 15:09:40 +0200 Subject: [PATCH 02/14] set Jackson 3 as internal serde --- core/pom.xml | 6 +- core/src/main/java/com/arangodb/ArangoDB.java | 32 +--- .../arangodb/entity/AbstractBaseDocument.java | 2 +- .../entity/AqlQueryExplainEntity.java | 10 +- .../com/arangodb/entity/CollectionType.java | 2 +- .../com/arangodb/entity/CursorEntity.java | 4 +- .../java/com/arangodb/entity/CursorStats.java | 2 +- .../com/arangodb/entity/EdgeDefinition.java | 2 +- .../arangodb/entity/InvertedIndexField.java | 2 +- .../entity/InvertedIndexPrimarySort.java | 6 +- .../java/com/arangodb/entity/LogLevel.java | 2 +- .../arangodb/entity/ReplicationFactor.java | 2 +- .../com/arangodb/entity/ShardingStrategy.java | 2 +- .../arangodb/entity/VectorIndexParams.java | 2 +- .../arangosearch/ArangoSearchCompression.java | 2 +- .../ArangoSearchPropertiesEntity.java | 2 +- .../entity/arangosearch/CollectionLink.java | 6 +- .../entity/arangosearch/FieldLink.java | 6 +- .../entity/arangosearch/PrimarySort.java | 2 +- .../entity/arangosearch/SearchAliasIndex.java | 6 +- .../SearchAliasPropertiesEntity.java | 2 +- .../entity/arangosearch/StoredValue.java | 6 +- .../analyzer/StopwordsAnalyzerProperties.java | 4 +- .../internal/InternalArangoCollection.java | 6 +- .../arangodb/internal/InternalArangoDB.java | 10 +- .../internal/config/ArangoConfig.java | 8 +- .../internal/net/ProtocolProvider.java | 3 - .../serde/InternalAnnotationIntrospector.java | 24 +-- .../internal/serde/InternalDeserializers.java | 85 ++++------ .../serde/InternalMapperProvider.java | 45 ++++-- .../internal/serde/InternalModule.java | 6 +- .../internal/serde/InternalSerde.java | 4 +- .../internal/serde/InternalSerdeImpl.java | 118 ++++++-------- .../internal/serde/InternalSerdeProvider.java | 8 +- .../internal/serde/InternalSerializers.java | 50 +++--- .../arangodb/internal/serde/JacksonUtils.java | 127 --------------- .../MultiDocumentEntityDeserializer.java | 28 ++-- .../internal/serde/RawUserDataValue.java | 3 +- .../arangodb/internal/serde/SerdeUtils.java | 53 +++---- .../internal/serde/UserDataDeserializer.java | 24 ++- .../internal/serde/UserDataSerializer.java | 14 +- .../com/arangodb/model/CollectionSchema.java | 4 +- .../ArangoSearchCreateOptions.java | 3 +- .../ArangoSearchPropertiesOptions.java | 2 +- .../reflect-config-serde.json | 112 ------------- .../reflect-config-spi.json | 11 -- .../resource-config-spi.json | 10 -- .../test/java/helper/NativeImageHelper.java | 21 ++- .../arangodb/http/HttpProtocolProvider.java | 6 - jackson-serde-json/pom.xml | 4 +- .../serde/jackson/JacksonMapperProvider.java | 40 ----- .../arangodb/serde/jackson/JacksonSerde.java | 25 +-- .../ArangoSerdeAnnotationIntrospector.java | 20 +-- .../jackson/internal/JacksonSerdeImpl.java | 46 ++---- .../json/JacksonJsonSerdeProvider.java | 3 +- jackson3-serde-json/pom.xml | 56 ------- .../arangodb/serde/jackson3/JacksonSerde.java | 36 ----- .../ArangoSerdeAnnotationIntrospector.java | 62 -------- .../jackson3/internal/JacksonSerdeImpl.java | 47 ------ .../json/JacksonJsonSerdeProvider.java | 14 -- .../native-image.properties | 3 - .../reflect-config-spi.json | 11 -- .../resource-config-spi.json | 10 -- .../com.arangodb.serde.ArangoSerdeProvider | 1 - pom.xml | 13 +- shaded/pom.xml | 13 -- test-functional/pom.xml | 22 --- .../arangodb/ArangoCollectionAsyncTest.java | 50 +++--- .../com/arangodb/ArangoCollectionTest.java | 50 +++--- .../java/com/arangodb/ArangoCursorTest.java | 2 +- .../java/com/arangodb/ArangoDBAsyncTest.java | 14 +- .../test/java/com/arangodb/ArangoDBTest.java | 38 ++--- .../com/arangodb/ArangoDatabaseAsyncTest.java | 47 ++---- .../java/com/arangodb/ArangoDatabaseTest.java | 30 +--- .../test/java/com/arangodb/BaseJunit5.java | 32 +--- .../java/com/arangodb/CompressionTest.java | 7 +- .../java/com/arangodb/RequestContextTest.java | 20 +-- .../java/com/arangodb/SerializableTest.java | 42 ++--- .../java/com/arangodb/UserAgentAsyncTest.java | 12 +- .../test/java/com/arangodb/UserAgentTest.java | 7 +- .../annotations/ArangoAnnotationsTest.java | 4 +- .../arangodb/serde/CustomSerdeAsyncTest.java | 55 ++++--- .../com/arangodb/serde/CustomSerdeTest.java | 49 +++--- .../serde/JacksonConfigurationTest.java | 3 +- .../serde/JacksonInterferenceTest.java | 35 ++--- .../java/com/arangodb/serde/SerdeTest.java | 8 +- .../META-INF/native-image/reflect-config.json | 18 --- .../test/resources/simplelogger.properties | 1 - test-non-functional/pom.xml | 19 --- .../src/test/java/CommunicationTest.java | 4 +- .../src/test/java/ConfigurationTest.java | 6 +- .../src/test/java/arch/SerdeArchTest.java | 7 - .../src/test/java/arch/ShadedArchTest.java | 14 +- .../ConnectionLoadBalanceTest.java | 3 +- .../src/test/java/example/ExampleBase.java | 4 +- .../src/test/java/example/FirstProject.java | 2 +- ...ueryWithSpecialReturnTypesExampleTest.java | 12 +- .../document/GetDocumentExampleTest.java | 8 +- .../document/InsertDocumentExampleTest.java | 6 +- .../graph/AQLActorsAndMoviesExampleTest.java | 3 +- .../java/example/graph/BaseGraphTest.java | 4 +- .../test/java/serde/InternalSerdeTest.java | 4 +- .../src/test/java/serde/Jackson3Person.java | 13 -- .../serde/Jackson3RequestContextTest.java | 147 ------------------ .../test/java/serde/Jackson3SerdeTest.java | 92 ----------- .../java/serde/JacksonRequestContextTest.java | 32 ++-- .../src/test/java/serde/JacksonSerdeTest.java | 16 +- .../java/serde/SerdeConfigurationTest.java | 43 ----- .../test/resources/simplelogger.properties | 1 - .../main/java/com/arangodb/SerdeBench.java | 12 +- .../src/test/java/resilience/ClusterTest.java | 14 +- .../logging/RequestLoggingTest.java | 7 +- .../test/java/resilience/mock/SerdeTest.java | 18 +-- tutorial/Tutorial.md | 2 +- .../maven/src/main/java/FirstProject.java | 2 - 115 files changed, 585 insertions(+), 1757 deletions(-) delete mode 100644 core/src/main/java/com/arangodb/internal/serde/JacksonUtils.java delete mode 100644 driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-spi.json delete mode 100644 driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/resource-config-spi.json delete mode 100644 jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonMapperProvider.java delete mode 100644 jackson3-serde-json/pom.xml delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/JacksonSerde.java delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/JacksonSerdeImpl.java delete mode 100644 jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/json/JacksonJsonSerdeProvider.java delete mode 100644 jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/native-image.properties delete mode 100644 jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/reflect-config-spi.json delete mode 100644 jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/resource-config-spi.json delete mode 100644 jackson3-serde-json/src/main/resources/META-INF/services/com.arangodb.serde.ArangoSerdeProvider delete mode 100644 test-non-functional/src/test/java/serde/Jackson3Person.java delete mode 100644 test-non-functional/src/test/java/serde/Jackson3RequestContextTest.java delete mode 100644 test-non-functional/src/test/java/serde/Jackson3SerdeTest.java diff --git a/core/pom.xml b/core/pom.xml index fb3ce1162..22d335116 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -25,12 +25,12 @@ compile - com.fasterxml.jackson.core + tools.jackson.core jackson-databind compile - com.fasterxml.jackson.core + tools.jackson.core jackson-core compile @@ -40,7 +40,7 @@ compile - com.fasterxml.jackson.datatype + tools.jackson.datatype jackson-datatype-jakarta-jsonp compile diff --git a/core/src/main/java/com/arangodb/ArangoDB.java b/core/src/main/java/com/arangodb/ArangoDB.java index 6356c1900..16a37a885 100644 --- a/core/src/main/java/com/arangodb/ArangoDB.java +++ b/core/src/main/java/com/arangodb/ArangoDB.java @@ -426,8 +426,6 @@ public ArangoDB build() { } ProtocolProvider protocolProvider = protocolProvider(config.getProtocol()); - config.setProtocolModule(protocolProvider.protocolModule()); - ConnectionFactory connectionFactory = protocolProvider.createConnectionFactory(config.getProtocolConfig()); Collection hostList = createHostList(connectionFactory); HostResolver hostResolver = createHostResolver(hostList, connectionFactory); @@ -732,7 +730,7 @@ public Builder responseQueueTimeSamples(final Integer responseQueueTimeSamples) * - body payload of requests and responses in {@link ArangoDB#execute(Request, Class)} *

* However, note that the following types will always be serialized and deserialized using the internal serde: - * - {@link com.fasterxml.jackson.databind.JsonNode} + * - {@link tools.jackson.databind.JsonNode} * - {@link com.arangodb.util.RawJson} * - {@link com.arangodb.util.RawBytes} * - {@link com.arangodb.entity.BaseDocument} @@ -828,29 +826,11 @@ protected ProtocolProvider protocolProvider(Protocol protocol) { @UnstableApi protected HostHandler createHostHandler(@UnstableApi final HostResolver hostResolver) { - - final HostHandler hostHandler; - - LoadBalancingStrategy loadBalancingStrategy = config.getLoadBalancingStrategy(); - if (loadBalancingStrategy != null) { - switch (loadBalancingStrategy) { - case ONE_RANDOM: - hostHandler = new RandomHostHandler(hostResolver, new FallbackHostHandler(hostResolver)); - break; - case ROUND_ROBIN: - hostHandler = new RoundRobinHostHandler(hostResolver); - break; - case NONE: - default: - hostHandler = new FallbackHostHandler(hostResolver); - break; - } - } else { - hostHandler = new FallbackHostHandler(hostResolver); - } - - LOG.debug("HostHandler is {}", hostHandler.getClass().getSimpleName()); - return hostHandler; + return switch (config.getLoadBalancingStrategy()) { + case ONE_RANDOM -> new RandomHostHandler(hostResolver, new FallbackHostHandler(hostResolver)); + case ROUND_ROBIN -> new RoundRobinHostHandler(hostResolver); + default -> new FallbackHostHandler(hostResolver); + }; } @UnstableApi diff --git a/core/src/main/java/com/arangodb/entity/AbstractBaseDocument.java b/core/src/main/java/com/arangodb/entity/AbstractBaseDocument.java index 5019834c8..e9e4bf8a2 100644 --- a/core/src/main/java/com/arangodb/entity/AbstractBaseDocument.java +++ b/core/src/main/java/com/arangodb/entity/AbstractBaseDocument.java @@ -45,7 +45,7 @@ abstract class AbstractBaseDocument implements Serializable { DocumentFields.KEY, DocumentFields.REV }; - private final HashMap properties; + private HashMap properties; AbstractBaseDocument() { properties = new HashMap<>(); diff --git a/core/src/main/java/com/arangodb/entity/AqlQueryExplainEntity.java b/core/src/main/java/com/arangodb/entity/AqlQueryExplainEntity.java index c4eb9ea22..1f061e4a6 100644 --- a/core/src/main/java/com/arangodb/entity/AqlQueryExplainEntity.java +++ b/core/src/main/java/com/arangodb/entity/AqlQueryExplainEntity.java @@ -68,7 +68,7 @@ public int hashCode() { } public static final class ExecutionPlan { - private final Map properties = new HashMap<>(); + private Map properties = new HashMap<>(); private Collection nodes; private Double estimatedCost; private Collection collections; @@ -118,7 +118,7 @@ public int hashCode() { } public static final class ExecutionNode { - private final Map properties = new HashMap<>(); + private Map properties = new HashMap<>(); @JsonAnySetter public void add(String key, Object value) { @@ -143,7 +143,7 @@ public int hashCode() { } public static final class ExecutionVariable { - private final Map properties = new HashMap<>(); + private Map properties = new HashMap<>(); @JsonAnySetter public void add(String key, Object value) { @@ -168,7 +168,7 @@ public int hashCode() { } public static final class ExecutionCollection { - private final Map properties = new HashMap<>(); + private Map properties = new HashMap<>(); @JsonAnySetter public void add(String key, Object value) { @@ -193,7 +193,7 @@ public int hashCode() { } public static final class ExecutionStats { - private final Map properties = new HashMap<>(); + private Map properties = new HashMap<>(); @JsonAnySetter public void add(String key, Object value) { diff --git a/core/src/main/java/com/arangodb/entity/CollectionType.java b/core/src/main/java/com/arangodb/entity/CollectionType.java index 7d771b67d..21fc46733 100644 --- a/core/src/main/java/com/arangodb/entity/CollectionType.java +++ b/core/src/main/java/com/arangodb/entity/CollectionType.java @@ -27,7 +27,7 @@ public enum CollectionType { DOCUMENT(2), EDGES(3); - private final int type; + private int type; CollectionType(final int type) { this.type = type; diff --git a/core/src/main/java/com/arangodb/entity/CursorEntity.java b/core/src/main/java/com/arangodb/entity/CursorEntity.java index 6070ddc1a..22fb93481 100644 --- a/core/src/main/java/com/arangodb/entity/CursorEntity.java +++ b/core/src/main/java/com/arangodb/entity/CursorEntity.java @@ -39,7 +39,7 @@ public final class CursorEntity { private List result; private Boolean potentialDirtyRead; private String nextBatchId; - private final Extras extra = new Extras(); + private Extras extra = new Extras(); public String getId() { return id; @@ -124,7 +124,7 @@ public int hashCode() { } public static final class Extras { - private final Collection warnings = Collections.emptyList(); + private Collection warnings = Collections.emptyList(); private CursorStats stats; public CursorStats getStats() { diff --git a/core/src/main/java/com/arangodb/entity/CursorStats.java b/core/src/main/java/com/arangodb/entity/CursorStats.java index 2d5ce96a3..2cbf04b3e 100644 --- a/core/src/main/java/com/arangodb/entity/CursorStats.java +++ b/core/src/main/java/com/arangodb/entity/CursorStats.java @@ -7,7 +7,7 @@ import java.util.Objects; public final class CursorStats { - private final Map properties = new HashMap<>(); + private Map properties = new HashMap<>(); private Long writesExecuted; private Long writesIgnored; private Long scannedFull; diff --git a/core/src/main/java/com/arangodb/entity/EdgeDefinition.java b/core/src/main/java/com/arangodb/entity/EdgeDefinition.java index 021aab42c..5ef461ad6 100644 --- a/core/src/main/java/com/arangodb/entity/EdgeDefinition.java +++ b/core/src/main/java/com/arangodb/entity/EdgeDefinition.java @@ -32,7 +32,7 @@ public final class EdgeDefinition { private String collection; private Collection from; private Collection to; - private final Options options = new Options(); + private Options options = new Options(); public String getCollection() { return collection; diff --git a/core/src/main/java/com/arangodb/entity/InvertedIndexField.java b/core/src/main/java/com/arangodb/entity/InvertedIndexField.java index a05167612..155ee4058 100644 --- a/core/src/main/java/com/arangodb/entity/InvertedIndexField.java +++ b/core/src/main/java/com/arangodb/entity/InvertedIndexField.java @@ -15,7 +15,7 @@ public final class InvertedIndexField { private Boolean searchField; private Boolean trackListPositions; private Boolean cache; - private final Set features = new HashSet<>(); + private Set features = new HashSet<>(); private Collection nested; public String getName() { diff --git a/core/src/main/java/com/arangodb/entity/InvertedIndexPrimarySort.java b/core/src/main/java/com/arangodb/entity/InvertedIndexPrimarySort.java index b1b00105f..3d35f5ac1 100644 --- a/core/src/main/java/com/arangodb/entity/InvertedIndexPrimarySort.java +++ b/core/src/main/java/com/arangodb/entity/InvertedIndexPrimarySort.java @@ -14,7 +14,7 @@ * @since ArangoDB 3.10 */ public final class InvertedIndexPrimarySort { - private final List fields = new ArrayList<>(); + private List fields = new ArrayList<>(); private ArangoSearchCompression compression; private Boolean cache; @@ -75,8 +75,8 @@ public int hashCode() { } public static class Field { - private final String field; - private final Direction direction; + private String field; + private Direction direction; /** * @param field An attribute path. The . character denotes sub-attributes. diff --git a/core/src/main/java/com/arangodb/entity/LogLevel.java b/core/src/main/java/com/arangodb/entity/LogLevel.java index 8895bfa7a..b61c00268 100644 --- a/core/src/main/java/com/arangodb/entity/LogLevel.java +++ b/core/src/main/java/com/arangodb/entity/LogLevel.java @@ -27,7 +27,7 @@ public enum LogLevel { FATAL(0), ERROR(1), WARNING(2), INFO(3), DEBUG(4); - private final int level; + private int level; LogLevel(final int level) { this.level = level; diff --git a/core/src/main/java/com/arangodb/entity/ReplicationFactor.java b/core/src/main/java/com/arangodb/entity/ReplicationFactor.java index 60e56e4af..aed17806a 100644 --- a/core/src/main/java/com/arangodb/entity/ReplicationFactor.java +++ b/core/src/main/java/com/arangodb/entity/ReplicationFactor.java @@ -46,7 +46,7 @@ public String get() { final class NumericReplicationFactor implements ReplicationFactor { - private final Integer value; + private Integer value; public NumericReplicationFactor(Integer value) { this.value = value; diff --git a/core/src/main/java/com/arangodb/entity/ShardingStrategy.java b/core/src/main/java/com/arangodb/entity/ShardingStrategy.java index 384e51554..2c78c8c14 100644 --- a/core/src/main/java/com/arangodb/entity/ShardingStrategy.java +++ b/core/src/main/java/com/arangodb/entity/ShardingStrategy.java @@ -32,7 +32,7 @@ public enum ShardingStrategy { ENTERPRISE_HASH_SMART_EDGE("enterprise-hash-smart-edge"), ENTERPRISE_HEX_SMART_VERTEX("enterprise-hex-smart-vertex"); - private final String internalName; + private String internalName; ShardingStrategy(String internalName) { this.internalName = internalName; diff --git a/core/src/main/java/com/arangodb/entity/VectorIndexParams.java b/core/src/main/java/com/arangodb/entity/VectorIndexParams.java index a03267dba..d29a166e9 100644 --- a/core/src/main/java/com/arangodb/entity/VectorIndexParams.java +++ b/core/src/main/java/com/arangodb/entity/VectorIndexParams.java @@ -82,7 +82,7 @@ public VectorIndexParams metric(Metric metric) { return this; } - public Integer getnLists() { + public Integer getNLists() { return nLists; } diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/ArangoSearchCompression.java b/core/src/main/java/com/arangodb/entity/arangosearch/ArangoSearchCompression.java index 6bc05ee4c..23d9f8948 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/ArangoSearchCompression.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/ArangoSearchCompression.java @@ -37,7 +37,7 @@ public enum ArangoSearchCompression { */ none("none"); - private final String value; + private String value; ArangoSearchCompression(String value) { this.value = value; diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/ArangoSearchPropertiesEntity.java b/core/src/main/java/com/arangodb/entity/arangosearch/ArangoSearchPropertiesEntity.java index d17861430..915a26920 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/ArangoSearchPropertiesEntity.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/ArangoSearchPropertiesEntity.java @@ -22,7 +22,7 @@ import com.arangodb.entity.ViewEntity; import com.arangodb.internal.serde.InternalDeserializers; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonDeserialize; import java.util.Collection; import java.util.Objects; diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java b/core/src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java index 467b380c2..48d7a8cec 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java @@ -25,8 +25,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import java.util.Arrays; import java.util.Collection; @@ -37,7 +37,7 @@ */ public final class CollectionLink { - private final String name; + private String name; private Collection analyzers; private Boolean includeAllFields; private Boolean trackListPositions; diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/FieldLink.java b/core/src/main/java/com/arangodb/entity/arangosearch/FieldLink.java index 5d76a95db..7df48e6d2 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/FieldLink.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/FieldLink.java @@ -5,8 +5,8 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import java.util.Arrays; import java.util.Collection; @@ -14,7 +14,7 @@ public final class FieldLink { - private final String name; + private String name; private Collection analyzers; private Boolean includeAllFields; private Boolean trackListPositions; diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/PrimarySort.java b/core/src/main/java/com/arangodb/entity/arangosearch/PrimarySort.java index 5b82d830e..aaa5f8302 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/PrimarySort.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/PrimarySort.java @@ -30,7 +30,7 @@ */ public final class PrimarySort { - private final String fieldName; + private String fieldName; private Boolean ascending; public PrimarySort( diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/SearchAliasIndex.java b/core/src/main/java/com/arangodb/entity/arangosearch/SearchAliasIndex.java index 7d92d2768..281c05a0e 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/SearchAliasIndex.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/SearchAliasIndex.java @@ -10,9 +10,9 @@ * @since ArabgoDB 3.10 */ public final class SearchAliasIndex { - private final String collection; - private final String index; - private final OperationType operation; + private String collection; + private String index; + private OperationType operation; /** * @param collection The name of a collection. diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/SearchAliasPropertiesEntity.java b/core/src/main/java/com/arangodb/entity/arangosearch/SearchAliasPropertiesEntity.java index 208c17664..30e3658d6 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/SearchAliasPropertiesEntity.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/SearchAliasPropertiesEntity.java @@ -31,7 +31,7 @@ */ public final class SearchAliasPropertiesEntity extends ViewEntity { - private final Collection indexes = new ArrayList<>(); + private Collection indexes = new ArrayList<>(); /** * @return A list of inverted indexes to add to the View. diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/StoredValue.java b/core/src/main/java/com/arangodb/entity/arangosearch/StoredValue.java index 824db2066..999966eac 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/StoredValue.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/StoredValue.java @@ -33,9 +33,9 @@ */ public final class StoredValue { - private final List fields; - private final ArangoSearchCompression compression; - private final Boolean cache; + private List fields; + private ArangoSearchCompression compression; + private Boolean cache; /** * @param fields A list of attribute paths. The . character denotes sub-attributes. diff --git a/core/src/main/java/com/arangodb/entity/arangosearch/analyzer/StopwordsAnalyzerProperties.java b/core/src/main/java/com/arangodb/entity/arangosearch/analyzer/StopwordsAnalyzerProperties.java index daa3d4e04..72034c05d 100644 --- a/core/src/main/java/com/arangodb/entity/arangosearch/analyzer/StopwordsAnalyzerProperties.java +++ b/core/src/main/java/com/arangodb/entity/arangosearch/analyzer/StopwordsAnalyzerProperties.java @@ -33,8 +33,8 @@ */ public final class StopwordsAnalyzerProperties { - private final List stopwords; - private final boolean hex; + private List stopwords; + private boolean hex; public StopwordsAnalyzerProperties() { stopwords = new ArrayList<>(); diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java index 1ff995d86..a4d5ea622 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java @@ -27,7 +27,7 @@ import com.arangodb.internal.util.RequestUtils; import com.arangodb.model.*; import com.arangodb.util.RawData; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import java.lang.reflect.Type; import java.util.ArrayList; @@ -392,7 +392,7 @@ protected ResponseDeserializer> getIndexesResponseDeseri return (response) -> { Collection indexes = new ArrayList<>(); for (JsonNode idx : getSerde().parse(response.getBody(), "/indexes")) { - if (!"inverted".equals(idx.get("type").textValue())) { + if (!"inverted".equals(idx.get("type").stringValue())) { indexes.add(getSerde().deserialize(idx, IndexEntity.class)); } } @@ -404,7 +404,7 @@ protected ResponseDeserializer> getInvertedIndex return (response) -> { Collection indexes = new ArrayList<>(); for (JsonNode idx : getSerde().parse(response.getBody(), "/indexes")) { - if ("inverted".equals(idx.get("type").textValue())) { + if ("inverted".equals(idx.get("type").stringValue())) { indexes.add(getSerde().deserialize(idx, InvertedIndexEntity.class)); } } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoDB.java b/core/src/main/java/com/arangodb/internal/InternalArangoDB.java index a07fe4c07..0b3019054 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoDB.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoDB.java @@ -100,15 +100,7 @@ protected InternalRequest getAccessibleDatabasesForRequest(final String dbName, } protected ResponseDeserializer> getAccessibleDatabasesForResponseDeserializer() { - return (response) -> { - Iterator names = - getSerde().parse(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER).fieldNames(); - final Collection dbs = new ArrayList<>(); - while (names.hasNext()) { - dbs.add(names.next()); - } - return dbs; - }; + return (response) -> getSerde().parse(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER).propertyNames(); } protected InternalRequest createUserRequest( diff --git a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java index f4c08e0cc..7d5c7ea88 100644 --- a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java +++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java @@ -12,7 +12,6 @@ import com.arangodb.internal.serde.InternalSerdeProvider; import com.arangodb.serde.ArangoSerde; import com.arangodb.serde.ArangoSerdeProvider; -import com.fasterxml.jackson.databind.Module; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; @@ -57,7 +56,6 @@ public class ArangoConfig { private ArangoSerde userDataSerde; private Class serdeProviderClass; private Integer responseQueueTimeSamples; - private Module protocolModule; private Executor asyncExecutor; private Compression compression; private Integer compressionThreshold; @@ -314,7 +312,7 @@ public ArangoSerde getUserDataSerde() { public InternalSerde getInternalSerde() { if (internalSerde == null) { - internalSerde = new InternalSerdeProvider().create(getUserDataSerde(), protocolModule); + internalSerde = new InternalSerdeProvider().create(getUserDataSerde()); } return internalSerde; } @@ -335,10 +333,6 @@ public void setResponseQueueTimeSamples(Integer responseQueueTimeSamples) { this.responseQueueTimeSamples = responseQueueTimeSamples; } - public void setProtocolModule(Module m) { - protocolModule = m; - } - public Executor getAsyncExecutor() { return asyncExecutor; } diff --git a/core/src/main/java/com/arangodb/internal/net/ProtocolProvider.java b/core/src/main/java/com/arangodb/internal/net/ProtocolProvider.java index 9e573e993..b5c1b0ca8 100644 --- a/core/src/main/java/com/arangodb/internal/net/ProtocolProvider.java +++ b/core/src/main/java/com/arangodb/internal/net/ProtocolProvider.java @@ -5,7 +5,6 @@ import com.arangodb.arch.UsedInApi; import com.arangodb.config.ProtocolConfig; import com.arangodb.internal.config.ArangoConfig; -import com.fasterxml.jackson.databind.Module; @UsedInApi public interface ProtocolProvider { @@ -17,6 +16,4 @@ default ConnectionFactory createConnectionFactory(ProtocolConfig config) { } CommunicationProtocol createProtocol(ArangoConfig config, HostHandler hostHandler); - - Module protocolModule(); } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalAnnotationIntrospector.java b/core/src/main/java/com/arangodb/internal/serde/InternalAnnotationIntrospector.java index d0655cfd5..7596c60b8 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalAnnotationIntrospector.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalAnnotationIntrospector.java @@ -1,11 +1,13 @@ package com.arangodb.internal.serde; -import com.fasterxml.jackson.databind.introspect.Annotated; -import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import tools.jackson.databind.cfg.MapperConfig; +import tools.jackson.databind.introspect.Annotated; +import tools.jackson.databind.introspect.JacksonAnnotationIntrospector; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.Serial; class InternalAnnotationIntrospector extends JacksonAnnotationIntrospector { @@ -21,45 +23,47 @@ class InternalAnnotationIntrospector extends JacksonAnnotationIntrospector { } @Override - public Object findSerializer(Annotated a) { + public Object findSerializer(MapperConfig config, Annotated a) { if (a.getAnnotation(UserData.class) != null) { return userDataSerializer; } else { - return super.findSerializer(a); + return super.findSerializer(config, a); } } @Override - public Object findContentSerializer(Annotated a) { + public Object findContentSerializer(MapperConfig config, Annotated a) { if (a.getAnnotation(UserDataInside.class) != null) { return userDataSerializer; } else { - return super.findContentSerializer(a); + return super.findContentSerializer(config, a); } } @Override - public Object findDeserializer(Annotated a) { + public Object findDeserializer(MapperConfig config, Annotated a) { if (a.getAnnotation(UserData.class) != null) { return userDataDeserializer; } else { - return super.findDeserializer(a); + return super.findDeserializer(config, a); } } @Override - public Object findContentDeserializer(Annotated a) { + public Object findContentDeserializer(MapperConfig config, Annotated a) { if (a.getAnnotation(UserDataInside.class) != null) { return userDataDeserializer; } else { - return super.findContentDeserializer(a); + return super.findContentDeserializer(config, a); } } + @Serial private void writeObject(ObjectOutputStream out) throws IOException { throw new IOException("Serialization not allowed"); } + @Serial private void readObject(ObjectInputStream in) throws IOException { throw new IOException("Deserialization not allowed"); } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java b/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java index 3ff874ad7..3a47805f6 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java @@ -8,17 +8,13 @@ import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import com.arangodb.internal.InternalResponse; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.*; - -import java.io.IOException; -import java.io.StringWriter; +import tools.jackson.core.JsonParser; +import tools.jackson.core.TreeNode; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.node.*; + import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; @@ -27,52 +23,43 @@ public final class InternalDeserializers { - static final JsonDeserializer RAW_JSON_DESERIALIZER = new JsonDeserializer() { + static final ValueDeserializer RAW_JSON_DESERIALIZER = new ValueDeserializer<>() { @Override - public RawJson deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - if (JsonFactory.FORMAT_NAME_JSON.equals(p.getCodec().getFactory().getFormatName())) { - return RawJson.of(new String(SerdeUtils.extractBytes(p), StandardCharsets.UTF_8)); - } else { - StringWriter w = new StringWriter(); - try (JsonGenerator gen = SerdeUtils.INSTANCE.getJsonMapper().getFactory().createGenerator(w)) { - gen.copyCurrentStructure(p); - gen.flush(); - } - return RawJson.of(w.toString()); - } + public RawJson deserialize(JsonParser p, DeserializationContext ctxt) { + return RawJson.of(new String(SerdeUtils.extractBytes(p), StandardCharsets.UTF_8)); } }; - static final JsonDeserializer RAW_BYTES_DESERIALIZER = new JsonDeserializer() { + static final ValueDeserializer RAW_BYTES_DESERIALIZER = new ValueDeserializer<>() { @Override - public RawBytes deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public RawBytes deserialize(JsonParser p, DeserializationContext ctxt) { return RawBytes.of(SerdeUtils.extractBytes(p)); } }; - static final JsonDeserializer COLLECTION_TYPE = new JsonDeserializer() { + static final ValueDeserializer COLLECTION_TYPE = new ValueDeserializer<>() { @Override - public CollectionType deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { + public CollectionType deserialize(final JsonParser p, final DeserializationContext ctxt) { return CollectionType.fromType(p.getIntValue()); } }; - static final JsonDeserializer REPLICATION_FACTOR = new JsonDeserializer() { + static final ValueDeserializer REPLICATION_FACTOR = new ValueDeserializer<>() { @Override - public ReplicationFactor deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { + public ReplicationFactor deserialize(final JsonParser p, final DeserializationContext ctxt) { TreeNode node = p.readValueAsTree(); if (node instanceof NumericNode) { return ReplicationFactor.of(((NumericNode) node).intValue()); - } else if (node instanceof TextNode && "satellite".equals(((TextNode) node).textValue())) { + } else if (node instanceof StringNode && "satellite".equals(((StringNode) node).stringValue())) { return ReplicationFactor.ofSatellite(); } else throw new IllegalArgumentException(); } }; @SuppressWarnings("unchecked") - static final JsonDeserializer RESPONSE = new JsonDeserializer() { + static final ValueDeserializer RESPONSE = new ValueDeserializer<>() { @Override - public InternalResponse deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { + public InternalResponse deserialize(final JsonParser p, final DeserializationContext ctxt) { final InternalResponse response = new InternalResponse(); Iterator it = ((ArrayNode) p.readValueAsTree()).iterator(); response.setVersion(it.next().intValue()); @@ -85,11 +72,11 @@ public InternalResponse deserialize(final JsonParser p, final DeserializationCon } }; - static final JsonDeserializer INVERTED_INDEX_PRIMARY_SORT_FIELD = new JsonDeserializer() { + static final ValueDeserializer INVERTED_INDEX_PRIMARY_SORT_FIELD = new ValueDeserializer<>() { @Override - public InvertedIndexPrimarySort.Field deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { + public InvertedIndexPrimarySort.Field deserialize(final JsonParser p, final DeserializationContext ctxt) { ObjectNode tree = p.readValueAsTree(); - String field = tree.get("field").textValue(); + String field = tree.get("field").stringValue(); InvertedIndexPrimarySort.Field.Direction direction = tree.get("asc").booleanValue() ? InvertedIndexPrimarySort.Field.Direction.asc : InvertedIndexPrimarySort.Field.Direction.desc; return new InvertedIndexPrimarySort.Field(field, direction); @@ -99,22 +86,16 @@ public InvertedIndexPrimarySort.Field deserialize(final JsonParser p, final Dese private InternalDeserializers() { } - private static T readTreeAsValue(JsonParser p, DeserializationContext ctxt, JsonNode n, Class targetType) throws IOException { - try (TreeTraversingParser t = new TreeTraversingParser(n, p.getCodec())) { - t.nextToken(); - return ctxt.readValue(t, targetType); - } + private static T readTreeAsValue(JsonParser p, DeserializationContext ctxt, JsonNode n, Class targetType) { + return ctxt.readTreeAsValue(n, targetType); } - public static class CollectionLinksDeserializer extends JsonDeserializer> { - + public static class CollectionLinksDeserializer extends ValueDeserializer> { @Override - public Collection deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public Collection deserialize(JsonParser p, DeserializationContext ctxt) { Collection out = new ArrayList<>(); ObjectNode tree = p.readValueAsTree(); - Iterator> it = tree.fields(); - while (it.hasNext()) { - Map.Entry e = it.next(); + for (Map.Entry e : tree.properties()) { ObjectNode v = (ObjectNode) e.getValue(); v.put("name", e.getKey()); out.add(readTreeAsValue(p, ctxt, v, CollectionLink.class)); @@ -123,15 +104,13 @@ public Collection deserialize(JsonParser p, DeserializationConte } } - public static class FieldLinksDeserializer extends JsonDeserializer { + public static class FieldLinksDeserializer extends ValueDeserializer { @Override - public FieldLink[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public FieldLink[] deserialize(JsonParser p, DeserializationContext ctxt) { Collection out = new ArrayList<>(); ObjectNode tree = p.readValueAsTree(); - Iterator> it = tree.fields(); - while (it.hasNext()) { - Map.Entry e = it.next(); + for (Map.Entry e : tree.properties()) { ObjectNode v = (ObjectNode) e.getValue(); v.put("name", e.getKey()); out.add(readTreeAsValue(p, ctxt, v, FieldLink.class)); @@ -140,9 +119,9 @@ public FieldLink[] deserialize(JsonParser p, DeserializationContext ctxt) throws } } - public static class CollectionSchemaRuleDeserializer extends JsonDeserializer { + public static class CollectionSchemaRuleDeserializer extends ValueDeserializer { @Override - public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public String deserialize(JsonParser p, DeserializationContext ctxt) { return SerdeUtils.INSTANCE.writeJson(p.readValueAsTree()); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java b/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java index eed6cfb18..c04f36ca6 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java @@ -1,10 +1,15 @@ package com.arangodb.internal.serde; import com.arangodb.ArangoDBException; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import tools.jackson.core.StreamReadConstraints; +import tools.jackson.core.StreamReadFeature; +import tools.jackson.core.StreamWriteConstraints; +import tools.jackson.core.TokenStreamFactory; +import tools.jackson.core.json.JsonFactory; +import tools.jackson.core.json.JsonWriteFeature; +import tools.jackson.databind.json.JsonMapper; import java.util.Iterator; import java.util.ServiceConfigurationError; @@ -13,22 +18,40 @@ class InternalMapperProvider { private static final Logger LOG = LoggerFactory.getLogger(InternalMapperProvider.class); - static ObjectMapper load() { - ServiceLoader sl = ServiceLoader.load(JsonFactory.class); - Iterator iterator = sl.iterator(); + static JsonMapper load() { + ServiceLoader sl = ServiceLoader.load(TokenStreamFactory.class); + Iterator iterator = sl.iterator(); while (iterator.hasNext()) { - JsonFactory jf; + TokenStreamFactory tsf; try { - jf = iterator.next(); + tsf = iterator.next(); } catch (ServiceConfigurationError e) { LOG.warn("ServiceLoader failed to load JsonFactory", e); continue; } - if ("JSON".equals(jf.getFormatName())) { - JacksonUtils.tryConfigureJsonFactory(jf); - return new ObjectMapper(jf); + if (!"JSON".equals(tsf.getFormatName())) { + LOG.debug("JSON not supported by TokenStreamFactory: {}", tsf.getClass().getName()); + } else if (!(tsf instanceof JsonFactory jf)) { + LOG.debug("TokenStreamFactory is not instance of JsonFactory: {}", tsf.getClass().getName()); + } else { + return new JsonMapper( + jf.rebuild() + .disable(JsonWriteFeature.ESCAPE_FORWARD_SLASHES) + .disable(JsonWriteFeature.COMBINE_UNICODE_SURROGATES_IN_UTF8) + .enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION) + .streamReadConstraints(StreamReadConstraints.builder() + .maxNumberLength(Integer.MAX_VALUE) + .maxStringLength(Integer.MAX_VALUE) + .maxNestingDepth(Integer.MAX_VALUE) + .maxNameLength(Integer.MAX_VALUE) + .maxDocumentLength(Long.MAX_VALUE) + .maxTokenCount(Integer.MAX_VALUE) + .build()) + .streamWriteConstraints(StreamWriteConstraints.builder() + .maxNestingDepth(Integer.MAX_VALUE) + .build()) + .build()); } - LOG.debug("JSON not supported by JsonFactory: {}", jf.getClass().getName()); } throw new ArangoDBException("No JsonFactory found for content type JSON"); } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalModule.java b/core/src/main/java/com/arangodb/internal/serde/InternalModule.java index 9cfecd8bb..5d9471a77 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalModule.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalModule.java @@ -8,12 +8,12 @@ import com.arangodb.util.RawJson; import com.arangodb.internal.InternalRequest; import com.arangodb.internal.InternalResponse; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.module.SimpleModule; +import tools.jackson.databind.JacksonModule; +import tools.jackson.databind.module.SimpleModule; class InternalModule { - static Module get(InternalSerde serde) { + static JacksonModule get(InternalSerde serde) { SimpleModule module = new SimpleModule(); module.addDeserializer(MultiDocumentEntity.class, new MultiDocumentEntityDeserializer(serde)); diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java index 6f17a8ed1..183913838 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java @@ -2,8 +2,8 @@ import com.arangodb.arch.UsedInApi; import com.arangodb.serde.ArangoSerde; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.JsonNode; import java.lang.reflect.Type; diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java index 8bd24ba31..24b8960b9 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -6,24 +6,17 @@ import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsonp.JSONPModule; import jakarta.json.JsonException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import tools.jackson.core.*; +import tools.jackson.core.json.JsonFactory; +import tools.jackson.databind.*; +import tools.jackson.databind.exc.MismatchedInputException; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.datatype.jsonp.JSONPModule; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; @@ -38,39 +31,40 @@ final class InternalSerdeImpl implements InternalSerde { } private final ArangoSerde userSerde; - private final ObjectMapper mapper; + private final JsonMapper mapper; + + InternalSerdeImpl(final JsonMapper mapper, final ArangoSerde userSerde) { + var builder = mapper.rebuild() + .deactivateDefaultTyping() + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .addModule(InternalModule.get(this)) + .enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION) + .changeDefaultPropertyInclusion(i -> i.withValueInclusion(JsonInclude.Include.NON_NULL)) + .annotationIntrospector(new InternalAnnotationIntrospector( + new UserDataSerializer(this), + new UserDataDeserializer(this) + )); - InternalSerdeImpl(final ObjectMapper mapper, final ArangoSerde userSerde, final Module protocolModule) { - this.mapper = mapper; - this.userSerde = userSerde; - mapper.deactivateDefaultTyping(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.enable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION); - mapper.registerModule(InternalModule.get(this)); - if (protocolModule != null) { - mapper.registerModule(protocolModule); - } - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - mapper.setAnnotationIntrospector(new InternalAnnotationIntrospector( - new UserDataSerializer(this), - new UserDataDeserializer(this) - )); // JSON-P datatypes + JSONPModule jsonPModule = null; try { - mapper.registerModule(new JSONPModule()); + jsonPModule = new JSONPModule(); } catch (JsonException e) { LOG.debug("Jakarta JSON-P provider not found, handling of JSON-P datatypes is disabled", e); } + + if (jsonPModule != null) { + builder.addModule(jsonPModule); + } + + this.userSerde = userSerde; + this.mapper = builder.build(); } @Override public byte[] serialize(final Object value) { - try { - return mapper.writeValueAsBytes(value); - } catch (JsonProcessingException e) { - throw ArangoDBException.of(e); - } + return mapper.writeValueAsBytes(value); } @Override @@ -96,7 +90,7 @@ public byte[] extract(final byte[] content, final String jsonPointer) { throw new ArangoDBException("Unsupported JSON pointer: " + jsonPointer); } String[] parts = jsonPointer.substring(1).split("/"); - try (JsonParser parser = mapper.getFactory().createParser(content)) { + try (JsonParser parser = mapper.tokenStreamFactory().createParser(content)) { int match = 0; int level = 0; JsonToken token = parser.nextToken(); @@ -114,7 +108,7 @@ public byte[] extract(final byte[] content, final String jsonPointer) { if (token == null || level < match) { throw new ArangoDBException("Unable to parse JSON pointer: " + jsonPointer); } - if (token == JsonToken.FIELD_NAME && match == level && parts[match].equals(parser.getText())) { + if (token == JsonToken.PROPERTY_NAME && match == level && parts[match].equals(parser.getString())) { match++; if (match == parts.length) { parser.nextToken(); @@ -122,18 +116,12 @@ public byte[] extract(final byte[] content, final String jsonPointer) { } } } - } catch (IOException e) { - throw ArangoDBException.of(e); } } @Override public JsonNode parse(byte[] content, String jsonPointer) { - try { - return mapper.readTree(content).at(jsonPointer); - } catch (IOException e) { - throw ArangoDBException.of(e); - } + return mapper.readTree(content).at(jsonPointer); } @Override @@ -144,7 +132,7 @@ public byte[] serializeUserData(Object value) { Class clazz = value.getClass(); if (RawBytes.class.equals(clazz)) { return ((RawBytes) value).get(); - } else if (RawJson.class.equals(clazz) && JsonFactory.FORMAT_NAME_JSON.equals(mapper.getFactory().getFormatName())) { + } else if (RawJson.class.equals(clazz) && JsonFactory.FORMAT_NAME_JSON.equals(mapper.tokenStreamFactory().getFormatName())) { return ((RawJson) value).get().getBytes(StandardCharsets.UTF_8); } else if (SerdeUtils.isManagedClass(clazz)) { return serialize(value); @@ -156,15 +144,13 @@ public byte[] serializeUserData(Object value) { @Override public byte[] serializeCollectionUserData(Iterable value) { ByteArrayOutputStream os = new ByteArrayOutputStream(); - try (JsonGenerator gen = mapper.getFactory().createGenerator(os)) { + try (JsonGenerator gen = mapper.tokenStreamFactory().createGenerator(os)) { gen.writeStartArray(); for (Object o : value) { gen.writeRawValue(new RawUserDataValue(serializeUserData(o))); } gen.writeEndArray(); gen.flush(); - } catch (IOException e) { - throw ArangoDBException.of(e); } return os.toByteArray(); } @@ -181,20 +167,16 @@ public T deserializeUserData(byte[] content, Class clazz) { @Override @SuppressWarnings("unchecked") public T deserializeUserData(byte[] content, JavaType clazz) { - try { - if (SerdeUtils.isManagedClass(clazz.getRawClass())) { - return mapper.readerFor(clazz).readValue(content); - } else { - return deserializeUserData(content, (Class) clazz.getRawClass()); - } - } catch (IOException e) { - throw ArangoDBException.of(e); + if (SerdeUtils.isManagedClass(clazz.getRawClass())) { + return mapper.readerFor(clazz).readValue(content); + } else { + return deserializeUserData(content, (Class) clazz.getRawClass()); } } @Override public boolean isDocument(byte[] content) { - try (JsonParser p = mapper.getFactory().createParser(content)) { + try (JsonParser p = mapper.tokenStreamFactory().createParser(content)) { if (p.nextToken() != JsonToken.START_OBJECT) { return false; } @@ -202,8 +184,8 @@ public boolean isDocument(byte[] content) { int level = 1; while (level >= 1) { JsonToken t = p.nextToken(); - if (level == 1 && t == JsonToken.FIELD_NAME) { - String fieldName = p.getText(); + if (level == 1 && t == JsonToken.PROPERTY_NAME) { + String fieldName = p.getString(); if (fieldName.equals("_id") || fieldName.equals("_key") || fieldName.equals("_rev")) { return true; } @@ -216,10 +198,8 @@ public boolean isDocument(byte[] content) { } if (p.currentToken() != JsonToken.END_OBJECT) { - throw new JsonMappingException(p, "Expected END_OBJECT but got " + p.currentToken()); + throw MismatchedInputException.from(p, "Expected END_OBJECT but got " + p.currentToken()); } - } catch (IOException e) { - throw ArangoDBException.of(e); } return false; } @@ -231,11 +211,7 @@ public ArangoSerde getUserSerde() { @Override public T deserialize(final JsonNode node, final Type type) { - try { - return mapper.readerFor(mapper.constructType(type)).readValue(node); - } catch (IOException e) { - throw ArangoDBException.of(e); - } + return mapper.readerFor(mapper.constructType(type)).readValue(node); } @Override @@ -246,14 +222,10 @@ public T deserialize(final byte[] content, final Type type) { } if (RawBytes.class.equals(type)) { return (T) RawBytes.of(content); - } else if (RawJson.class.equals(type) && JsonFactory.FORMAT_NAME_JSON.equals(mapper.getFactory().getFormatName())) { + } else if (RawJson.class.equals(type) && JsonFactory.FORMAT_NAME_JSON.equals(mapper.tokenStreamFactory().getFormatName())) { return (T) RawJson.of(new String(content, StandardCharsets.UTF_8)); } else { - try { - return mapper.readerFor(mapper.constructType(type)).readValue(content); - } catch (IOException e) { - throw ArangoDBException.of(e); - } + return mapper.readerFor(mapper.constructType(type)).readValue(content); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java index 069068370..32ba02623 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java @@ -2,7 +2,6 @@ import com.arangodb.serde.ArangoSerde; import com.arangodb.serde.ArangoSerdeProvider; -import com.fasterxml.jackson.databind.Module; public class InternalSerdeProvider implements ArangoSerdeProvider { @@ -13,18 +12,17 @@ public class InternalSerdeProvider implements ArangoSerdeProvider { */ @Override public InternalSerde create() { - return create(null, null); + return create(null); } /** * Creates a new InternalSerde with default settings. * * @param userSerde user serde - * @param protocolModule optional Jackson module to support protocol specific types * @return the created InternalSerde */ - public InternalSerde create(ArangoSerde userSerde, Module protocolModule) { - return new InternalSerdeImpl(InternalMapperProvider.load(), userSerde, protocolModule); + public InternalSerde create(ArangoSerde userSerde) { + return new InternalSerdeImpl(InternalMapperProvider.load(), userSerde); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerializers.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerializers.java index db156dff8..81e30ffa9 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerializers.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerializers.java @@ -6,13 +6,10 @@ import com.arangodb.internal.ArangoRequestParam; import com.arangodb.util.RawJson; import com.arangodb.internal.InternalRequest; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; -import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.HashMap; @@ -21,22 +18,15 @@ public final class InternalSerializers { - static final JsonSerializer RAW_JSON_SERIALIZER = new JsonSerializer() { + static final ValueSerializer RAW_JSON_SERIALIZER = new ValueSerializer<>() { @Override - public void serialize(RawJson value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - if (JsonFactory.FORMAT_NAME_JSON.equals(gen.getCodec().getFactory().getFormatName())) { - gen.writeRawValue(new RawUserDataValue(value.get().getBytes(StandardCharsets.UTF_8))); - } else { - try (JsonParser parser = SerdeUtils.INSTANCE.getJsonMapper().getFactory().createParser(value.get())) { - parser.nextToken(); - gen.copyCurrentStructure(parser); - } - } + public void serialize(RawJson value, JsonGenerator gen, SerializationContext ctxt) { + gen.writeRawValue(new RawUserDataValue(value.get().getBytes(StandardCharsets.UTF_8))); } }; - static final JsonSerializer REQUEST = new JsonSerializer() { + static final ValueSerializer REQUEST = new ValueSerializer<>() { @Override - public void serialize(InternalRequest value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(InternalRequest value, JsonGenerator gen, SerializationContext ctxt) { gen.writeStartArray(); gen.writeNumber(value.getVersion()); gen.writeNumber(value.getType()); @@ -45,20 +35,20 @@ public void serialize(InternalRequest value, JsonGenerator gen, SerializerProvid gen.writeString(value.getPath()); gen.writeStartObject(); for (final Map.Entry entry : value.getQueryParam().entrySet()) { - gen.writeStringField(entry.getKey(), entry.getValue()); + gen.writeStringProperty(entry.getKey(), entry.getValue()); } gen.writeEndObject(); gen.writeStartObject(); for (final Map.Entry entry : value.getHeaderParam().entrySet()) { - gen.writeStringField(entry.getKey(), entry.getValue()); + gen.writeStringProperty(entry.getKey(), entry.getValue()); } gen.writeEndObject(); gen.writeEndArray(); } }; - static final JsonSerializer COLLECTION_TYPE = new JsonSerializer() { + static final ValueSerializer COLLECTION_TYPE = new ValueSerializer<>() { @Override - public void serialize(CollectionType value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(CollectionType value, JsonGenerator gen, SerializationContext ctxt) { gen.writeNumber(value.getType()); } }; @@ -66,32 +56,32 @@ public void serialize(CollectionType value, JsonGenerator gen, SerializerProvide private InternalSerializers() { } - public static class CollectionSchemaRuleSerializer extends JsonSerializer { + public static class CollectionSchemaRuleSerializer extends ValueSerializer { @Override - public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(String value, JsonGenerator gen, SerializationContext ctxt) { gen.writeTree(SerdeUtils.INSTANCE.parseJson(value)); } } - public static class FieldLinksSerializer extends JsonSerializer> { + public static class FieldLinksSerializer extends ValueSerializer> { @Override - public void serialize(Collection value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(Collection value, JsonGenerator gen, SerializationContext ctxt) { Map mapLikeValue = new HashMap<>(); for (FieldLink fl : value) { mapLikeValue.put(fl.getName(), fl); } - gen.writeObject(mapLikeValue); + ctxt.writeValue(gen, mapLikeValue); } } - public static class CollectionLinksSerializer extends JsonSerializer> { + public static class CollectionLinksSerializer extends ValueSerializer> { @Override - public void serialize(Collection value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(Collection value, JsonGenerator gen, SerializationContext ctxt) { Map mapLikeValue = new HashMap<>(); for (CollectionLink cl : value) { mapLikeValue.put(cl.getName(), cl); } - gen.writeObject(mapLikeValue); + ctxt.writeValue(gen, mapLikeValue); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/JacksonUtils.java b/core/src/main/java/com/arangodb/internal/serde/JacksonUtils.java deleted file mode 100644 index a0db1c8eb..000000000 --- a/core/src/main/java/com/arangodb/internal/serde/JacksonUtils.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.arangodb.internal.serde; - -import com.arangodb.internal.ShadedProxy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class JacksonUtils { - private static final Logger LOG = LoggerFactory.getLogger(JacksonUtils.class); - - private JacksonUtils() { - } - - public interface Version { - int getMajorVersion(); - - int getMinorVersion(); - - String toString(); - } - - public interface StreamReadConstraints { - - interface Static { - Builder builder(); - } - - interface Builder { - Builder maxNumberLength(final int maxNumLen); - - Builder maxStringLength(int maxStringLen); - - Builder maxNestingDepth(int maxNestingDepth); - - Builder maxNameLength(int maxNameLen); - - Builder maxDocumentLength(long maxDocLen); - - StreamReadConstraints build(); - } - } - - public interface StreamWriteConstraints { - interface Static { - Builder builder(); - } - - interface Builder { - Builder maxNestingDepth(int maxNestingDepth); - - StreamWriteConstraints build(); - } - } - - public interface JsonFactory { - Version version(); - - @SuppressWarnings("UnusedReturnValue") - JsonFactory setStreamReadConstraints(StreamReadConstraints src); - - @SuppressWarnings("UnusedReturnValue") - JsonFactory setStreamWriteConstraints(StreamWriteConstraints swc); - } - - /** - * Configure JsonFactory with permissive StreamReadConstraints and StreamWriteConstraints. - * It uses reflection to avoid compilation errors with older Jackson versions. - * It uses dynamic package names to be compatible with shaded Jackson. - * - * @param jf JsonFactory to configure - */ - public static void tryConfigureJsonFactory(Object jf) { - try { - configureJsonFactory(jf); - } catch (Throwable t) { - LOG.warn("Got exception while configuring JsonFactory, skipping...", t); - } - } - - private static void configureJsonFactory(Object jf) throws Exception { - JsonFactory proxy = ShadedProxy.of(JsonFactory.class, jf); - Version version = proxy.version(); - LOG.debug("Detected Jackson version: {}", version); - - // get pkg name dynamically, to support shaded Jackson - String basePkg = jf.getClass().getPackage().getName(); - - if (isAtLeastVersion(version, 2, 15)) { - Class srcClass = Class.forName(basePkg + "." + StreamReadConstraints.class.getSimpleName()); - StreamReadConstraints.Builder builder = ShadedProxy.of(StreamReadConstraints.Static.class, srcClass) - .builder() - .maxNumberLength(Integer.MAX_VALUE) - .maxStringLength(Integer.MAX_VALUE) - .maxNestingDepth(Integer.MAX_VALUE); - if (isAtLeastVersion(version, 2, 16)) { - builder = builder - .maxNameLength(Integer.MAX_VALUE) - .maxDocumentLength(Long.MAX_VALUE); - } else { - LOG.debug("Skipping configuring StreamReadConstraints maxNameLength"); - LOG.debug("Skipping configuring StreamReadConstraints maxDocumentLength"); - } - proxy.setStreamReadConstraints(builder.build()); - } else { - LOG.debug("Skipping configuring StreamReadConstraints"); - } - - if (isAtLeastVersion(version, 2, 16)) { - LOG.debug("Configuring StreamWriteConstraints ..."); - Class swcClass = Class.forName(basePkg + "." + StreamWriteConstraints.class.getSimpleName()); - StreamWriteConstraints swc = ShadedProxy.of(StreamWriteConstraints.Static.class, swcClass) - .builder() - .maxNestingDepth(Integer.MAX_VALUE) - .build(); - proxy.setStreamWriteConstraints(swc); - } else { - LOG.debug("Skipping configuring StreamWriteConstraints"); - } - } - - @SuppressWarnings("SameParameterValue") - private static boolean isAtLeastVersion(Version version, int major, int minor) { - int currentMajor = version.getMajorVersion(); - int currentMinor = version.getMinorVersion(); - return currentMajor > major || (currentMajor == major && currentMinor >= minor); - } - -} diff --git a/core/src/main/java/com/arangodb/internal/serde/MultiDocumentEntityDeserializer.java b/core/src/main/java/com/arangodb/internal/serde/MultiDocumentEntityDeserializer.java index ca650569d..a27cb700b 100644 --- a/core/src/main/java/com/arangodb/internal/serde/MultiDocumentEntityDeserializer.java +++ b/core/src/main/java/com/arangodb/internal/serde/MultiDocumentEntityDeserializer.java @@ -2,18 +2,16 @@ import com.arangodb.entity.ErrorEntity; import com.arangodb.entity.MultiDocumentEntity; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.BeanProperty; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.deser.ContextualDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.BeanProperty; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.exc.MismatchedInputException; -import java.io.IOException; -public class MultiDocumentEntityDeserializer extends JsonDeserializer> implements ContextualDeserializer { +public class MultiDocumentEntityDeserializer extends ValueDeserializer> { private final JavaType containedType; private final InternalSerde serde; @@ -27,7 +25,7 @@ public class MultiDocumentEntityDeserializer extends JsonDeserializer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public MultiDocumentEntity deserialize(JsonParser p, DeserializationContext ctxt) { MultiDocumentEntity multiDocument = new MultiDocumentEntity<>(); // silent=true returns an empty object @@ -35,17 +33,17 @@ public MultiDocumentEntity deserialize(JsonParser p, DeserializationContext c if (p.nextToken() == JsonToken.END_OBJECT) { return multiDocument; } else { - throw new JsonMappingException(p, "Unexpected token sequence: START_OBJECT, " + p.currentToken()); + throw MismatchedInputException.from(p, "Unexpected token sequence: START_OBJECT, " + p.currentToken()); } } if (p.currentToken() != JsonToken.START_ARRAY) { - throw new JsonMappingException(p, "Expected START_ARRAY but got " + p.currentToken()); + throw MismatchedInputException.from(p, "Expected START_ARRAY but got " + p.currentToken()); } p.nextToken(); while (p.currentToken() != JsonToken.END_ARRAY) { if (p.currentToken() != JsonToken.START_OBJECT) { - throw new JsonMappingException(p, "Expected START_OBJECT but got " + p.currentToken()); + throw MismatchedInputException.from(p, "Expected START_OBJECT but got " + p.currentToken()); } byte[] element = SerdeUtils.extractBytes(p); if (serde.isDocument(element)) { @@ -63,7 +61,7 @@ public MultiDocumentEntity deserialize(JsonParser p, DeserializationContext c } @Override - public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) { + public ValueDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) { return new MultiDocumentEntityDeserializer(serde, ctxt.getContextualType().containedType(0)); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java b/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java index 039741043..fdd3d8da5 100644 --- a/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java +++ b/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java @@ -1,6 +1,7 @@ package com.arangodb.internal.serde; -import com.fasterxml.jackson.core.SerializableString; + +import tools.jackson.core.SerializableString; import java.io.IOException; import java.io.OutputStream; diff --git a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java index e8e903fe9..2681f4b91 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java @@ -5,33 +5,30 @@ import com.arangodb.entity.BaseEdgeDocument; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.TypeFactory; import jakarta.json.JsonValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; -import java.io.IOException; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +// TODO: make static methods instance methods public enum SerdeUtils { INSTANCE; private static final Logger LOGGER = LoggerFactory.getLogger(SerdeUtils.class); - private final ObjectMapper jsonMapper = new ObjectMapper(); + private final JsonMapper jsonMapper = new JsonMapper(); public static Type constructListType(Class clazz) { - return TypeFactory.defaultInstance().constructCollectionType(List.class, clazz); + return INSTANCE.jsonMapper.getTypeFactory().constructCollectionType(List.class, clazz); } public static Type constructParametricType(Class rawType, Type... rawArgs) { @@ -53,8 +50,8 @@ public static Type convertToType(final JavaType javaType) { static void checkSupportedJacksonVersion() { Arrays.asList( - com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION, - com.fasterxml.jackson.core.json.PackageVersion.VERSION + tools.jackson.databind.cfg.PackageVersion.VERSION, + tools.jackson.core.json.PackageVersion.VERSION ).forEach(version -> { int major = version.getMajorVersion(); int minor = version.getMinorVersion(); @@ -64,7 +61,7 @@ static void checkSupportedJacksonVersion() { }); } - public ObjectMapper getJsonMapper() { + public JsonMapper getJsonMapper() { return jsonMapper; } @@ -75,11 +72,7 @@ public ObjectMapper getJsonMapper() { * @return root of the parsed tree */ public JsonNode parseJson(final String json) { - try { - return jsonMapper.readTree(json); - } catch (JsonProcessingException e) { - throw ArangoDBException.of(e); - } + return jsonMapper.readTree(json); } /** @@ -87,28 +80,22 @@ public JsonNode parseJson(final String json) { * @return JSON string */ public String writeJson(final JsonNode data) { - try { - return jsonMapper.writeValueAsString(data); - } catch (JsonProcessingException e) { - throw ArangoDBException.of(e); - } + return jsonMapper.writeValueAsString(data); } /** * Extract raw bytes for the current JSON node * - * @param parser JsonParser with current token pointing to the node to extract + * @param parser JsonParser with the current token pointing to the node to extract * @return byte array */ - @SuppressWarnings("deprecation") - public static byte[] extractBytes(JsonParser parser) throws IOException { + public static byte[] extractBytes(JsonParser parser) { JsonToken t = parser.currentToken(); - if (t.isStructEnd() || t == JsonToken.FIELD_NAME) { + if (t.isStructEnd() || t == JsonToken.PROPERTY_NAME) { throw new ArangoDBException("Unexpected token: " + t); } - byte[] data = (byte[]) parser.getTokenLocation().getSourceRef(); - int start = (int) parser.getTokenLocation().getByteOffset(); - int end = (int) parser.getCurrentLocation().getByteOffset(); + byte[] data = (byte[]) parser.currentTokenLocation().contentReference().getRawContent(); + int start = (int) parser.currentTokenLocation().getByteOffset(); if (t.isStructStart()) { int open = 1; while (open > 0) { @@ -121,9 +108,7 @@ public static byte[] extractBytes(JsonParser parser) throws IOException { } } parser.finishToken(); - if (JsonFactory.FORMAT_NAME_JSON.equals(parser.getCodec().getFactory().getFormatName())) { - end = (int) parser.getCurrentLocation().getByteOffset(); - } + int end = (int) parser.currentLocation().getByteOffset(); return Arrays.copyOfRange(data, start, end); } diff --git a/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java b/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java index ecb8c83f3..f84232712 100644 --- a/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java +++ b/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java @@ -1,19 +1,17 @@ package com.arangodb.internal.serde; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.BeanProperty; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.deser.ContextualDeserializer; -import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; - -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.BeanProperty; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.jsontype.TypeDeserializer; + import java.lang.reflect.Type; import static com.arangodb.internal.serde.SerdeUtils.convertToType; -class UserDataDeserializer extends JsonDeserializer implements ContextualDeserializer { +class UserDataDeserializer extends ValueDeserializer { private final Type targetType; private final InternalSerde serde; @@ -28,7 +26,7 @@ private UserDataDeserializer(final JavaType targetType, final InternalSerde serd } @Override - public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public Object deserialize(JsonParser p, DeserializationContext ctxt) { Class clazz = (Class) targetType; if (SerdeUtils.isManagedClass(clazz)) { return p.readValueAs(clazz); @@ -38,12 +36,12 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx } @Override - public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException { + public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) { return deserialize(p, ctxt); } @Override - public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) { + public ValueDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) { return new UserDataDeserializer(ctxt.getContextualType(), serde); } diff --git a/core/src/main/java/com/arangodb/internal/serde/UserDataSerializer.java b/core/src/main/java/com/arangodb/internal/serde/UserDataSerializer.java index 501998da4..3c36a26ce 100644 --- a/core/src/main/java/com/arangodb/internal/serde/UserDataSerializer.java +++ b/core/src/main/java/com/arangodb/internal/serde/UserDataSerializer.java @@ -1,13 +1,11 @@ package com.arangodb.internal.serde; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; -import java.io.IOException; - -class UserDataSerializer extends JsonSerializer { +class UserDataSerializer extends ValueSerializer { private final InternalSerde serde; UserDataSerializer(InternalSerde serde) { @@ -15,7 +13,7 @@ class UserDataSerializer extends JsonSerializer { } @Override - public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(Object value, JsonGenerator gen, SerializationContext ctxt) { if (value != null && JsonNode.class.isAssignableFrom(value.getClass())) { gen.writeTree((JsonNode) value); } else { diff --git a/core/src/main/java/com/arangodb/model/CollectionSchema.java b/core/src/main/java/com/arangodb/model/CollectionSchema.java index b6665c117..2623c0942 100644 --- a/core/src/main/java/com/arangodb/model/CollectionSchema.java +++ b/core/src/main/java/com/arangodb/model/CollectionSchema.java @@ -25,8 +25,8 @@ import com.arangodb.internal.serde.InternalDeserializers; import com.arangodb.internal.serde.InternalSerializers; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; /** * @author Michele Rastelli diff --git a/core/src/main/java/com/arangodb/model/arangosearch/ArangoSearchCreateOptions.java b/core/src/main/java/com/arangodb/model/arangosearch/ArangoSearchCreateOptions.java index baf67f9e3..7af5907eb 100644 --- a/core/src/main/java/com/arangodb/model/arangosearch/ArangoSearchCreateOptions.java +++ b/core/src/main/java/com/arangodb/model/arangosearch/ArangoSearchCreateOptions.java @@ -23,8 +23,7 @@ import com.arangodb.entity.ViewType; import com.arangodb.entity.arangosearch.*; import com.arangodb.internal.serde.InternalSerializers; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonSerialize; import java.util.Arrays; import java.util.Collection; diff --git a/core/src/main/java/com/arangodb/model/arangosearch/ArangoSearchPropertiesOptions.java b/core/src/main/java/com/arangodb/model/arangosearch/ArangoSearchPropertiesOptions.java index 912540c7f..3747c219e 100644 --- a/core/src/main/java/com/arangodb/model/arangosearch/ArangoSearchPropertiesOptions.java +++ b/core/src/main/java/com/arangodb/model/arangosearch/ArangoSearchPropertiesOptions.java @@ -24,7 +24,7 @@ import com.arangodb.entity.arangosearch.ConsolidationPolicy; import com.arangodb.entity.arangosearch.PrimarySort; import com.arangodb.internal.serde.InternalSerializers; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.annotation.JsonSerialize; import java.util.Arrays; import java.util.Collection; diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-serde.json b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-serde.json index c50a5e113..e8fc825ff 100644 --- a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-serde.json +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-serde.json @@ -30,117 +30,5 @@ { "name": "com.arangodb.internal.serde.JacksonUtils$Version", "queryAllDeclaredMethods": true - }, - { - "name": "com.fasterxml.jackson.core.JsonFactory", - "queryAllPublicMethods": true, - "methods": [ - { - "name": "setStreamReadConstraints", - "parameterTypes": [ - "com.fasterxml.jackson.core.StreamReadConstraints" - ] - }, - { - "name": "setStreamWriteConstraints", - "parameterTypes": [ - "com.fasterxml.jackson.core.StreamWriteConstraints" - ] - }, - { - "name": "version", - "parameterTypes": [] - } - ] - }, - { - "name": "com.fasterxml.jackson.core.StreamReadConstraints", - "queryAllPublicMethods": true, - "methods": [ - { - "name": "builder", - "parameterTypes": [] - } - ] - }, - { - "name": "com.fasterxml.jackson.core.StreamReadConstraints$Builder", - "queryAllPublicMethods": true, - "methods": [ - { - "name": "build", - "parameterTypes": [] - }, - { - "name": "maxDocumentLength", - "parameterTypes": [ - "long" - ] - }, - { - "name": "maxNameLength", - "parameterTypes": [ - "int" - ] - }, - { - "name": "maxNestingDepth", - "parameterTypes": [ - "int" - ] - }, - { - "name": "maxNumberLength", - "parameterTypes": [ - "int" - ] - }, - { - "name": "maxStringLength", - "parameterTypes": [ - "int" - ] - } - ] - }, - { - "name": "com.fasterxml.jackson.core.StreamWriteConstraints", - "queryAllPublicMethods": true, - "methods": [ - { - "name": "builder", - "parameterTypes": [] - } - ] - }, - { - "name": "com.fasterxml.jackson.core.StreamWriteConstraints$Builder", - "queryAllPublicMethods": true, - "methods": [ - { - "name": "build", - "parameterTypes": [] - }, - { - "name": "maxNestingDepth", - "parameterTypes": [ - "int" - ] - } - ] - }, - { - "name": "com.fasterxml.jackson.core.Version", - "queryAllPublicMethods": true, - "methods": [ - { - "name": "getMajorVersion", - "parameterTypes": [] - }, - { - "name": "getMinorVersion", - "parameterTypes": [] - } - ] } ] \ No newline at end of file diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-spi.json b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-spi.json deleted file mode 100644 index cf082f1dd..000000000 --- a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-spi.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "name": "com.fasterxml.jackson.core.JsonFactory", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - } -] diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/resource-config-spi.json b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/resource-config-spi.json deleted file mode 100644 index 7fb12eab0..000000000 --- a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/resource-config-spi.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "resources": { - "includes": [ - { - "pattern": "META-INF/services/com.fasterxml.jackson.core.JsonFactory" - } - ] - }, - "bundles": [] -} diff --git a/driver/src/test/java/helper/NativeImageHelper.java b/driver/src/test/java/helper/NativeImageHelper.java index 8b923b840..7386395e8 100644 --- a/driver/src/test/java/helper/NativeImageHelper.java +++ b/driver/src/test/java/helper/NativeImageHelper.java @@ -1,16 +1,15 @@ package helper; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.reflections.Reflections; import org.reflections.scanners.SubTypesScanner; import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; import org.reflections.util.FilterBuilder; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.ValueSerializer; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; import java.net.URL; import java.util.Arrays; @@ -24,11 +23,11 @@ * @author Michele Rastelli */ public class NativeImageHelper { - public static void main(String[] args) throws JsonProcessingException { + public static void main(String[] args) { generateReflectConfig(); } - private static void generateReflectConfig() throws JsonProcessingException { + private static void generateReflectConfig() { System.out.println("---------------------------"); System.out.println("--- reflect-config.json ---"); System.out.println("---------------------------"); @@ -39,7 +38,7 @@ private static void generateReflectConfig() throws JsonProcessingException { "com.arangodb.internal.cursor.entity" ); - ObjectMapper mapper = new ObjectMapper(); + JsonMapper mapper = new JsonMapper(); ArrayNode rootNode = mapper.createArrayNode(); String internalSerdePackage = "com.arangodb.internal.serde"; @@ -48,10 +47,10 @@ private static void generateReflectConfig() throws JsonProcessingException { .setScanners(new SubTypesScanner(false)) .setUrls(serdeUrls) .filterInputsBy(new FilterBuilder().includePackage(internalSerdePackage))); - Stream serializers = r.getSubTypesOf(JsonSerializer.class).stream() + Stream serializers = r.getSubTypesOf(ValueSerializer.class).stream() .filter(it -> !it.isAnonymousClass()) .map(Class::getName); - Stream deserializers = r.getSubTypesOf(JsonDeserializer.class).stream() + Stream deserializers = r.getSubTypesOf(ValueDeserializer.class).stream() .filter(it -> !it.isAnonymousClass()) .map(Class::getName); Stream serdeClasses = Stream.concat(serializers, deserializers) diff --git a/http-protocol/src/main/java/com/arangodb/http/HttpProtocolProvider.java b/http-protocol/src/main/java/com/arangodb/http/HttpProtocolProvider.java index 7783b1d52..847dd05c4 100644 --- a/http-protocol/src/main/java/com/arangodb/http/HttpProtocolProvider.java +++ b/http-protocol/src/main/java/com/arangodb/http/HttpProtocolProvider.java @@ -8,7 +8,6 @@ import com.arangodb.internal.net.ConnectionFactory; import com.arangodb.internal.net.HostHandler; import com.arangodb.internal.net.ProtocolProvider; -import com.fasterxml.jackson.databind.Module; @UnstableApi public class HttpProtocolProvider implements ProtocolProvider { @@ -31,9 +30,4 @@ public CommunicationProtocol createProtocol(@UnstableApi ArangoConfig config, @U return new HttpProtocol(new HttpCommunication(config, hostHandler)); } - @Override - public Module protocolModule() { - return null; - } - } diff --git a/jackson-serde-json/pom.xml b/jackson-serde-json/pom.xml index 9ff2d6e9d..4046f5018 100644 --- a/jackson-serde-json/pom.xml +++ b/jackson-serde-json/pom.xml @@ -25,12 +25,12 @@ provided - com.fasterxml.jackson.core + tools.jackson.core jackson-databind compile - com.fasterxml.jackson.core + tools.jackson.core jackson-core compile diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonMapperProvider.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonMapperProvider.java deleted file mode 100644 index 2008cba72..000000000 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonMapperProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.arangodb.serde.jackson; - -import com.arangodb.ArangoDBException; -import com.arangodb.internal.serde.JacksonUtils; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Iterator; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; - -/** - * Not shaded in arangodb-java-driver-shaded. - */ -public class JacksonMapperProvider { - private static final Logger LOG = LoggerFactory.getLogger(JacksonMapperProvider.class); - - public static ObjectMapper load() { - ServiceLoader sl = ServiceLoader.load(JsonFactory.class); - Iterator iterator = sl.iterator(); - while (iterator.hasNext()) { - JsonFactory jf; - try { - jf = iterator.next(); - } catch (ServiceConfigurationError e) { - LOG.warn("ServiceLoader failed to load JsonFactory", e); - continue; - } - if ("JSON".equals(jf.getFormatName())) { - JacksonUtils.tryConfigureJsonFactory(jf); - return new ObjectMapper(jf); - } - LOG.debug("JSON not supported by JsonFactory: {}", jf.getClass().getName()); - } - - throw new ArangoDBException("No JsonFactory found for content type JSON"); - } -} diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerde.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerde.java index 8059960b5..485f06d9c 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerde.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerde.java @@ -3,10 +3,8 @@ import com.arangodb.serde.ArangoSerde; import com.arangodb.RequestContext; import com.arangodb.serde.jackson.internal.JacksonSerdeImpl; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.function.Consumer; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.json.JsonMapper; import static com.arangodb.serde.jackson.internal.JacksonSerdeImpl.SERDE_CONTEXT_ATTRIBUTE_NAME; @@ -16,21 +14,21 @@ public interface JacksonSerde extends ArangoSerde { /** - * Creates a new JacksonSerde with default settings. + * Creates a new JacksonSerde. * * @return the created JacksonSerde */ - static JacksonSerde load() { - return create(JacksonMapperProvider.load()); + static JacksonSerde create() { + return create(new JsonMapper()); } /** - * Creates a new JacksonSerde using the provided ObjectMapper. + * Creates a new JacksonSerde using the provided JsonMapper. * - * @param mapper Jackson ObjectMapper to use + * @param mapper Jackson JsonMapper to use * @return the created JacksonSerde */ - static JacksonSerde create(final ObjectMapper mapper) { + static JacksonSerde create(final JsonMapper mapper) { return new JacksonSerdeImpl(mapper); } @@ -44,11 +42,4 @@ static RequestContext getRequestContext(DeserializationContext ctx) { return (RequestContext) ctx.getAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME); } - /** - * Allows configuring the underlying Jackson ObjectMapper - * - * @param configureFunction function to configure the Jackson ObjectMapper - */ - JacksonSerde configure(final Consumer configureFunction); - } diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java index b1d6465ed..95110fb3b 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java @@ -1,11 +1,11 @@ package com.arangodb.serde.jackson.internal; import com.arangodb.serde.annotation.*; -import com.arangodb.serde.jackson.*; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.PropertyName; -import com.fasterxml.jackson.databind.introspect.Annotated; -import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import tools.jackson.databind.PropertyName; +import tools.jackson.databind.cfg.MapperConfig; +import tools.jackson.databind.introspect.Annotated; +import tools.jackson.databind.introspect.JacksonAnnotationIntrospector; import java.lang.annotation.Annotation; import java.util.HashMap; @@ -32,13 +32,13 @@ private static class JsonIncludeNonNull { } @Override - public PropertyName findNameForSerialization(Annotated a) { - return Optional.ofNullable(findMapping(a)).orElseGet(() -> super.findNameForSerialization(a)); + public PropertyName findNameForSerialization(MapperConfig config, Annotated a) { + return Optional.ofNullable(findMapping(a)).orElseGet(() -> super.findNameForSerialization(config, a)); } @Override - public PropertyName findNameForDeserialization(Annotated a) { - return Optional.ofNullable(findMapping(a)).orElseGet(() -> super.findNameForDeserialization(a)); + public PropertyName findNameForDeserialization(MapperConfig config, Annotated a) { + return Optional.ofNullable(findMapping(a)).orElseGet(() -> super.findNameForDeserialization(config, a)); } private PropertyName findMapping(Annotated a) { @@ -51,11 +51,11 @@ private PropertyName findMapping(Annotated a) { } @Override - public JsonInclude.Value findPropertyInclusion(Annotated a) { + public JsonInclude.Value findPropertyInclusion(MapperConfig config, Annotated a) { if (_hasOneOf(a, ANNOTATIONS)) { return new JsonInclude.Value(JSON_INCLUDE_NON_NULL); } else { - return super.findPropertyInclusion(a); + return super.findPropertyInclusion(config, a); } } } diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java index f7c5b2a5a..c6c6e28bc 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java @@ -2,14 +2,9 @@ import com.arangodb.RequestContext; import com.arangodb.serde.jackson.JacksonSerde; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.cfg.ContextAttributes; - -import java.io.IOException; -import java.util.Objects; -import java.util.function.Consumer; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.cfg.ContextAttributes; +import tools.jackson.databind.json.JsonMapper; /** @@ -18,21 +13,18 @@ public final class JacksonSerdeImpl implements JacksonSerde { public static final String SERDE_CONTEXT_ATTRIBUTE_NAME = "arangoRequestContext"; - private final ObjectMapper mapper; + private final JsonMapper mapper; - public JacksonSerdeImpl(final ObjectMapper mapper) { - this.mapper = mapper; - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setAnnotationIntrospector(new ArangoSerdeAnnotationIntrospector()); + public JacksonSerdeImpl(final JsonMapper mapper) { + this.mapper = mapper.rebuild() + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .annotationIntrospector(new ArangoSerdeAnnotationIntrospector()) + .build(); } @Override public byte[] serialize(final Object value) { - try { - return mapper.writeValueAsBytes(value); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + return mapper.writeValueAsBytes(value); } @Override @@ -42,23 +34,11 @@ public T deserialize(final byte[] content, final Class type) { @Override public T deserialize(byte[] content, Class type, RequestContext ctx) { - Objects.requireNonNull(ctx); if (content == null || content.length == 0) { return null; } - try { - return mapper.readerFor(mapper.constructType(type)) - .with(ContextAttributes.getEmpty().withPerCallAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) - .readValue(content); - } catch (IOException e) { - throw new RuntimeException(e); - } + return mapper.readerFor(mapper.constructType(type)) + .with(ContextAttributes.getEmpty().withPerCallAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) + .readValue(content); } - - @Override - public JacksonSerde configure(Consumer configureFunction) { - configureFunction.accept(mapper); - return this; - } - } diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java index 7a3ba8967..1df637914 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java @@ -3,10 +3,11 @@ import com.arangodb.serde.ArangoSerde; import com.arangodb.serde.ArangoSerdeProvider; import com.arangodb.serde.jackson.JacksonSerde; +import tools.jackson.databind.json.JsonMapper; public class JacksonJsonSerdeProvider implements ArangoSerdeProvider { @Override public ArangoSerde create() { - return JacksonSerde.load(); + return JacksonSerde.create(new JsonMapper()); } } diff --git a/jackson3-serde-json/pom.xml b/jackson3-serde-json/pom.xml deleted file mode 100644 index 235377f66..000000000 --- a/jackson3-serde-json/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - 4.0.0 - - - com.arangodb - arangodb-java-driver-parent - 8.0.0-SNAPSHOT - - - jackson3-serde-json - jackson3-serde-json - Jackson 3 Serde JSON module for ArangoDB Java Driver - - - com.arangodb.serde.jackson3.json - - - - - - tools.jackson - jackson-bom - 3.1.0 - import - pom - - - - - - - com.arangodb - core - provided - - - tools.jackson.core - jackson-databind - compile - - - tools.jackson.core - jackson-core - compile - - - com.fasterxml.jackson.core - jackson-annotations - compile - - - - \ No newline at end of file diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/JacksonSerde.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/JacksonSerde.java deleted file mode 100644 index ce7dce0b8..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/JacksonSerde.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.arangodb.serde.jackson3; - -import com.arangodb.serde.ArangoSerde; -import com.arangodb.RequestContext; -import com.arangodb.serde.jackson3.internal.JacksonSerdeImpl; -import tools.jackson.databind.DeserializationContext; -import tools.jackson.databind.ObjectMapper; - -import static com.arangodb.serde.jackson3.internal.JacksonSerdeImpl.SERDE_CONTEXT_ATTRIBUTE_NAME; - -/** - * User data serde based on Jackson Databind. Not shaded in arangodb-java-driver-shaded. - */ -public interface JacksonSerde extends ArangoSerde { - - /** - * Creates a new JacksonSerde using the provided ObjectMapper. - * - * @param mapper Jackson ObjectMapper to use - * @return the created JacksonSerde - */ - static JacksonSerde create(final ObjectMapper mapper) { - return new JacksonSerdeImpl(mapper); - } - - /** - * Extracts the {@link RequestContext} from the current {@link DeserializationContext}. - * - * @param ctx current Jackson {@link DeserializationContext} - * @return current {@link RequestContext} - */ - static RequestContext getRequestContext(DeserializationContext ctx) { - return (RequestContext) ctx.getAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME); - } - -} diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java deleted file mode 100644 index b53c1916b..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.arangodb.serde.jackson3.internal; - -import com.arangodb.serde.annotation.*; -import com.arangodb.serde.jackson3.*; -import com.fasterxml.jackson.annotation.JsonInclude; -import tools.jackson.databind.PropertyName; -import tools.jackson.databind.cfg.MapperConfig; -import tools.jackson.databind.introspect.Annotated; -import tools.jackson.databind.introspect.JacksonAnnotationIntrospector; - -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -class ArangoSerdeAnnotationIntrospector extends JacksonAnnotationIntrospector { - private static final JsonInclude JSON_INCLUDE_NON_NULL = JsonIncludeNonNull.class.getAnnotation(JsonInclude.class); - private static final Map, String> MAPPINGS; - private static final Class[] ANNOTATIONS; - - static { - MAPPINGS = new HashMap<>(); - MAPPINGS.put(Id.class, "_id"); - MAPPINGS.put(Key.class, "_key"); - MAPPINGS.put(Rev.class, "_rev"); - MAPPINGS.put(From.class, "_from"); - MAPPINGS.put(To.class, "_to"); - ANNOTATIONS = MAPPINGS.keySet().toArray(new Class[0]); - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - private static class JsonIncludeNonNull { - } - - @Override - public PropertyName findNameForSerialization(MapperConfig config, Annotated a) { - return Optional.ofNullable(findMapping(a)).orElseGet(() -> super.findNameForSerialization(config, a)); - } - - @Override - public PropertyName findNameForDeserialization(MapperConfig config, Annotated a) { - return Optional.ofNullable(findMapping(a)).orElseGet(() -> super.findNameForDeserialization(config, a)); - } - - private PropertyName findMapping(Annotated a) { - for (Map.Entry, String> e : MAPPINGS.entrySet()) { - if (_hasAnnotation(a, e.getKey())) { - return PropertyName.construct(e.getValue()); - } - } - return null; - } - - @Override - public JsonInclude.Value findPropertyInclusion(MapperConfig config, Annotated a) { - if (_hasOneOf(a, ANNOTATIONS)) { - return new JsonInclude.Value(JSON_INCLUDE_NON_NULL); - } else { - return super.findPropertyInclusion(config, a); - } - } -} diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/JacksonSerdeImpl.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/JacksonSerdeImpl.java deleted file mode 100644 index 4909d1929..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/JacksonSerdeImpl.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.arangodb.serde.jackson3.internal; - -import com.arangodb.RequestContext; -import com.arangodb.serde.jackson3.JacksonSerde; -import tools.jackson.databind.DeserializationFeature; -import tools.jackson.databind.ObjectMapper; -import tools.jackson.databind.cfg.ContextAttributes; - -import java.util.Objects; - - -/** - * Not shaded in arangodb-java-driver-shaded. - */ -public final class JacksonSerdeImpl implements JacksonSerde { - public static final String SERDE_CONTEXT_ATTRIBUTE_NAME = "arangoRequestContext"; - - private final ObjectMapper mapper; - - public JacksonSerdeImpl(final ObjectMapper mapper) { - this.mapper = mapper.rebuild() - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) - .annotationIntrospector(new ArangoSerdeAnnotationIntrospector()) - .build(); - } - - @Override - public byte[] serialize(final Object value) { - return mapper.writeValueAsBytes(value); - } - - @Override - public T deserialize(final byte[] content, final Class type) { - return deserialize(content, type, RequestContext.EMPTY); - } - - @Override - public T deserialize(byte[] content, Class type, RequestContext ctx) { - Objects.requireNonNull(ctx); - if (content == null || content.length == 0) { - return null; - } - return mapper.readerFor(mapper.constructType(type)) - .with(ContextAttributes.getEmpty().withPerCallAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) - .readValue(content); - } -} diff --git a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/json/JacksonJsonSerdeProvider.java b/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/json/JacksonJsonSerdeProvider.java deleted file mode 100644 index ab1b33014..000000000 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/json/JacksonJsonSerdeProvider.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.arangodb.serde.jackson3.json; - -import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.ArangoSerdeProvider; -import com.arangodb.serde.jackson3.JacksonSerde; -import tools.jackson.databind.json.JsonMapper; - -public class JacksonJsonSerdeProvider implements ArangoSerdeProvider { - @Override - public ArangoSerde create() { - return JacksonSerde.create(new JsonMapper()); - } - -} diff --git a/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/native-image.properties b/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/native-image.properties deleted file mode 100644 index f6d4bf39a..000000000 --- a/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/native-image.properties +++ /dev/null @@ -1,3 +0,0 @@ -Args=\ --H:ResourceConfigurationResources=${.}/resource-config-spi.json \ --H:ReflectionConfigurationResources=${.}/reflect-config-spi.json diff --git a/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/reflect-config-spi.json b/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/reflect-config-spi.json deleted file mode 100644 index 3bd002566..000000000 --- a/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/reflect-config-spi.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "name": "com.arangodb.serde.jackson3.json.JacksonJsonSerdeProvider", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - } -] diff --git a/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/resource-config-spi.json b/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/resource-config-spi.json deleted file mode 100644 index 520213dcf..000000000 --- a/jackson3-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson3-serde-json/resource-config-spi.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "resources": { - "includes": [ - { - "pattern": "META-INF/services/com.arangodb.serde.ArangoSerdeProvider" - } - ] - }, - "bundles": [] -} diff --git a/jackson3-serde-json/src/main/resources/META-INF/services/com.arangodb.serde.ArangoSerdeProvider b/jackson3-serde-json/src/main/resources/META-INF/services/com.arangodb.serde.ArangoSerdeProvider deleted file mode 100644 index bdf29f046..000000000 --- a/jackson3-serde-json/src/main/resources/META-INF/services/com.arangodb.serde.ArangoSerdeProvider +++ /dev/null @@ -1 +0,0 @@ -com.arangodb.serde.jackson3.json.JacksonJsonSerdeProvider diff --git a/pom.xml b/pom.xml index 0dd058c0b..76a3a3e9a 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,6 @@ driver shaded jackson-serde-json - jackson3-serde-json jsonb-serde http-protocol @@ -250,6 +249,13 @@ import pom + + tools.jackson + jackson-bom + 3.1.1 + import + pom + com.google.code.findbugs jsr305 @@ -290,11 +296,6 @@ jackson-serde-json ${project.version} - - com.arangodb - jackson3-serde-json - ${project.version} - com.arangodb jsonb-serde diff --git a/shaded/pom.xml b/shaded/pom.xml index fb9a1ca97..197ec6f07 100644 --- a/shaded/pom.xml +++ b/shaded/pom.xml @@ -107,13 +107,6 @@ META-INF/maven/** - - com.fasterxml.jackson.core:* - - META-INF/** - module-info.class - - io.netty:* @@ -128,12 +121,6 @@ META-INF/** - - com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp - - META-INF/MANIFEST.MF - - diff --git a/test-functional/pom.xml b/test-functional/pom.xml index 8d7f45af4..59760adec 100644 --- a/test-functional/pom.xml +++ b/test-functional/pom.xml @@ -45,28 +45,6 @@ **/HttpProxyTest.**, **/RequestContextTest.** - - - com.fasterxml.jackson.databind.JsonNode - com.arangodb.shaded.fasterxml.jackson.databind.JsonNode - - - com.fasterxml.jackson.databind.ObjectNode - com.arangodb.shaded.fasterxml.jackson.databind.ObjectNode - - - com.fasterxml.jackson.databind.node - com.arangodb.shaded.fasterxml.jackson.databind.node - - - com.fasterxml.jackson.databind.ObjectMapper - com.arangodb.shaded.fasterxml.jackson.databind.ObjectMapper - - - com.fasterxml.jackson.core.JsonProcessingException - com.arangodb.shaded.fasterxml.jackson.core.JsonProcessingException - - diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 57f7ced00..76b170c35 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -29,14 +29,13 @@ import com.arangodb.util.*; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.JsonNode; import java.util.*; import java.util.concurrent.ExecutionException; @@ -57,7 +56,7 @@ class ArangoCollectionAsyncTest extends BaseJunit5 { private static final String COLLECTION_NAME = "ArangoCollectionTest_collection"; private static final String EDGE_COLLECTION_NAME = "ArangoCollectionTest_edge_collection"; - private final ObjectMapper mapper = new ObjectMapper(); + private final JsonMapper mapper = new JsonMapper(); private static Stream asyncCols() { return asyncDbsStream().map(mapNamedPayload(db -> db.collection(COLLECTION_NAME))).map(Arguments::of); @@ -524,7 +523,7 @@ void insertDocumentAsBytes(ArangoCollectionAsync collection) throws ExecutionExc assertThat(createEntity.getKey()).isEqualTo(key); assertThat(createEntity.getRev()).isNotNull(); assertThat(createEntity.getNew()).isNotNull().isInstanceOf(RawBytes.class); - Map newDoc = collection.getSerde().getUserSerde().deserialize(createEntity.getNew().get(), Map.class); + @SuppressWarnings("unchecked") Map newDoc = collection.getSerde().getUserSerde().deserialize(createEntity.getNew().get(), Map.class); assertThat(newDoc).containsAllEntriesOf(doc); } @@ -1091,7 +1090,7 @@ void updateDocumentMergeObjectsTrue(ArangoCollectionAsync collection) throws Exe assertThat(readResult.getKey()).isEqualTo(createResult.getKey()); final Object aResult = readResult.getAttribute("a"); assertThat(aResult).isInstanceOf(Map.class); - final Map aMap = (Map) aResult; + @SuppressWarnings("unchecked") final Map aMap = (Map) aResult; assertThat(aMap).containsKeys("a", "b"); } @@ -1118,7 +1117,7 @@ void updateDocumentMergeObjectsFalse(ArangoCollectionAsync collection) throws Ex assertThat(readResult.getKey()).isEqualTo(createResult.getKey()); final Object aResult = readResult.getAttribute("a"); assertThat(aResult).isInstanceOf(Map.class); - final Map aMap = (Map) aResult; + @SuppressWarnings("unchecked") final Map aMap = (Map) aResult; assertThat(aMap.keySet()).doesNotContain("a"); assertThat(aMap).containsKey("b"); } @@ -1573,7 +1572,7 @@ void deleteDocumentsWithRevs(ArangoCollectionAsync collection) throws ExecutionE ), new DocumentDeleteOptions().ignoreRevs(false)).get(); assertThat(info).isNotNull(); assertThat(info.getDocuments()).hasSize(1); - assertThat(info.getDocuments().get(0).getKey()).isEqualTo(a.getKey()); + assertThat(info.getDocuments().getFirst().getKey()).isEqualTo(a.getKey()); assertThat(info.getErrors()).hasSize(1); } @@ -1941,7 +1940,6 @@ void createAndGetVectorIndex(ArangoCollectionAsync collection) throws ExecutionE } - @ParameterizedTest @MethodSource("asyncCols") void createMDIndex(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { @@ -2106,7 +2104,6 @@ void indexDeduplicateFalse(ArangoCollectionAsync collection) throws ExecutionExc } - @ParameterizedTest @MethodSource("asyncCols") void createTtlIndexWithoutOptions(ArangoCollectionAsync collection) { @@ -2408,7 +2405,7 @@ void insertDocumentsFail(ArangoCollectionAsync collection) throws ExecutionExcep assertThat(docs.getDocuments()).hasSize(2); assertThat(docs.getErrors()).isNotNull(); assertThat(docs.getErrors()).hasSize(1); - assertThat(docs.getErrors().iterator().next().getErrorNum()).isEqualTo(1210); + assertThat(docs.getErrors().getFirst().getErrorNum()).isEqualTo(1210); } @ParameterizedTest @@ -2630,7 +2627,7 @@ void importDocumentsFromToPrefix(ArangoCollection edgeCollection) { @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJson(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJson(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { final String values = mapper.writeValueAsString(Arrays.asList(Collections.singletonMap("_key", rnd()), Collections.singletonMap("_key", rnd()))); @@ -2646,7 +2643,7 @@ void importDocumentsJson(ArangoCollectionAsync collection) throws JsonProcessing @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJsonDuplicateDefaultError(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJsonDuplicateDefaultError(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { String k1 = rnd(); String k2 = rnd(); @@ -2665,7 +2662,7 @@ void importDocumentsJsonDuplicateDefaultError(ArangoCollectionAsync collection) @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJsonDuplicateError(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJsonDuplicateError(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { String k1 = rnd(); String k2 = rnd(); @@ -2685,7 +2682,7 @@ void importDocumentsJsonDuplicateError(ArangoCollectionAsync collection) throws @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJsonDuplicateIgnore(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJsonDuplicateIgnore(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { String k1 = rnd(); String k2 = rnd(); @@ -2704,7 +2701,7 @@ void importDocumentsJsonDuplicateIgnore(ArangoCollectionAsync collection) throws @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJsonDuplicateReplace(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJsonDuplicateReplace(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { String k1 = rnd(); String k2 = rnd(); @@ -2724,7 +2721,7 @@ void importDocumentsJsonDuplicateReplace(ArangoCollectionAsync collection) throw @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJsonDuplicateUpdate(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJsonDuplicateUpdate(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { String k1 = rnd(); String k2 = rnd(); @@ -2755,7 +2752,7 @@ void importDocumentsJsonCompleteFail(ArangoCollectionAsync collection) { @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJsonDetails(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJsonDetails(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { String k1 = rnd(); String k2 = rnd(); @@ -2776,7 +2773,7 @@ void importDocumentsJsonDetails(ArangoCollectionAsync collection) throws JsonPro @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJsonOverwriteFalse(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJsonOverwriteFalse(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { collection.insertDocument(new BaseDocument()).get(); Long initialCount = collection.count().get().getCount(); @@ -2788,7 +2785,7 @@ void importDocumentsJsonOverwriteFalse(ArangoCollectionAsync collection) throws @ParameterizedTest @MethodSource("asyncCols") - void importDocumentsJsonOverwriteTrue(ArangoCollectionAsync collection) throws JsonProcessingException, ExecutionException, InterruptedException { + void importDocumentsJsonOverwriteTrue(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { collection.insertDocument(new BaseDocument()).get(); final String values = mapper.writeValueAsString(Arrays.asList(Collections.singletonMap("_key", rnd()), @@ -2799,7 +2796,7 @@ void importDocumentsJsonOverwriteTrue(ArangoCollectionAsync collection) throws J @ParameterizedTest @MethodSource("edges") - void importDocumentsJsonFromToPrefix(ArangoCollection edgeCollection) throws JsonProcessingException { + void importDocumentsJsonFromToPrefix(ArangoCollection edgeCollection) { String k1 = UUID.randomUUID().toString(); String k2 = UUID.randomUUID().toString(); @@ -2861,7 +2858,7 @@ void deleteDocumentsRawDataByKeyReturnOld(ArangoCollectionAsync collection) thro assertThat(i.getKey()).isIn("1", "2"); assertThat(i.getOld()).isNotNull().isInstanceOf(RawJson.class); JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) i.getOld()).get()); - assertThat(jn.get("_key").asText()).isEqualTo(i.getKey()); + assertThat(jn.get("_key").asString()).isEqualTo(i.getKey()); } assertThat(deleteResult.getErrors()).isEmpty(); } @@ -2991,7 +2988,7 @@ void updateDocuments(ArangoCollectionAsync collection) throws ExecutionException @MethodSource("asyncCols") void updateDocumentsWithDifferentReturnType(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { List keys = - IntStream.range(0, 3).mapToObj(it -> "key-" + UUID.randomUUID()).collect(Collectors.toList()); + IntStream.range(0, 3).mapToObj(it -> "key-" + UUID.randomUUID()).toList(); List docs = keys.stream().map(BaseDocument::new).peek(it -> it.addAttribute("a", "test")).collect(Collectors.toList()); @@ -3108,7 +3105,7 @@ void updateDocumentsRawDataReturnNew(ArangoCollectionAsync collection) throws Ex JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); assertThat(jn.has("foo")).isTrue(); - assertThat(jn.get("foo").textValue()).isEqualTo("bar"); + assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } } @@ -3227,7 +3224,7 @@ void replaceDocumentsRawDataReturnNew(ArangoCollectionAsync collection) throws E JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); assertThat(jn.has("foo")).isTrue(); - assertThat(jn.get("foo").textValue()).isEqualTo("bar"); + assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } } @@ -3546,6 +3543,7 @@ public AnnotatedEntity(@Key String key) { this.key = key; } + @Key public String getKey() { return key; } diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java index 3491e1a96..8a7ac6fcb 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -29,14 +29,13 @@ import com.arangodb.util.*; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.JsonNodeFactory; import java.util.*; import java.util.stream.Collectors; @@ -56,7 +55,7 @@ class ArangoCollectionTest extends BaseJunit5 { private static final String COLLECTION_NAME = "ArangoCollectionTest_collection"; private static final String EDGE_COLLECTION_NAME = "ArangoCollectionTest_edge_collection"; - private final ObjectMapper mapper = new ObjectMapper(); + private final JsonMapper mapper = new JsonMapper(); private static Stream cols() { return dbsStream() @@ -585,7 +584,7 @@ void insertDocumentsWithErrors(ArangoCollection collection) { assertThat(res.getErrors()).hasSize(1); assertThat(res.getDocumentsAndErrors()).hasSize(3); assertThat(res.getDocumentsAndErrors().get(0)).isSameAs(res.getDocuments().get(0)); - assertThat(res.getDocumentsAndErrors().get(1)).isSameAs(res.getErrors().get(0)); + assertThat(res.getDocumentsAndErrors().get(1)).isSameAs(res.getErrors().getFirst()); assertThat(res.getDocumentsAndErrors().get(2)).isSameAs(res.getDocuments().get(1)); } @@ -1623,7 +1622,7 @@ void deleteDocumentsWithRevs(ArangoCollection collection) { ), new DocumentDeleteOptions().ignoreRevs(false)); assertThat(info).isNotNull(); assertThat(info.getDocuments()).hasSize(1); - assertThat(info.getDocuments().get(0).getKey()).isEqualTo(a.getKey()); + assertThat(info.getDocuments().getFirst().getKey()).isEqualTo(a.getKey()); assertThat(info.getErrors()).hasSize(1); } @@ -1848,7 +1847,7 @@ void createPersistentIndex(ArangoCollection collection) { assertThat(indexResult.getType()).isEqualTo(IndexType.persistent); assertThat(indexResult.getUnique()).isFalse(); assertThat(indexResult.getDeduplicate()).isTrue(); - assertThat(indexResult.getCacheEnabled()).isFalse(); + assertThat(indexResult.getCacheEnabled()).isFalse(); } @ParameterizedTest @@ -1991,7 +1990,6 @@ void createAndGetVectorIndex(ArangoCollection collection) { } - @ParameterizedTest @MethodSource("cols") void createMDIndex(ArangoCollection collection) { @@ -2156,7 +2154,6 @@ void indexDeduplicateFalse(ArangoCollection collection) { } - @ParameterizedTest @MethodSource("cols") void createTtlIndexWithoutOptions(ArangoCollection collection) { @@ -2486,7 +2483,7 @@ void insertDocumentsFail(ArangoCollection collection) { assertThat(docs.getDocuments()).hasSize(2); assertThat(docs.getErrors()).isNotNull(); assertThat(docs.getErrors()).hasSize(1); - assertThat(docs.getErrors().iterator().next().getErrorNum()).isEqualTo(1210); + assertThat(docs.getErrors().getFirst().getErrorNum()).isEqualTo(1210); } @ParameterizedTest @@ -2708,7 +2705,7 @@ void importDocumentsFromToPrefix(ArangoCollection edgeCollection) { @ParameterizedTest @MethodSource("cols") - void importDocumentsJson(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJson(ArangoCollection collection) { final String values = mapper.writeValueAsString(Arrays.asList(Collections.singletonMap("_key", rnd()), Collections.singletonMap("_key", rnd()))); @@ -2724,7 +2721,7 @@ void importDocumentsJson(ArangoCollection collection) throws JsonProcessingExcep @ParameterizedTest @MethodSource("cols") - void importDocumentsJsonDuplicateDefaultError(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJsonDuplicateDefaultError(ArangoCollection collection) { String k1 = rnd(); String k2 = rnd(); @@ -2743,7 +2740,7 @@ void importDocumentsJsonDuplicateDefaultError(ArangoCollection collection) throw @ParameterizedTest @MethodSource("cols") - void importDocumentsJsonDuplicateError(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJsonDuplicateError(ArangoCollection collection) { String k1 = rnd(); String k2 = rnd(); @@ -2763,7 +2760,7 @@ void importDocumentsJsonDuplicateError(ArangoCollection collection) throws JsonP @ParameterizedTest @MethodSource("cols") - void importDocumentsJsonDuplicateIgnore(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJsonDuplicateIgnore(ArangoCollection collection) { String k1 = rnd(); String k2 = rnd(); @@ -2782,7 +2779,7 @@ void importDocumentsJsonDuplicateIgnore(ArangoCollection collection) throws Json @ParameterizedTest @MethodSource("cols") - void importDocumentsJsonDuplicateReplace(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJsonDuplicateReplace(ArangoCollection collection) { String k1 = rnd(); String k2 = rnd(); @@ -2802,7 +2799,7 @@ void importDocumentsJsonDuplicateReplace(ArangoCollection collection) throws Jso @ParameterizedTest @MethodSource("cols") - void importDocumentsJsonDuplicateUpdate(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJsonDuplicateUpdate(ArangoCollection collection) { String k1 = rnd(); String k2 = rnd(); @@ -2833,7 +2830,7 @@ void importDocumentsJsonCompleteFail(ArangoCollection collection) { @ParameterizedTest @MethodSource("cols") - void importDocumentsJsonDetails(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJsonDetails(ArangoCollection collection) { String k1 = rnd(); String k2 = rnd(); @@ -2854,7 +2851,7 @@ void importDocumentsJsonDetails(ArangoCollection collection) throws JsonProcessi @ParameterizedTest @MethodSource("cols") - void importDocumentsJsonOverwriteFalse(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJsonOverwriteFalse(ArangoCollection collection) { collection.insertDocument(new BaseDocument()); Long initialCount = collection.count().getCount(); @@ -2866,7 +2863,7 @@ void importDocumentsJsonOverwriteFalse(ArangoCollection collection) throws JsonP @ParameterizedTest @MethodSource("cols") - void importDocumentsJsonOverwriteTrue(ArangoCollection collection) throws JsonProcessingException { + void importDocumentsJsonOverwriteTrue(ArangoCollection collection) { collection.insertDocument(new BaseDocument()); final String values = mapper.writeValueAsString(Arrays.asList(Collections.singletonMap("_key", rnd()), @@ -2877,7 +2874,7 @@ void importDocumentsJsonOverwriteTrue(ArangoCollection collection) throws JsonPr @ParameterizedTest @MethodSource("edges") - void importDocumentsJsonFromToPrefix(ArangoCollection edgeCollection) throws JsonProcessingException { + void importDocumentsJsonFromToPrefix(ArangoCollection edgeCollection) { String k1 = UUID.randomUUID().toString(); String k2 = UUID.randomUUID().toString(); @@ -2939,7 +2936,7 @@ void deleteDocumentsRawDataByKeyReturnOld(ArangoCollection collection) { assertThat(i.getKey()).isIn("1", "2"); assertThat(i.getOld()).isNotNull().isInstanceOf(RawJson.class); JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) i.getOld()).get()); - assertThat(jn.get("_key").asText()).isEqualTo(i.getKey()); + assertThat(jn.get("_key").asString()).isEqualTo(i.getKey()); } assertThat(deleteResult.getErrors()).isEmpty(); } @@ -3069,7 +3066,7 @@ void updateDocuments(ArangoCollection collection) { @MethodSource("cols") void updateDocumentsWithDifferentReturnType(ArangoCollection collection) { List keys = - IntStream.range(0, 3).mapToObj(it -> "key-" + UUID.randomUUID()).collect(Collectors.toList()); + IntStream.range(0, 3).mapToObj(it -> "key-" + UUID.randomUUID()).toList(); List docs = keys.stream().map(BaseDocument::new).peek(it -> it.addAttribute("a", "test")).collect(Collectors.toList()); @@ -3186,7 +3183,7 @@ void updateDocumentsRawDataReturnNew(ArangoCollection collection) { JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); assertThat(jn.has("foo")).isTrue(); - assertThat(jn.get("foo").textValue()).isEqualTo("bar"); + assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } } @@ -3305,7 +3302,7 @@ void replaceDocumentsRawDataReturnNew(ArangoCollection collection) { JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); assertThat(jn.has("foo")).isTrue(); - assertThat(jn.get("foo").textValue()).isEqualTo("bar"); + assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } } @@ -3355,7 +3352,7 @@ void changeProperties(ArangoCollection collection) { assertThat(changedProperties.getCacheEnabled()).isEqualTo(updatedOptions.getCacheEnabled()); assertThat(changedProperties.getComputedValues()) .hasSize(1) - .contains(updatedOptions.getComputedValues().get(0)); + .contains(updatedOptions.getComputedValues().getFirst()); assertThat(changedProperties.getReplicationFactor().get()).isEqualTo(updatedOptions.getReplicationFactor().get()); assertThat(changedProperties.getSchema().getLevel()).isEqualTo(CollectionSchema.Level.NEW); assertThat(changedProperties.getSchema().getMessage()).isEqualTo(schemaMessage); @@ -3646,6 +3643,7 @@ public AnnotatedEntity(@Key String key) { this.key = key; } + @Key public String getKey() { return key; } diff --git a/test-functional/src/test/java/com/arangodb/ArangoCursorTest.java b/test-functional/src/test/java/com/arangodb/ArangoCursorTest.java index 1d542dae8..44692edf5 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCursorTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCursorTest.java @@ -21,10 +21,10 @@ package com.arangodb; import com.arangodb.model.AqlQueryOptions; -import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import tools.jackson.databind.JsonNode; import java.util.Optional; import java.util.Set; diff --git a/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java index cadce9bcb..cceba10da 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java @@ -29,12 +29,12 @@ import com.arangodb.util.RawJson; import com.arangodb.util.SlowTest; import com.arangodb.util.UnicodeUtils; -import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import tools.jackson.databind.JsonNode; import java.time.LocalDateTime; import java.time.ZoneId; @@ -98,7 +98,7 @@ void createAndDeleteDatabase(ArangoDBAsync arangoDB) throws ExecutionException, void createWithNotNormalizedName(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { assumeTrue(supportsExtendedDbNames()); - final String dbName = "testDB-\u006E\u0303\u00f1"; + @SuppressWarnings("UnnecessaryUnicodeEscape") final String dbName = "testDB-\u006E\u0303\u00f1"; String normalized = UnicodeUtils.normalize(dbName); arangoDB.createDatabase(normalized).get(); arangoDB.db(normalized).drop().get(); @@ -425,7 +425,7 @@ void executeGetVersion(ArangoDBAsync arangoDB) throws ExecutionException, Interr .build(); final Response response = arangoDB.execute(request, RawJson.class).get(); JsonNode body = SerdeUtils.INSTANCE.parseJson(response.getBody().get()); - assertThat(body.get("version").isTextual()).isTrue(); + assertThat(body.get("version").isString()).isTrue(); assertThat(body.get("details").isObject()).isTrue(); assertThat(response.getResponseCode()).isEqualTo(200); String header = response.getHeaders().get("x-arango-queue-time-seconds"); @@ -462,7 +462,7 @@ void getLogEntriesLevel(ArangoDBAsync arangoDB) throws ExecutionException, Inter @MethodSource("asyncArangos") void getLogEntriesStart(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { final LogEntriesEntity logs = arangoDB.getLogEntries(null).get(); - final Long firstId = logs.getMessages().get(0).getId(); + final Long firstId = logs.getMessages().getFirst().getId(); final LogEntriesEntity logsStart = arangoDB.getLogEntries(new LogOptions().start(firstId + 1)).get(); assertThat(logsStart.getMessages()) .map(LogEntriesEntity.Message::getId) @@ -484,7 +484,7 @@ void getLogEntriesSize(ArangoDBAsync arangoDB) throws ExecutionException, Interr void getLogEntriesOffset(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { final LogEntriesEntity logs = arangoDB.getLogEntries(null).get(); assertThat(logs.getTotal()).isPositive(); - Long firstId = logs.getMessages().get(0).getId(); + Long firstId = logs.getMessages().getFirst().getId(); final LogEntriesEntity logsOffset = arangoDB.getLogEntries(new LogOptions().offset(1)).get(); assertThat(logsOffset.getMessages()) .map(LogEntriesEntity.Message::getId) @@ -506,7 +506,7 @@ void getLogEntriesSortAsc(ArangoDBAsync arangoDB) throws ExecutionException, Int long lastId = -1; List ids = logs.getMessages().stream() .map(LogEntriesEntity.Message::getId) - .collect(Collectors.toList()); + .toList(); for (final Long id : ids) { assertThat(id).isGreaterThan(lastId); lastId = id; @@ -520,7 +520,7 @@ void getLogEntriesSortDesc(ArangoDBAsync arangoDB) throws ExecutionException, In long lastId = Long.MAX_VALUE; List ids = logs.getMessages().stream() .map(LogEntriesEntity.Message::getId) - .collect(Collectors.toList()); + .toList(); for (final Long id : ids) { assertThat(lastId).isGreaterThan(id); lastId = id; diff --git a/test-functional/src/test/java/com/arangodb/ArangoDBTest.java b/test-functional/src/test/java/com/arangodb/ArangoDBTest.java index 969bcf152..bc0c12850 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDBTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDBTest.java @@ -30,14 +30,14 @@ import com.arangodb.util.RawJson; import com.arangodb.util.SlowTest; import com.arangodb.util.UnicodeUtils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; import java.time.LocalDateTime; import java.time.ZoneId; @@ -45,7 +45,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; -import java.util.stream.Collectors; import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; @@ -103,7 +102,7 @@ void createAndDeleteDatabase(ArangoDB arangoDB) { void createWithNotNormalizedName(ArangoDB arangoDB) { assumeTrue(supportsExtendedDbNames()); - final String dbName = "testDB-\u006E\u0303\u00f1"; + @SuppressWarnings("UnnecessaryUnicodeEscape") final String dbName = "testDB-\u006E\u0303\u00f1"; String normalized = UnicodeUtils.normalize(dbName); arangoDB.createDatabase(normalized); arangoDB.db(normalized).drop(); @@ -168,7 +167,7 @@ void createDatabaseWithOptionsSatellite(ArangoDB arangoDB) { @SlowTest @ParameterizedTest @MethodSource("arangos") - void createDatabaseWithUsers(ArangoDB arangoDB) throws InterruptedException { + void createDatabaseWithUsers(ArangoDB arangoDB) { final String dbName = rndDbName(); final Map extra = Collections.singletonMap("key", "value"); final Boolean resultCreate = arangoDB.createDatabase(new DBCreateOptions() @@ -420,28 +419,13 @@ void executeGetVersion(ArangoDB arangoDB) { .build(); final Response response = arangoDB.execute(request, RawJson.class); JsonNode body = SerdeUtils.INSTANCE.parseJson(response.getBody().get()); - assertThat(body.get("version").isTextual()).isTrue(); + assertThat(body.get("version").isString()).isTrue(); assertThat(body.get("details").isObject()).isTrue(); assertThat(response.getResponseCode()).isEqualTo(200); String header = response.getHeaders().get("x-arango-queue-time-seconds"); assertThat(header).isNotNull(); } - @ParameterizedTest - @MethodSource("arangos") - void executeJS(ArangoDB arangoDB) { - assumeTrue(supportsV8()); - assumeTrue(isAtLeastVersion(3, 11)); - Request request = Request.builder() - .db(ArangoRequestParam.SYSTEM) - .method(Request.Method.POST) - .path("/_admin/execute") - .body(JsonNodeFactory.instance.textNode("return 11;")) - .build(); - final Response response = arangoDB.execute(request, Integer.class); - assertThat(response.getBody()).isEqualTo(11); - } - @ParameterizedTest @MethodSource("arangos") void getLogEntries(ArangoDB arangoDB) { @@ -472,7 +456,7 @@ void getLogEntriesLevel(ArangoDB arangoDB) { @MethodSource("arangos") void getLogEntriesStart(ArangoDB arangoDB) { final LogEntriesEntity logs = arangoDB.getLogEntries(null); - final Long firstId = logs.getMessages().get(0).getId(); + final Long firstId = logs.getMessages().getFirst().getId(); final LogEntriesEntity logsStart = arangoDB.getLogEntries(new LogOptions().start(firstId + 1)); assertThat(logsStart.getMessages()) .map(LogEntriesEntity.Message::getId) @@ -494,7 +478,7 @@ void getLogEntriesSize(ArangoDB arangoDB) { void getLogEntriesOffset(ArangoDB arangoDB) { final LogEntriesEntity logs = arangoDB.getLogEntries(null); assertThat(logs.getTotal()).isPositive(); - Long firstId = logs.getMessages().get(0).getId(); + Long firstId = logs.getMessages().getFirst().getId(); final LogEntriesEntity logsOffset = arangoDB.getLogEntries(new LogOptions().offset(1)); assertThat(logsOffset.getMessages()) .map(LogEntriesEntity.Message::getId) @@ -516,7 +500,7 @@ void getLogEntriesSortAsc(ArangoDB arangoDB) { long lastId = -1; List ids = logs.getMessages().stream() .map(LogEntriesEntity.Message::getId) - .collect(Collectors.toList()); + .toList(); for (final Long id : ids) { assertThat(id).isGreaterThan(lastId); lastId = id; @@ -530,7 +514,7 @@ void getLogEntriesSortDesc(ArangoDB arangoDB) { long lastId = Long.MAX_VALUE; List ids = logs.getMessages().stream() .map(LogEntriesEntity.Message::getId) - .collect(Collectors.toList()); + .toList(); for (final Long id : ids) { assertThat(lastId).isGreaterThan(id); lastId = id; @@ -739,7 +723,7 @@ void queueTime(ArangoDB arangoDB) throws InterruptedException, ExecutionExceptio () -> arangoDB.db().query("RETURN SLEEP(1)", Void.class), Executors.newFixedThreadPool(80)) ) - .collect(Collectors.toList()); + .toList(); for (CompletableFuture f : futures) { f.get(); } diff --git a/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java index 55bb857a3..c9b38f202 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java @@ -25,13 +25,10 @@ import com.arangodb.internal.serde.InternalSerde; import com.arangodb.model.*; import com.arangodb.util.*; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import tools.jackson.databind.JsonNode; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -105,7 +102,7 @@ void createCollection(ArangoDatabaseAsync db) throws ExecutionException, Interru @MethodSource("asyncDbs") void createCollectionWithNotNormalizedName(ArangoDatabaseAsync db) { assumeTrue(supportsExtendedNames()); - final String colName = "testCol-\u006E\u0303\u00f1"; + @SuppressWarnings("UnnecessaryUnicodeEscape") final String colName = "testCol-\u006E\u0303\u00f1"; Throwable thrown = catchThrowable(() -> db.createCollection(colName).get()).getCause(); assertThat(thrown) @@ -173,7 +170,7 @@ void createCollectionWithNumberOfShards(ArangoDatabaseAsync db) throws Execution @ParameterizedTest @MethodSource("asyncDbs") - void createCollectionWithShardingStrategys(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { + void createCollectionWithShardingStrategy(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { assumeTrue(isCluster()); String name = rndName(); @@ -685,7 +682,7 @@ void queryRawBytes(ArangoDatabaseAsync db) throws ExecutionException, Interrupte InternalSerde serde = db.getSerde(); RawBytes doc = RawBytes.of(serde.serialize(Collections.singletonMap("value", 1))); RawBytes res = db.query("RETURN @doc", RawBytes.class, Collections.singletonMap("doc", doc)).get() - .getResult().get(0); + .getResult().getFirst(); JsonNode data = serde.deserialize(res.get(), JsonNode.class); assertThat(data.isObject()).isTrue(); assertThat(data.get("value").isNumber()).isTrue(); @@ -796,8 +793,7 @@ void queryWithMaxWarningCount(ArangoDatabaseAsync db) throws ExecutionException, void queryCursor(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { ArangoCursorAsync c1 = db.query("for i in 1..4 return i", Integer.class, new AqlQueryOptions().batchSize(1)).get(); - List result = new ArrayList<>(); - result.addAll(c1.getResult()); + List result = new ArrayList<>(c1.getResult()); ArangoCursorAsync c2 = c1.nextBatch().get(); result.addAll(c2.getResult()); ArangoCursorAsync c3 = db.cursor(c2.getId(), Integer.class).get(); @@ -814,8 +810,7 @@ void queryCursorInTx(ArangoDatabaseAsync db) throws ExecutionException, Interrup StreamTransactionEntity tx = db.beginStreamTransaction(new StreamTransactionOptions()).get(); ArangoCursorAsync c1 = db.query("for i in 1..4 return i", Integer.class, new AqlQueryOptions().batchSize(1).streamTransactionId(tx.getId())).get(); - List result = new ArrayList<>(); - result.addAll(c1.getResult()); + List result = new ArrayList<>(c1.getResult()); ArangoCursorAsync c2 = c1.nextBatch().get(); result.addAll(c2.getResult()); ArangoCursorAsync c3 = db.cursor(c2.getId(), Integer.class, @@ -833,8 +828,7 @@ void queryCursorInTx(ArangoDatabaseAsync db) throws ExecutionException, Interrup void queryCursorRetry(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { ArangoCursorAsync c1 = db.query("for i in 1..4 return i", Integer.class, new AqlQueryOptions().batchSize(1).allowRetry(true)).get(); - List result = new ArrayList<>(); - result.addAll(c1.getResult()); + List result = new ArrayList<>(c1.getResult()); ArangoCursorAsync c2 = c1.nextBatch().get(); result.addAll(c2.getResult()); ArangoCursorAsync c3 = db.cursor(c2.getId(), Integer.class, c2.getNextBatchId()).get(); @@ -852,8 +846,7 @@ void queryCursorRetryInTx(ArangoDatabaseAsync db) throws ExecutionException, Int StreamTransactionEntity tx = db.beginStreamTransaction(new StreamTransactionOptions()).get(); ArangoCursorAsync c1 = db.query("for i in 1..4 return i", Integer.class, new AqlQueryOptions().batchSize(1).allowRetry(true).streamTransactionId(tx.getId())).get(); - List result = new ArrayList<>(); - result.addAll(c1.getResult()); + List result = new ArrayList<>(c1.getResult()); ArangoCursorAsync c2 = c1.nextBatch().get(); result.addAll(c2.getResult()); ArangoCursorAsync c3 = db.cursor(c2.getId(), Integer.class, c2.getNextBatchId(), @@ -917,9 +910,9 @@ void queryWithRawBindVars(ArangoDatabaseAsync db) throws ExecutionException, Int bindVars.put("bar", RawBytes.of(db.getSerde().serializeUserData(11))); final JsonNode res = db.query("RETURN {foo: @foo, bar: @bar}", JsonNode.class, bindVars).get() - .getResult().get(0); + .getResult().getFirst(); - assertThat(res.get("foo").textValue()).isEqualTo("fooValue"); + assertThat(res.get("foo").stringValue()).isEqualTo("fooValue"); assertThat(res.get("bar").intValue()).isEqualTo(11); } @@ -1090,8 +1083,6 @@ private String getExplainQuery(ArangoDatabaseAsync db) throws ExecutionException } - - void checkUntypedExecutionPlan(AqlQueryExplainEntity.ExecutionPlan plan) { assertThat(plan).isNotNull(); assertThat(plan.get("estimatedNrItems")) @@ -1304,7 +1295,6 @@ void getAndClearSlowQueries(ArangoDatabaseAsync db) throws ExecutionException, I } - @ParameterizedTest @MethodSource("asyncDbs") void createGraph(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { @@ -1325,13 +1315,13 @@ void createGraphSatellite(ArangoDatabaseAsync db) throws ExecutionException, Int GraphEntity info = db.graph(name).getInfo().get(); assertThat(info.getReplicationFactor()).isEqualTo(ReplicationFactor.ofSatellite()); - GraphEntity graph = db.getGraphs().get().stream().filter(g -> name.equals(g.getName())).findFirst().get(); + GraphEntity graph = db.getGraphs().get().stream().filter(g -> name.equals(g.getName())).findFirst().orElseThrow(); assertThat(graph.getReplicationFactor()).isEqualTo(ReplicationFactor.ofSatellite()); } @ParameterizedTest @MethodSource("asyncDbs") - void createGraphReplicationFaktor(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { + void createGraphReplicationFactor(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { assumeTrue(isCluster()); String name = "graph-" + rnd(); final String edgeCollection = rndName(); @@ -1378,18 +1368,6 @@ void getGraphs(ArangoDatabaseAsync db) throws ExecutionException, InterruptedExc } - - - - - - - - - - - - @ParameterizedTest @MethodSource("asyncDbs") void getInfo(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { @@ -1408,5 +1386,4 @@ void getInfo(ArangoDatabaseAsync db) throws ExecutionException, InterruptedExcep } - } diff --git a/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java b/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java index 20d574b8f..f891f67c0 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java @@ -25,13 +25,10 @@ import com.arangodb.internal.serde.InternalSerde; import com.arangodb.model.*; import com.arangodb.util.*; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import tools.jackson.databind.JsonNode; import java.io.IOException; import java.util.*; @@ -109,7 +106,7 @@ void createCollection(ArangoDatabase db) { @MethodSource("dbs") void createCollectionWithNotNormalizedName(ArangoDatabase db) { assumeTrue(supportsExtendedNames()); - final String colName = "testCol-\u006E\u0303\u00f1"; + @SuppressWarnings("UnnecessaryUnicodeEscape") final String colName = "testCol-\u006E\u0303\u00f1"; Throwable thrown = catchThrowable(() -> db.createCollection(colName)); assertThat(thrown) @@ -1039,7 +1036,7 @@ void queryWithRawBindVars(ArangoDatabase db) { final JsonNode res = db.query("RETURN {foo: @foo, bar: @bar}", JsonNode.class, bindVars).next(); - assertThat(res.get("foo").textValue()).isEqualTo("fooValue"); + assertThat(res.get("foo").stringValue()).isEqualTo("fooValue"); assertThat(res.get("bar").intValue()).isEqualTo(11); } @@ -1150,7 +1147,7 @@ BaseDocument.class, new MapBuilder().put("@col", CNAME1).put("test", null).get() @ParameterizedTest @MethodSource("arangos") - void queryAllowRetry(ArangoDB arangoDB) throws IOException { + void queryAllowRetry(ArangoDB arangoDB) { final ArangoCursor cursor = arangoDB.db() .query("for i in 1..2 return i", String.class, new AqlQueryOptions().allowRetry(true).batchSize(1)); assertThat(cursor.asListRemaining()).containsExactly("1", "2"); @@ -1194,9 +1191,6 @@ void queryAllowRetryCloseSingleBatch(ArangoDB arangoDB) throws IOException { } - - - private String getExplainQuery(ArangoDatabase db) { ArangoCollection character = db.collection("got_characters"); ArangoCollection actor = db.collection("got_actors"); @@ -1434,7 +1428,6 @@ void getAndClearSlowQueries(ArangoDatabase db) { } - @ParameterizedTest @MethodSource("dbs") void createGraph(ArangoDatabase db) { @@ -1455,7 +1448,7 @@ void createGraphSatellite(ArangoDatabase db) { GraphEntity info = db.graph(name).getInfo(); assertThat(info.getReplicationFactor()).isEqualTo(ReplicationFactor.ofSatellite()); - GraphEntity graph = db.getGraphs().stream().filter(g -> name.equals(g.getName())).findFirst().get(); + GraphEntity graph = db.getGraphs().stream().filter(g -> name.equals(g.getName())).findFirst().orElseThrow(); assertThat(graph.getReplicationFactor()).isEqualTo(ReplicationFactor.ofSatellite()); } @@ -1508,18 +1501,6 @@ void getGraphs(ArangoDatabase db) { } - - - - - - - - - - - - @ParameterizedTest @MethodSource("dbs") void getInfo(ArangoDatabase db) { @@ -1538,5 +1519,4 @@ void getInfo(ArangoDatabase db) { } - } diff --git a/test-functional/src/test/java/com/arangodb/BaseJunit5.java b/test-functional/src/test/java/com/arangodb/BaseJunit5.java index a9c0d8576..b20c27428 100644 --- a/test-functional/src/test/java/com/arangodb/BaseJunit5.java +++ b/test-functional/src/test/java/com/arangodb/BaseJunit5.java @@ -6,20 +6,19 @@ import com.arangodb.model.CollectionCreateOptions; import com.arangodb.model.GraphCreateOptions; import com.arangodb.util.TestUtils; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import jakarta.json.JsonObject; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Named; import org.junit.jupiter.params.provider.Arguments; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.function.Function; -import java.util.stream.Collectors; import java.util.stream.Stream; import static com.arangodb.util.TestUtils.TEST_DB; @@ -33,14 +32,13 @@ public class BaseJunit5 { private static final ArangoDBVersion version = adb.getVersion(); private static final ServerRole role = adb.getRole(); - private static final boolean supportsV8 = supportsV8(adb); private static final List> adbs = Arrays.stream(Protocol.values()) .map(p -> Named.of(p.toString(), new ArangoDB.Builder() .loadProperties(config) .protocol(p) .build())) - .collect(Collectors.toList()); + .toList(); private static Boolean extendedDbNames; private static Boolean extendedNames; @@ -92,7 +90,7 @@ protected static String getJwt() { ) .build(), ObjectNode.class); - return response.getBody().get("jwt").textValue(); + return response.getBody().get("jwt").stringValue(); } static ArangoDatabase initDB(String name) { @@ -214,26 +212,4 @@ public static boolean isSingleServer() { public static boolean isCluster() { return role == ServerRole.COORDINATOR; } - - public static boolean isEnterprise() { - return version.getLicense() == License.ENTERPRISE; - } - - public static boolean supportsV8() { - return supportsV8; - } - - private static boolean supportsV8(ArangoDB adb) { - JsonObject v = adb.execute(Request.builder() - .method(Request.Method.GET) - .path("/_api/version") - .queryParam("details", "true") - .build(), - JsonObject.class - ).getBody(); - JsonObject details = v.getJsonObject("details"); - if (!details.containsKey("v8-version")) return false; - return !details.getString("v8-version").equals("none"); - } - } diff --git a/test-functional/src/test/java/com/arangodb/CompressionTest.java b/test-functional/src/test/java/com/arangodb/CompressionTest.java index 9becbaf7b..789ba3e3d 100644 --- a/test-functional/src/test/java/com/arangodb/CompressionTest.java +++ b/test-functional/src/test/java/com/arangodb/CompressionTest.java @@ -2,14 +2,13 @@ import com.arangodb.config.ArangoConfigProperties; import com.arangodb.util.ProtocolSource; -import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.params.ParameterizedTest; +import tools.jackson.databind.JsonNode; import java.util.Locale; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * Non-exhaustive tests of content encoding, executed during integration and native tests. @@ -22,14 +21,12 @@ class CompressionTest extends BaseJunit5 { @ParameterizedTest @ProtocolSource void gzip(Protocol protocol) { - assumeTrue(supportsV8()); doTest(protocol, Compression.GZIP); } @ParameterizedTest @ProtocolSource void deflate(Protocol protocol) { - assumeTrue(supportsV8()); doTest(protocol, Compression.DEFLATE); } @@ -49,7 +46,7 @@ void doTest(Protocol protocol, Compression compression) { .build(), JsonNode.class); String encoding = compression.toString().toLowerCase(Locale.ROOT); - String reqAcceptEncoding = resp.getBody().get("headers").get("accept-encoding").textValue(); + String reqAcceptEncoding = resp.getBody().get("headers").get("accept-encoding").stringValue(); assertThat(reqAcceptEncoding).contains(encoding); adb.shutdown(); diff --git a/test-functional/src/test/java/com/arangodb/RequestContextTest.java b/test-functional/src/test/java/com/arangodb/RequestContextTest.java index f76a0fd3d..b1224a9e9 100644 --- a/test-functional/src/test/java/com/arangodb/RequestContextTest.java +++ b/test-functional/src/test/java/com/arangodb/RequestContextTest.java @@ -28,13 +28,12 @@ import com.arangodb.model.StreamTransactionOptions; import com.arangodb.serde.ArangoSerde; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.json.JsonMapper; -import java.io.IOException; import java.util.Collections; import java.util.Objects; import java.util.concurrent.ExecutionException; @@ -57,8 +56,9 @@ class RequestContextTest { @BeforeAll static void init() { ArangoSerde serde = new ArangoSerde() { - private ObjectMapper mapper = new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + private final JsonMapper mapper = JsonMapper.builder() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .build(); @Override public byte[] serialize(Object value) { @@ -78,13 +78,9 @@ public T deserialize(byte[] content, Class clazz, RequestContext ctx) { throw new UnsupportedOperationException(); } - try { - Person res = mapper.readValue(content, Person.class); - res.txId = ctx.getStreamTransactionId().get(); - return (T) res; - } catch (IOException e) { - throw new RuntimeException(e); - } + Person res = mapper.readValue(content, Person.class); + res.txId = ctx.getStreamTransactionId().orElseThrow(); + return (T) res; } }; diff --git a/test-functional/src/test/java/com/arangodb/SerializableTest.java b/test-functional/src/test/java/com/arangodb/SerializableTest.java index a915a74aa..38ef663ca 100644 --- a/test-functional/src/test/java/com/arangodb/SerializableTest.java +++ b/test-functional/src/test/java/com/arangodb/SerializableTest.java @@ -4,10 +4,10 @@ import com.arangodb.entity.BaseEdgeDocument; import com.arangodb.entity.ErrorEntity; import com.arangodb.internal.net.ArangoDBRedirectException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.JsonNodeFactory; import java.io.*; import java.util.Collections; @@ -18,8 +18,8 @@ class SerializableTest { @Test - void serializeArangoDBException() throws IOException, ClassNotFoundException { - ObjectMapper mapper = new ObjectMapper(); + void serializeArangoDBException() { + JsonMapper mapper = new JsonMapper(); JsonNode jn = JsonNodeFactory.instance.objectNode() .put("errorMessage", "boomError") .put("exception", "boomException") @@ -36,7 +36,7 @@ void serializeArangoDBException() throws IOException, ClassNotFoundException { } @Test - void serializeArangoDBRedirectException() throws IOException, ClassNotFoundException { + void serializeArangoDBRedirectException() { ArangoDBRedirectException e = new ArangoDBRedirectException("foo", "bar"); ArangoDBRedirectException e2 = roundTrip(e); assertThat(e2.getMessage()).isEqualTo(e.getMessage()); @@ -44,16 +44,16 @@ void serializeArangoDBRedirectException() throws IOException, ClassNotFoundExcep } @Test - void serializeArangoDBMultipleException() throws IOException, ClassNotFoundException { + void serializeArangoDBMultipleException() { List exceptions = Collections.singletonList(new RuntimeException("foo")); ArangoDBMultipleException e = new ArangoDBMultipleException(exceptions); ArangoDBMultipleException e2 = roundTrip(e); assertThat(e2.getExceptions()).hasSize(1); - assertThat(e2.getExceptions().iterator().next().getMessage()).isEqualTo("foo"); + assertThat(e2.getExceptions().getFirst().getMessage()).isEqualTo("foo"); } @Test - void serializeBaseDocument() throws IOException, ClassNotFoundException { + void serializeBaseDocument() { BaseDocument doc = new BaseDocument(); doc.setKey("test"); doc.setId("id"); @@ -64,7 +64,7 @@ void serializeBaseDocument() throws IOException, ClassNotFoundException { } @Test - void serializeBaseEdgeDocument() throws IOException, ClassNotFoundException { + void serializeBaseEdgeDocument() { BaseEdgeDocument doc = new BaseEdgeDocument(); doc.setKey("test"); doc.setId("id"); @@ -76,16 +76,20 @@ void serializeBaseEdgeDocument() throws IOException, ClassNotFoundException { assertThat(doc2).isEqualTo(doc); } - private T roundTrip(T input) throws IOException, ClassNotFoundException { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - ObjectOutputStream objectOutputStream = new ObjectOutputStream(os); - objectOutputStream.writeObject(input); + private T roundTrip(T input) { + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(os); + objectOutputStream.writeObject(input); - InputStream is = new ByteArrayInputStream(os.toByteArray()); - ObjectInputStream objectInputStream = new ObjectInputStream(is); - T output = (T) objectInputStream.readObject(); - objectInputStream.close(); + InputStream is = new ByteArrayInputStream(os.toByteArray()); + ObjectInputStream objectInputStream = new ObjectInputStream(is); + @SuppressWarnings("unchecked") T output = (T) objectInputStream.readObject(); + objectInputStream.close(); - return output; + return output; + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } } } diff --git a/test-functional/src/test/java/com/arangodb/UserAgentAsyncTest.java b/test-functional/src/test/java/com/arangodb/UserAgentAsyncTest.java index d18e46e45..805c2830e 100644 --- a/test-functional/src/test/java/com/arangodb/UserAgentAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/UserAgentAsyncTest.java @@ -1,19 +1,17 @@ package com.arangodb; import com.arangodb.util.ProtocolSource; -import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.params.ParameterizedTest; +import tools.jackson.databind.JsonNode; import java.util.concurrent.ExecutionException; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assumptions.assumeTrue; class UserAgentAsyncTest extends BaseJunit5 { @ParameterizedTest @ProtocolSource void userAgentHeader(Protocol protocol) throws ExecutionException, InterruptedException { - assumeTrue(supportsV8()); ArangoDBAsync adb = new ArangoDB.Builder() .loadProperties(config) .protocol(protocol) @@ -21,11 +19,11 @@ void userAgentHeader(Protocol protocol) throws ExecutionException, InterruptedEx .async(); Response resp = adb.execute(Request.builder() - .method(Request.Method.GET) - .path("/_admin/echo") - .build(), JsonNode.class) + .method(Request.Method.GET) + .path("/_admin/echo") + .build(), JsonNode.class) .get(); - String headerValue = resp.getBody().get("headers").get("x-arango-driver").textValue(); + String headerValue = resp.getBody().get("headers").get("x-arango-driver").stringValue(); String jvmVersion = System.getProperty("java.specification.version"); String expected = "JavaDriver/" + PackageVersion.VERSION + " (JVM/" + jvmVersion + ")"; diff --git a/test-functional/src/test/java/com/arangodb/UserAgentTest.java b/test-functional/src/test/java/com/arangodb/UserAgentTest.java index c645681c0..35c45ade6 100644 --- a/test-functional/src/test/java/com/arangodb/UserAgentTest.java +++ b/test-functional/src/test/java/com/arangodb/UserAgentTest.java @@ -1,12 +1,11 @@ package com.arangodb; import com.arangodb.util.ProtocolSource; -import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import tools.jackson.databind.JsonNode; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assumptions.assumeTrue; class UserAgentTest extends BaseJunit5 { @@ -27,8 +26,6 @@ void packageVersionIsShaded() { @ParameterizedTest @ProtocolSource void userAgentHeader(Protocol protocol) { - assumeTrue(supportsV8()); - ArangoDB adb = new ArangoDB.Builder() .loadProperties(config) .protocol(protocol) @@ -38,7 +35,7 @@ void userAgentHeader(Protocol protocol) { .method(Request.Method.GET) .path("/_admin/echo") .build(), JsonNode.class); - String headerValue = resp.getBody().get("headers").get("x-arango-driver").textValue(); + String headerValue = resp.getBody().get("headers").get("x-arango-driver").stringValue(); String jvmVersion = System.getProperty("java.specification.version"); String expected = "JavaDriver/" + PackageVersion.VERSION + " (JVM/" + jvmVersion + ")"; diff --git a/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java b/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java index 2af8441b7..4b25d24e7 100644 --- a/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java +++ b/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java @@ -35,7 +35,7 @@ class ArangoAnnotationsTest { @Test void documentFieldAnnotations() { - ArangoSerde mapper = JacksonSerde.load(); + ArangoSerde mapper = JacksonSerde.create(); AnnotatedEntity e = new AnnotatedEntity(); e.setId("Id"); @@ -45,7 +45,7 @@ void documentFieldAnnotations() { e.setTo("To"); byte[] serialized = mapper.serialize(e); - Map deserialized = mapper.deserialize(serialized, Map.class); + @SuppressWarnings("unchecked") Map deserialized = mapper.deserialize(serialized, Map.class); assertThat(deserialized) .containsEntry("_id", e.getId()) .containsEntry("_key", e.getKey()) diff --git a/test-functional/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java b/test-functional/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java index ec47e5385..c1abab038 100644 --- a/test-functional/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java @@ -27,16 +27,16 @@ import com.arangodb.internal.serde.InternalSerde; import com.arangodb.model.DocumentCreateOptions; import com.arangodb.serde.jackson.JacksonSerde; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.module.SimpleModule; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.*; +import tools.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.module.SimpleModule; -import java.io.IOException; import java.math.BigInteger; import java.util.Collections; import java.util.HashMap; @@ -44,9 +44,9 @@ import java.util.UUID; import java.util.concurrent.ExecutionException; -import static com.fasterxml.jackson.databind.DeserializationFeature.USE_BIG_INTEGER_FOR_INTS; -import static com.fasterxml.jackson.databind.SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED; import static org.assertj.core.api.Assertions.assertThat; +import static tools.jackson.databind.DeserializationFeature.USE_BIG_INTEGER_FOR_INTS; +import static tools.jackson.databind.SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED; /** @@ -64,14 +64,11 @@ class CustomSerdeAsyncTest { @BeforeAll static void init() throws ExecutionException, InterruptedException { - JacksonSerde serde = JacksonSerde.load() - .configure((mapper) -> { - mapper.configure(WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, true); - mapper.configure(USE_BIG_INTEGER_FOR_INTS, true); - SimpleModule module = new SimpleModule("PersonModule"); - module.addDeserializer(Person.class, new PersonDeserializer()); - mapper.registerModule(module); - }); + JacksonSerde serde = JacksonSerde.create(JsonMapper.builder() + .configure(WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, true) + .configure(USE_BIG_INTEGER_FOR_INTS, true) + .addModule(new SimpleModule("PersonModule").addDeserializer(Person.class, new PersonDeserializer())) + .build()); arangoDB = new ArangoDB.Builder() .loadProperties(ConfigUtils.loadConfig()) .serde(serde) @@ -131,11 +128,11 @@ void aqlSerialization() throws ExecutionException, InterruptedException { params.put("doc", doc); params.put("@collection", COLLECTION_NAME); - Map result = db.query( + @SuppressWarnings("unchecked") Map result = db.query( "INSERT @doc INTO @@collection RETURN NEW", Map.class, params - ).get().getResult().get(0); + ).get().getResult().getFirst(); assertThat(result.get("arr")).isInstanceOf(String.class); assertThat(result.get("arr")).isEqualTo("hello"); @@ -154,11 +151,11 @@ void aqlDeserialization() throws ExecutionException, InterruptedException { collection.insertDocument(doc).get(); - final Map result = db.query( + @SuppressWarnings("unchecked") final Map result = db.query( "RETURN DOCUMENT(@docId)", Map.class, Collections.singletonMap("docId", COLLECTION_NAME + "/" + key) - ).get().getResult().get(0); + ).get().getResult().getFirst(); assertThat(result.get("arr")).isInstanceOf(String.class); assertThat(result.get("arr")).isEqualTo("hello"); @@ -197,7 +194,7 @@ void getDocument() throws ExecutionException, InterruptedException { collection.insertDocument(doc).get(); - final Map result = db.collection(COLLECTION_NAME).getDocument( + @SuppressWarnings("unchecked") final Map result = db.collection(COLLECTION_NAME).getDocument( key, Map.class, null).get(); @@ -215,24 +212,24 @@ void parseNullString() { assertThat(json).isNull(); } - static class PersonSerializer extends JsonSerializer { + static class PersonSerializer extends ValueSerializer { @Override - public void serialize(Person value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(Person value, JsonGenerator gen, SerializationContext ctxt) { gen.writeStartObject(); - gen.writeFieldName("name"); + gen.writeName("name"); gen.writeString(PERSON_SERIALIZER_ADDED_PREFIX + value.name); gen.writeEndObject(); } } - static class PersonDeserializer extends JsonDeserializer { + static class PersonDeserializer extends ValueDeserializer { @Override - public Person deserialize(JsonParser parser, DeserializationContext ctx) throws IOException { + public Person deserialize(JsonParser parser, DeserializationContext ctxt) { Person person = new Person(); - JsonNode rootNode = parser.getCodec().readTree(parser); + JsonNode rootNode = ctxt.readTree(parser); JsonNode nameNode = rootNode.get("name"); - if (nameNode != null && nameNode.isTextual()) { - person.name = PERSON_DESERIALIZER_ADDED_PREFIX + nameNode.asText(); + if (nameNode != null && nameNode.isString()) { + person.name = PERSON_DESERIALIZER_ADDED_PREFIX + nameNode.asString(); } return person; } diff --git a/test-functional/src/test/java/com/arangodb/serde/CustomSerdeTest.java b/test-functional/src/test/java/com/arangodb/serde/CustomSerdeTest.java index a2657de56..e0396af9a 100644 --- a/test-functional/src/test/java/com/arangodb/serde/CustomSerdeTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/CustomSerdeTest.java @@ -27,24 +27,22 @@ import com.arangodb.internal.serde.InternalSerde; import com.arangodb.model.DocumentCreateOptions; import com.arangodb.serde.jackson.JacksonSerde; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.module.SimpleModule; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.*; +import tools.jackson.databind.annotation.JsonSerialize; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.module.SimpleModule; -import java.io.IOException; import java.math.BigInteger; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; -import static com.fasterxml.jackson.databind.DeserializationFeature.USE_BIG_INTEGER_FOR_INTS; -import static com.fasterxml.jackson.databind.SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED; import static org.assertj.core.api.Assertions.assertThat; @@ -63,14 +61,12 @@ class CustomSerdeTest { @BeforeAll static void init() { - JacksonSerde serde = JacksonSerde.load() - .configure((mapper) -> { - mapper.configure(WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, true); - mapper.configure(USE_BIG_INTEGER_FOR_INTS, true); - SimpleModule module = new SimpleModule("PersonModule"); - module.addDeserializer(Person.class, new PersonDeserializer()); - mapper.registerModule(module); - }); + JacksonSerde serde = JacksonSerde.create(JsonMapper.builder() + .configure(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, true) + .configure(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS, true) + .addModule(new SimpleModule("PersonModule").addDeserializer(Person.class, new PersonDeserializer())) + .build()); + arangoDB = new ArangoDB.Builder() .loadProperties(ConfigUtils.loadConfig()) .protocol(Protocol.HTTP_1_1) @@ -128,6 +124,7 @@ void aqlSerialization() { params.put("doc", doc); params.put("@collection", COLLECTION_NAME); + @SuppressWarnings("unchecked") Map result = db.query( "INSERT @doc INTO @@collection RETURN NEW", Map.class, @@ -151,7 +148,7 @@ void aqlDeserialization() { collection.insertDocument(doc); - final Map result = db.query( + @SuppressWarnings("unchecked") final Map result = db.query( "RETURN DOCUMENT(@docId)", Map.class, Collections.singletonMap("docId", COLLECTION_NAME + "/" + key) @@ -194,7 +191,7 @@ void getDocument() { collection.insertDocument(doc); - final Map result = db.collection(COLLECTION_NAME).getDocument( + @SuppressWarnings("unchecked") final Map result = db.collection(COLLECTION_NAME).getDocument( key, Map.class, null); @@ -212,24 +209,24 @@ void parseNullString() { assertThat(json).isNull(); } - static class PersonSerializer extends JsonSerializer { + static class PersonSerializer extends ValueSerializer { @Override - public void serialize(Person value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(Person value, JsonGenerator gen, SerializationContext ctxt) { gen.writeStartObject(); - gen.writeFieldName("name"); + gen.writeName("name"); gen.writeString(PERSON_SERIALIZER_ADDED_PREFIX + value.name); gen.writeEndObject(); } } - static class PersonDeserializer extends JsonDeserializer { + static class PersonDeserializer extends ValueDeserializer { @Override - public Person deserialize(JsonParser parser, DeserializationContext ctx) throws IOException { + public Person deserialize(JsonParser parser, DeserializationContext ctxt) { Person person = new Person(); - JsonNode rootNode = parser.getCodec().readTree(parser); + JsonNode rootNode = ctxt.readTree(parser); JsonNode nameNode = rootNode.get("name"); - if (nameNode != null && nameNode.isTextual()) { - person.name = PERSON_DESERIALIZER_ADDED_PREFIX + nameNode.asText(); + if (nameNode != null && nameNode.isString()) { + person.name = PERSON_DESERIALIZER_ADDED_PREFIX + nameNode.asString(); } return person; } diff --git a/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java b/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java index 3b0606fd5..0fcb4d994 100644 --- a/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java @@ -29,7 +29,7 @@ void bigStringInternalSerde() { @SlowTest @Test void bigStringUserSerde() { - ArangoSerde s = JacksonSerde.load(); + ArangoSerde s = JacksonSerde.create(); StringBuilder sb = new StringBuilder(); while (sb.length() < 40_000_000) { @@ -42,5 +42,4 @@ void bigStringUserSerde() { } - } diff --git a/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java b/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java index 8cfa3720c..cb2bc8ad5 100644 --- a/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java @@ -3,14 +3,13 @@ import com.arangodb.serde.annotation.*; import com.arangodb.serde.jackson.*; import com.arangodb.serde.jackson.json.JacksonJsonSerdeProvider; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; -import java.io.IOException; import java.util.UUID; import java.util.function.BiFunction; import java.util.function.Function; @@ -22,7 +21,7 @@ */ class JacksonInterferenceTest { - private final ObjectMapper mapper = new ObjectMapper(); + private final JsonMapper mapper = new JsonMapper(); private final ArangoSerde serde = new JacksonJsonSerdeProvider().create(); private FooField fooField; @@ -159,7 +158,7 @@ void serializeProp() { } @Test - void deserializeField() throws IOException { + void deserializeField() { // id testDeserialize("myId", FooField.class, foo -> foo.myId, this::jacksonDeserialize); testDeserialize("_id", FooField.class, foo -> foo.myId, this::serdeDeserialize); @@ -178,7 +177,7 @@ void deserializeField() throws IOException { } @Test - void deserializeProp() throws IOException { + void deserializeProp() { // id testDeserialize("myId", FooProp.class, FooProp::getMyId, this::jacksonDeserialize); testDeserialize("_id", FooProp.class, FooProp::getMyId, this::serdeDeserialize); @@ -203,7 +202,7 @@ void testSerialize(Object data, String fieldName, String expectedValue, Function } void testDeserialize(String fieldName, Class clazz, Function getter, - BiFunction, T> deserializer) throws IOException { + BiFunction, T> deserializer) { String fieldValue = UUID.randomUUID().toString(); ObjectNode on = JsonNodeFactory.instance.objectNode().put(fieldName, fieldValue); byte[] bytes = mapper.writeValueAsBytes(on); @@ -212,27 +211,15 @@ void testDeserialize(String fieldName, Class clazz, Function g } private JsonNode jacksonSerialize(Object data) { - try { - return mapper.readTree(mapper.writeValueAsBytes(data)); - } catch (IOException e) { - throw new RuntimeException(e); - } + return mapper.readTree(mapper.writeValueAsBytes(data)); } private JsonNode serdeSerialize(Object data) { - try { - return mapper.readTree(serde.serialize(data)); - } catch (IOException e) { - throw new RuntimeException(e); - } + return mapper.readTree(serde.serialize(data)); } private T jacksonDeserialize(byte[] bytes, Class clazz) { - try { - return mapper.readValue(bytes, clazz); - } catch (IOException e) { - throw new RuntimeException(e); - } + return mapper.readValue(bytes, clazz); } private T serdeDeserialize(byte[] bytes, Class clazz) { diff --git a/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java b/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java index d7848dd95..fd442c0e1 100644 --- a/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java @@ -6,10 +6,10 @@ import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; import java.util.*; @@ -58,8 +58,8 @@ void serializeBaseDocumentWithNestedProperties() { doc.addAttribute("properties", Collections.singletonMap("foo", "bbb")); byte[] ser = s.serialize(doc); ObjectNode on = s.deserializeUserData(ser, ObjectNode.class); - assertThat(on.get("foo").textValue()).isEqualTo("aaa"); - assertThat(on.get("properties").get("foo").textValue()).isEqualTo("bbb"); + assertThat(on.get("foo").stringValue()).isEqualTo("aaa"); + assertThat(on.get("properties").get("foo").stringValue()).isEqualTo("bbb"); } @Test diff --git a/test-functional/src/test/resources/META-INF/native-image/reflect-config.json b/test-functional/src/test/resources/META-INF/native-image/reflect-config.json index cc3e412db..3ec894275 100644 --- a/test-functional/src/test/resources/META-INF/native-image/reflect-config.json +++ b/test-functional/src/test/resources/META-INF/native-image/reflect-config.json @@ -179,24 +179,6 @@ "allDeclaredMethods": true, "allDeclaredConstructors": true }, - { - "name": "com.fasterxml.jackson.databind.deser.std.DateDeserializers$SqlDateDeserializer", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "com.fasterxml.jackson.databind.ser.std.SqlDateSerializer", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, { "name": "com.arangodb.ArangoCollectionTest$Animal", "allDeclaredMethods": true, diff --git a/test-functional/src/test/resources/simplelogger.properties b/test-functional/src/test/resources/simplelogger.properties index a2a4ce6d5..97d064869 100644 --- a/test-functional/src/test/resources/simplelogger.properties +++ b/test-functional/src/test/resources/simplelogger.properties @@ -7,7 +7,6 @@ org.slf4j.simpleLogger.showShortLogName=false org.slf4j.simpleLogger.defaultLogLevel=info -#org.slf4j.simpleLogger.log.com.arangodb.internal.serde.JacksonUtils=debug #org.slf4j.simpleLogger.log.com.arangodb.internal.net.Communication=debug #org.slf4j.simpleLogger.log.com.arangodb.internal.serde.InternalSerdeImpl=debug #org.slf4j.simpleLogger.log.io.netty.handler.logging.LoggingHandler=debug diff --git a/test-non-functional/pom.xml b/test-non-functional/pom.xml index 109921cf4..82a9b883c 100644 --- a/test-non-functional/pom.xml +++ b/test-non-functional/pom.xml @@ -20,11 +20,6 @@ - - com.arangodb - jackson3-serde-json - compile - com.arangodb jsonb-serde @@ -91,20 +86,6 @@ **/JacksonRequestContextTest.** - - - com.fasterxml.jackson.databind.JsonNode - com.arangodb.shaded.fasterxml.jackson.databind.JsonNode - - - com.fasterxml.jackson.databind.ObjectNode - com.arangodb.shaded.fasterxml.jackson.databind.ObjectNode - - - com.fasterxml.jackson.databind.node.JsonNodeFactory - com.arangodb.shaded.fasterxml.jackson.databind.node.JsonNodeFactory - - diff --git a/test-non-functional/src/test/java/CommunicationTest.java b/test-non-functional/src/test/java/CommunicationTest.java index 64888b242..1ba0d0785 100644 --- a/test-non-functional/src/test/java/CommunicationTest.java +++ b/test-non-functional/src/test/java/CommunicationTest.java @@ -21,7 +21,7 @@ void disconnectAsync(Protocol protocol) throws InterruptedException, ExecutionEx ArangoDBAsync arangoDB = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromFile()) .protocol(protocol) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .build() .async(); arangoDB.getVersion().get(); @@ -45,7 +45,7 @@ void disconnect(Protocol protocol) { ArangoDB arangoDB = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromFile()) .protocol(protocol) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .build(); arangoDB.getVersion(); diff --git a/test-non-functional/src/test/java/ConfigurationTest.java b/test-non-functional/src/test/java/ConfigurationTest.java index a0ffe4961..227ae58a1 100644 --- a/test-non-functional/src/test/java/ConfigurationTest.java +++ b/test-non-functional/src/test/java/ConfigurationTest.java @@ -14,7 +14,7 @@ public class ConfigurationTest { void fallbackHost() { final ArangoDB arangoDB = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromFile()) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .host("not-accessible", 8529) .host("172.28.0.1", 8529) .build(); @@ -26,7 +26,7 @@ void fallbackHost() { void loadPropertiesWithPrefix() { ArangoDB adb = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromFile("arangodb-with-prefix.properties", "adb")) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .build(); adb.getVersion(); adb.shutdown(); @@ -39,7 +39,7 @@ void loadConfigFromPropertiesWithPrefix() { props.setProperty("adb.password", "test"); ArangoDB adb = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromProperties(props, "adb")) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .build(); adb.getVersion(); adb.shutdown(); diff --git a/test-non-functional/src/test/java/arch/SerdeArchTest.java b/test-non-functional/src/test/java/arch/SerdeArchTest.java index 954d9c0c7..b5c26c6a2 100644 --- a/test-non-functional/src/test/java/arch/SerdeArchTest.java +++ b/test-non-functional/src/test/java/arch/SerdeArchTest.java @@ -26,11 +26,4 @@ public class SerdeArchTest { .should().dependOnClassesThat() .resideInAPackage("com.arangodb.serde.jackson.."); - @ArchTest - public static final ArchRule noDependencyOnJackson3Serde = noClasses().that() - .resideInAPackage("com.arangodb..").and() - .resideOutsideOfPackage("com.arangodb.serde.jackson3..") - .should().dependOnClassesThat() - .resideInAPackage("com.arangodb.serde.jackson3.."); - } diff --git a/test-non-functional/src/test/java/arch/ShadedArchTest.java b/test-non-functional/src/test/java/arch/ShadedArchTest.java index cc6e5318f..46278e9d9 100644 --- a/test-non-functional/src/test/java/arch/ShadedArchTest.java +++ b/test-non-functional/src/test/java/arch/ShadedArchTest.java @@ -20,7 +20,7 @@ public class ShadedArchTest { private static boolean isShaded() { boolean shaded; try { - Class.forName("com.arangodb.shaded.fasterxml.jackson.databind.JsonNode"); + Class.forName("com.arangodb.shaded.jackson.databind.JsonNode"); shaded = true; } catch (ClassNotFoundException e) { shaded = false; @@ -55,10 +55,9 @@ public void vertxRelocation() { public void jacksonRelocation() { noClasses().that() .resideInAPackage("com.arangodb..").and() - .resideOutsideOfPackage("com.arangodb.serde.jackson..").and() - .resideOutsideOfPackage("com.arangodb.serde.jackson3..") + .resideOutsideOfPackage("com.arangodb.serde.jackson..") .should().dependOnClassesThat() - .resideInAPackage("com.fasterxml.jackson..") + .resideInAPackage("tools.jackson..") .check(importedClasses); } @@ -66,12 +65,9 @@ public void jacksonRelocation() { public void noJacksonDependency() { noClasses().that() .resideInAPackage("com.arangodb..").and() - .resideOutsideOfPackages( - "com.arangodb.serde.jackson..", - "com.arangodb.serde.jackson3.." - ) + .resideOutsideOfPackage("com.arangodb.serde.jackson..") .should().dependOnClassesThat() - .resideInAPackage("com.fasterxml.jackson..") + .resideInAPackage("tools.jackson..") .check(importedClasses); } diff --git a/test-non-functional/src/test/java/concurrency/ConnectionLoadBalanceTest.java b/test-non-functional/src/test/java/concurrency/ConnectionLoadBalanceTest.java index 9fd0a4e7a..7d5dd4116 100644 --- a/test-non-functional/src/test/java/concurrency/ConnectionLoadBalanceTest.java +++ b/test-non-functional/src/test/java/concurrency/ConnectionLoadBalanceTest.java @@ -9,7 +9,6 @@ import org.junit.jupiter.params.provider.MethodSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import util.TestUtils; import java.time.Duration; import java.util.Map; @@ -53,7 +52,7 @@ void doTestLoadBalance(Config cfg, int sleepCycles) throws InterruptedException ArangoDatabaseAsync db = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromFile()) .protocol(cfg.protocol) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .maxConnections(cfg.maxConnections) .build().async().db(); diff --git a/test-non-functional/src/test/java/example/ExampleBase.java b/test-non-functional/src/test/java/example/ExampleBase.java index ae1d12219..0fdac2252 100644 --- a/test-non-functional/src/test/java/example/ExampleBase.java +++ b/test-non-functional/src/test/java/example/ExampleBase.java @@ -23,12 +23,10 @@ import com.arangodb.ArangoCollection; import com.arangodb.ArangoDB; import com.arangodb.ArangoDatabase; -import com.arangodb.Protocol; import com.arangodb.config.ArangoConfigProperties; import com.arangodb.serde.jackson.JacksonSerde; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import util.TestUtils; /** * @author Mark Vollmary @@ -46,7 +44,7 @@ static void setUp() { ArangoConfigProperties config = ArangoConfigProperties.fromFile(); arangoDB = new ArangoDB.Builder() .loadProperties(config) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .build(); String dbName = DB_NAME; if (arangoDB.db(dbName).exists()) diff --git a/test-non-functional/src/test/java/example/FirstProject.java b/test-non-functional/src/test/java/example/FirstProject.java index 2ce74358c..22061fb51 100644 --- a/test-non-functional/src/test/java/example/FirstProject.java +++ b/test-non-functional/src/test/java/example/FirstProject.java @@ -7,7 +7,7 @@ import com.arangodb.config.ArangoConfigProperties; import com.arangodb.entity.BaseDocument; import com.arangodb.entity.CollectionEntity; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; import java.util.Collections; import java.util.Map; diff --git a/test-non-functional/src/test/java/example/document/AqlQueryWithSpecialReturnTypesExampleTest.java b/test-non-functional/src/test/java/example/document/AqlQueryWithSpecialReturnTypesExampleTest.java index 8f93d4cb0..ea94dd1a7 100644 --- a/test-non-functional/src/test/java/example/document/AqlQueryWithSpecialReturnTypesExampleTest.java +++ b/test-non-functional/src/test/java/example/document/AqlQueryWithSpecialReturnTypesExampleTest.java @@ -22,11 +22,11 @@ import com.arangodb.ArangoCursor; import com.arangodb.entity.BaseDocument; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import example.ExampleBase; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; import java.util.Collections; import java.util.List; @@ -65,9 +65,9 @@ void aqlWithLimitQueryAsJsonObject() { assertThat((Object) cursor).isNotNull(); while (cursor.hasNext()) { final ObjectNode node = cursor.next(); - assertThat(node.get("name").asText()) + assertThat(node.get("name").asString()) .isIn("TestUser11", "TestUser13", "TestUser15", "TestUser17", "TestUser19"); - assertThat(node.get("gender").asText()).isEqualTo(Gender.FEMALE.name()); + assertThat(node.get("gender").asString()).isEqualTo(Gender.FEMALE.name()); assertThat(node.get("age").asInt()).isIn(21, 23, 25, 27, 29); } } @@ -81,9 +81,9 @@ void aqlWithLimitQueryAsJsonArray() { assertThat((Object) cursor).isNotNull(); while (cursor.hasNext()) { final ArrayNode arrNode = cursor.next(); - assertThat(arrNode.get(0).asText()) + assertThat(arrNode.get(0).asString()) .isIn("TestUser11", "TestUser13", "TestUser15", "TestUser17", "TestUser19"); - assertThat(arrNode.get(1).asText()).isEqualTo(Gender.FEMALE.name()); + assertThat(arrNode.get(1).asString()).isEqualTo(Gender.FEMALE.name()); assertThat(arrNode.get(2).asInt()).isIn(21, 23, 25, 27, 29); } } diff --git a/test-non-functional/src/test/java/example/document/GetDocumentExampleTest.java b/test-non-functional/src/test/java/example/document/GetDocumentExampleTest.java index e4e470028..4f69e65b2 100644 --- a/test-non-functional/src/test/java/example/document/GetDocumentExampleTest.java +++ b/test-non-functional/src/test/java/example/document/GetDocumentExampleTest.java @@ -25,10 +25,10 @@ import com.arangodb.internal.RequestContextHolder; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; -import com.fasterxml.jackson.databind.JsonNode; import example.ExampleBase; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; import java.util.Map; import java.util.UUID; @@ -67,6 +67,7 @@ void getAsBaseDocument() { @Test void getAsMap() { + @SuppressWarnings("unchecked") final Map doc = collection.getDocument(key, Map.class); assertThat(doc).isNotNull(); assertThat(doc.get("foo")).isNotNull(); @@ -77,8 +78,8 @@ void getAsMap() { void getAsJsonNode() { final JsonNode doc = collection.getDocument(key, JsonNode.class); assertThat(doc).isNotNull(); - assertThat(doc.get("foo").isTextual()).isTrue(); - assertThat(doc.get("foo").asText()).isEqualTo("bar"); + assertThat(doc.get("foo").isString()).isTrue(); + assertThat(doc.get("foo").asString()).isEqualTo("bar"); } @Test @@ -93,6 +94,7 @@ void getAsJson() { void getAsBytes() { final RawBytes doc = collection.getDocument(key, RawBytes.class); assertThat(doc.get()).isNotNull(); + @SuppressWarnings("unchecked") Map mapDoc = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> collection.getSerde().deserializeUserData(doc.get(), Map.class)); assertThat(mapDoc).containsEntry("foo", "bar"); diff --git a/test-non-functional/src/test/java/example/document/InsertDocumentExampleTest.java b/test-non-functional/src/test/java/example/document/InsertDocumentExampleTest.java index 60921d310..0f7b58887 100644 --- a/test-non-functional/src/test/java/example/document/InsertDocumentExampleTest.java +++ b/test-non-functional/src/test/java/example/document/InsertDocumentExampleTest.java @@ -23,10 +23,10 @@ import com.arangodb.entity.BaseDocument; import com.arangodb.entity.DocumentCreateEntity; import com.arangodb.util.RawJson; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import example.ExampleBase; import org.junit.jupiter.api.Test; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; import java.util.UUID; @@ -54,7 +54,7 @@ void insertBaseDocument() { @Test void insertJsonNode() { - ObjectMapper mapper = new ObjectMapper(); + JsonMapper mapper = new JsonMapper(); ObjectNode node = mapper.createObjectNode(); node.put("foo", "bar"); final DocumentCreateEntity doc = collection.insertDocument(node); diff --git a/test-non-functional/src/test/java/example/graph/AQLActorsAndMoviesExampleTest.java b/test-non-functional/src/test/java/example/graph/AQLActorsAndMoviesExampleTest.java index e1338806a..748176c18 100644 --- a/test-non-functional/src/test/java/example/graph/AQLActorsAndMoviesExampleTest.java +++ b/test-non-functional/src/test/java/example/graph/AQLActorsAndMoviesExampleTest.java @@ -33,7 +33,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import util.TestUtils; import java.util.UUID; @@ -57,7 +56,7 @@ static void setUp() { ArangoConfigProperties config = ArangoConfigProperties.fromFile(); arangoDB = new ArangoDB.Builder() .loadProperties(config) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .build(); if (arangoDB.db(TEST_DB).exists()) arangoDB.db(TEST_DB).drop(); diff --git a/test-non-functional/src/test/java/example/graph/BaseGraphTest.java b/test-non-functional/src/test/java/example/graph/BaseGraphTest.java index 1bd39eab7..4d9051745 100644 --- a/test-non-functional/src/test/java/example/graph/BaseGraphTest.java +++ b/test-non-functional/src/test/java/example/graph/BaseGraphTest.java @@ -23,14 +23,12 @@ import com.arangodb.ArangoDB; import com.arangodb.ArangoDBException; import com.arangodb.ArangoDatabase; -import com.arangodb.Protocol; import com.arangodb.config.ArangoConfigProperties; import com.arangodb.entity.EdgeDefinition; import com.arangodb.entity.VertexEntity; import com.arangodb.serde.jackson.JacksonSerde; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import util.TestUtils; import java.util.ArrayList; import java.util.Collection; @@ -53,7 +51,7 @@ static void init() { ArangoConfigProperties config = ArangoConfigProperties.fromFile(); arangoDB = new ArangoDB.Builder() .loadProperties(config) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .build(); } if (arangoDB.db(TEST_DB).exists()) diff --git a/test-non-functional/src/test/java/serde/InternalSerdeTest.java b/test-non-functional/src/test/java/serde/InternalSerdeTest.java index d425ee50f..3250863ce 100644 --- a/test-non-functional/src/test/java/serde/InternalSerdeTest.java +++ b/test-non-functional/src/test/java/serde/InternalSerdeTest.java @@ -3,12 +3,12 @@ import com.arangodb.ArangoDB; import com.arangodb.config.ArangoConfigProperties; import com.arangodb.internal.serde.InternalSerdeProvider; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.arangodb.util.RawJson; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; import java.util.Collections; import java.util.Map; diff --git a/test-non-functional/src/test/java/serde/Jackson3Person.java b/test-non-functional/src/test/java/serde/Jackson3Person.java deleted file mode 100644 index 46cb97993..000000000 --- a/test-non-functional/src/test/java/serde/Jackson3Person.java +++ /dev/null @@ -1,13 +0,0 @@ -package serde; - -import com.arangodb.serde.annotation.*; -import com.fasterxml.jackson.annotation.JsonProperty; - -public record Jackson3Person( - @Key - String key, - @JsonProperty("firstName") - String name, - int age -) { -} diff --git a/test-non-functional/src/test/java/serde/Jackson3RequestContextTest.java b/test-non-functional/src/test/java/serde/Jackson3RequestContextTest.java deleted file mode 100644 index d486f202c..000000000 --- a/test-non-functional/src/test/java/serde/Jackson3RequestContextTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * DISCLAIMER - * - * Copyright 2016 ArangoDB GmbH, Cologne, Germany - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright holder is ArangoDB GmbH, Cologne, Germany - */ - -package serde; - -import com.arangodb.*; -import com.arangodb.config.ArangoConfigProperties; -import com.arangodb.entity.BaseDocument; -import com.arangodb.entity.DocumentCreateEntity; -import com.arangodb.entity.StreamTransactionEntity; -import com.arangodb.model.DocumentReadOptions; -import com.arangodb.model.StreamTransactionOptions; -import com.arangodb.serde.jackson3.JacksonSerde; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import tools.jackson.core.JacksonException; -import tools.jackson.core.JsonParser; -import tools.jackson.databind.DeserializationContext; -import tools.jackson.databind.JsonNode; -import tools.jackson.databind.ValueDeserializer; -import tools.jackson.databind.json.JsonMapper; -import tools.jackson.databind.module.SimpleModule; - -import java.util.Collections; -import java.util.concurrent.ExecutionException; - -import static org.assertj.core.api.Assertions.assertThat; -import static util.TestUtils.TEST_DB; - -/** - * NB: excluded from shaded tests - */ -class Jackson3RequestContextTest { - - private static final String COLLECTION_NAME = "JacksonRequestContextTest_collection"; - - private static ArangoDB arangoDB; - private static ArangoDatabase db; - private static ArangoCollection collection; - private static ArangoCollectionAsync collectionAsync; - - @BeforeAll - static void init() { - SimpleModule module = new SimpleModule("PersonModule"); - module.addDeserializer(Person.class, new PersonDeserializer()); - JsonMapper mapper = JsonMapper.builder() - .addModule(module) - .build(); - - JacksonSerde serde = JacksonSerde.create(mapper); - arangoDB = new ArangoDB.Builder() - .loadProperties(ArangoConfigProperties.fromFile()) - .serde(serde).build(); - - db = arangoDB.db(TEST_DB); - if (!db.exists()) { - db.create(); - } - - collection = db.collection(COLLECTION_NAME); - collectionAsync = arangoDB.async().db(TEST_DB).collection(COLLECTION_NAME); - if (!collection.exists()) { - collection.create(); - } - } - - @AfterAll - static void shutdown() { - if (db.exists()) { - db.drop(); - } - arangoDB.shutdown(); - } - - static class PersonDeserializer extends ValueDeserializer { - @Override - public Person deserialize(JsonParser parser, DeserializationContext ctx) throws JacksonException { - JsonNode rootNode = parser.readValueAsTree(); - Person person = new Person(rootNode.get("name").asString()); - person.txId = JacksonSerde.getRequestContext(ctx).getStreamTransactionId().get(); - return person; - } - } - - static class Person { - String name; - String txId; - - Person(String name) { - this.name = name; - } - } - - @Test - void getDocumentWithinTx() { - DocumentCreateEntity doc = collection.insertDocument( - new BaseDocument(Collections.singletonMap("name", "foo")), null); - - StreamTransactionEntity tx = db - .beginStreamTransaction(new StreamTransactionOptions().readCollections(COLLECTION_NAME)); - - Person read = collection.getDocument(doc.getKey(), Person.class, - new DocumentReadOptions().streamTransactionId(tx.getId())); - - assertThat(read.name).isEqualTo("foo"); - assertThat(read.txId).isEqualTo(tx.getId()); - - db.abortStreamTransaction(tx.getId()); - } - - @Test - void asyncGetDocumentWithinTx() throws ExecutionException, InterruptedException { - DocumentCreateEntity doc = collection.insertDocument( - new BaseDocument(Collections.singletonMap("name", "foo")), null); - - StreamTransactionEntity tx = db - .beginStreamTransaction(new StreamTransactionOptions().readCollections(COLLECTION_NAME)); - - Person read = collectionAsync.getDocument(doc.getKey(), Person.class, - new DocumentReadOptions().streamTransactionId(tx.getId())) - .get(); - - assertThat(read.name).isEqualTo("foo"); - assertThat(read.txId).isEqualTo(tx.getId()); - - db.abortStreamTransaction(tx.getId()); - } - -} diff --git a/test-non-functional/src/test/java/serde/Jackson3SerdeTest.java b/test-non-functional/src/test/java/serde/Jackson3SerdeTest.java deleted file mode 100644 index 0f9a3a383..000000000 --- a/test-non-functional/src/test/java/serde/Jackson3SerdeTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package serde; - -import com.arangodb.ArangoDB; -import com.arangodb.config.ArangoConfigProperties; -import com.arangodb.serde.jackson3.json.JacksonJsonSerdeProvider; -import com.arangodb.util.RawJson; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import java.util.Collections; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -class Jackson3SerdeTest { - - private static ArangoDB adb; - - @BeforeAll - static void init() { - adb = new ArangoDB.Builder() - .loadProperties(ArangoConfigProperties.fromFile()) - .serdeProviderClass(JacksonJsonSerdeProvider.class) - .build(); - } - - @AfterAll - static void shutdown() { - adb.shutdown(); - } - - @Test - void shadedJsonNode() { - // uses the internal serde - JsonNode doc = JsonNodeFactory.instance - .objectNode() - .put("foo", "bar"); - JsonNode res = adb.db().query("return @d", JsonNode.class, Collections.singletonMap("d", doc)).next(); - assertThat(res.size()).isEqualTo(1); - assertThat(res.get("foo").asText()).isEqualTo("bar"); - JsonNode value = adb.db().query("return @d.foo", JsonNode.class, Collections.singletonMap("d", doc)).next(); - assertThat(value.textValue()).isEqualTo("bar"); - } - - @Test - void jsonNode() { - // uses the user serde - JsonNode doc = JsonNodeFactory.instance - .objectNode() - .put("foo", "bar"); - JsonNode res = adb.db().query("return @d", JsonNode.class, Collections.singletonMap("d", doc)).next(); - assertThat(res.size()).isEqualTo(1); - assertThat(res.get("foo").asText()).isEqualTo("bar"); - JsonNode value = adb.db().query("return @d.foo", JsonNode.class, Collections.singletonMap("d", doc)).next(); - assertThat(value.textValue()).isEqualTo("bar"); - } - - @Test - void map() { - Map doc = Collections.singletonMap("foo", "bar"); - Map res = adb.db().query("return @d", Map.class, Collections.singletonMap("d", doc)).next(); - assertThat(res).hasSize(1); - assertThat(res.get("foo")).isEqualTo("bar"); - String value = adb.db().query("return @d.foo", String.class, Collections.singletonMap("d", doc)).next(); - assertThat(value).isEqualTo("bar"); - } - - @Test - void rawJson() { - RawJson doc = RawJson.of(""" - {"foo":"bar"}"""); - RawJson res = adb.db().query("return @d", RawJson.class, Collections.singletonMap("d", doc)).next(); - assertThat(res.get()).isEqualTo(doc.get()); - RawJson value = adb.db().query("return @d.foo", RawJson.class, Collections.singletonMap("d", doc)).next(); - assertThat(value.get()).isEqualTo("\"bar\""); - } - - @Test - void person() { - Jackson3Person doc = new Jackson3Person("key", "Jim", 22); - Jackson3Person res = adb.db().query("return @d", Jackson3Person.class, Collections.singletonMap("d", doc)).next(); - assertThat(res).isEqualTo(doc); - String key = adb.db().query("return @d._key", String.class, Collections.singletonMap("d", doc)).next(); - assertThat(key).isEqualTo("key"); - String name = adb.db().query("return @d.firstName", String.class, Collections.singletonMap("d", doc)).next(); - assertThat(name).isEqualTo("Jim"); - } - -} diff --git a/test-non-functional/src/test/java/serde/JacksonRequestContextTest.java b/test-non-functional/src/test/java/serde/JacksonRequestContextTest.java index a610050db..b411938f1 100644 --- a/test-non-functional/src/test/java/serde/JacksonRequestContextTest.java +++ b/test-non-functional/src/test/java/serde/JacksonRequestContextTest.java @@ -28,16 +28,16 @@ import com.arangodb.model.DocumentReadOptions; import com.arangodb.model.StreamTransactionOptions; import com.arangodb.serde.jackson.JacksonSerde; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.module.SimpleModule; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.module.SimpleModule; -import java.io.IOException; import java.util.Collections; import java.util.concurrent.ExecutionException; @@ -58,12 +58,10 @@ class JacksonRequestContextTest { @BeforeAll static void init() { - JacksonSerde serde = JacksonSerde.load() - .configure((mapper) -> { - SimpleModule module = new SimpleModule("PersonModule"); - module.addDeserializer(Person.class, new PersonDeserializer()); - mapper.registerModule(module); - }); + JacksonSerde serde = JacksonSerde.create(JsonMapper.builder() + .addModule(new SimpleModule("PersonModule") + .addDeserializer(Person.class, new PersonDeserializer())) + .build()); arangoDB = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromFile()) .serde(serde).build(); @@ -88,12 +86,12 @@ static void shutdown() { arangoDB.shutdown(); } - static class PersonDeserializer extends JsonDeserializer { + static class PersonDeserializer extends ValueDeserializer { @Override - public Person deserialize(JsonParser parser, DeserializationContext ctx) throws IOException { - JsonNode rootNode = parser.getCodec().readTree(parser); - Person person = new Person(rootNode.get("name").asText()); - person.txId = JacksonSerde.getRequestContext(ctx).getStreamTransactionId().get(); + public Person deserialize(JsonParser parser, DeserializationContext ctx) { + JsonNode rootNode = ctx.readTree(parser); + Person person = new Person(rootNode.get("name").asString()); + person.txId = JacksonSerde.getRequestContext(ctx).getStreamTransactionId().orElseThrow(); return person; } } diff --git a/test-non-functional/src/test/java/serde/JacksonSerdeTest.java b/test-non-functional/src/test/java/serde/JacksonSerdeTest.java index 16ff150c0..cef6d5bf1 100644 --- a/test-non-functional/src/test/java/serde/JacksonSerdeTest.java +++ b/test-non-functional/src/test/java/serde/JacksonSerdeTest.java @@ -3,12 +3,12 @@ import com.arangodb.ArangoDB; import com.arangodb.config.ArangoConfigProperties; import com.arangodb.serde.jackson.JacksonSerde; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.arangodb.util.RawJson; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; import java.util.Collections; import java.util.Map; @@ -22,7 +22,7 @@ class JacksonSerdeTest { static void init() { adb = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromFile()) - .serde(JacksonSerde.load()) + .serde(JacksonSerde.create()) .build(); } @@ -47,14 +47,14 @@ void shadedJsonNode() { @Test void jsonNode() { // uses the user serde - com.fasterxml.jackson.databind.JsonNode doc = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance + JsonNode doc = JsonNodeFactory.instance .objectNode() .put("foo", "bar"); - com.fasterxml.jackson.databind.JsonNode res = adb.db().query("return @d", com.fasterxml.jackson.databind.JsonNode.class, Collections.singletonMap("d", doc)).next(); + JsonNode res = adb.db().query("return @d", JsonNode.class, Collections.singletonMap("d", doc)).next(); assertThat(res.size()).isEqualTo(1); - assertThat(res.get("foo").asText()).isEqualTo("bar"); - com.fasterxml.jackson.databind.JsonNode value = adb.db().query("return @d.foo", com.fasterxml.jackson.databind.JsonNode.class, Collections.singletonMap("d", doc)).next(); - assertThat(value.textValue()).isEqualTo("bar"); + assertThat(res.get("foo").asString()).isEqualTo("bar"); + JsonNode value = adb.db().query("return @d.foo", JsonNode.class, Collections.singletonMap("d", doc)).next(); + assertThat(value.stringValue()).isEqualTo("bar"); } @Test diff --git a/test-non-functional/src/test/java/serde/SerdeConfigurationTest.java b/test-non-functional/src/test/java/serde/SerdeConfigurationTest.java index 5088b408a..5074d9052 100644 --- a/test-non-functional/src/test/java/serde/SerdeConfigurationTest.java +++ b/test-non-functional/src/test/java/serde/SerdeConfigurationTest.java @@ -3,45 +3,13 @@ import com.arangodb.ArangoDB; import com.arangodb.config.ArangoConfigProperties; import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.jackson.internal.JacksonSerdeImpl; -import com.arangodb.serde.jackson.json.JacksonJsonSerdeProvider; import com.arangodb.serde.jsonb.JsonbSerde; import com.arangodb.serde.jsonb.JsonbSerdeProvider; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.VarHandle; - import static org.assertj.core.api.Assertions.assertThat; public class SerdeConfigurationTest { - private final VarHandle JACKSON_SERDE_IMPL_MAPPER; - { - try { - JACKSON_SERDE_IMPL_MAPPER = MethodHandles - .privateLookupIn(JacksonSerdeImpl.class, MethodHandles.lookup()) - .findVarHandle(JacksonSerdeImpl.class, "mapper", ObjectMapper.class); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - - @Test - void jsonSerdeProvider() { - ArangoDB adb = new ArangoDB.Builder() - .host("foo", 1111) - .serdeProviderClass(JacksonJsonSerdeProvider.class) - .build(); - - ArangoSerde serde = adb.getSerde().getUserSerde(); - assertThat(serde).isInstanceOf(JacksonSerdeImpl.class); - - ObjectMapper mapper = (ObjectMapper) JACKSON_SERDE_IMPL_MAPPER.get(serde); - assertThat(mapper.getFactory().getFormatName()).isEqualTo("JSON"); - } - @Test void jsonBSerdeProvider() { @@ -64,15 +32,4 @@ void jsonBSerdeProviderFromConfigFile() { assertThat(serde).isInstanceOf(JsonbSerde.class); } - @Test - void jackson3SerdeProvider() { - ArangoDB adb = new ArangoDB.Builder() - .host("foo", 1111) - .serdeProviderClass(com.arangodb.serde.jackson3.json.JacksonJsonSerdeProvider.class) - .build(); - - ArangoSerde serde = adb.getSerde().getUserSerde(); - assertThat(serde).isInstanceOf(com.arangodb.serde.jackson3.internal.JacksonSerdeImpl.class); - } - } diff --git a/test-non-functional/src/test/resources/simplelogger.properties b/test-non-functional/src/test/resources/simplelogger.properties index 495a73812..d79a72d6d 100644 --- a/test-non-functional/src/test/resources/simplelogger.properties +++ b/test-non-functional/src/test/resources/simplelogger.properties @@ -7,7 +7,6 @@ org.slf4j.simpleLogger.showShortLogName=false org.slf4j.simpleLogger.defaultLogLevel=info -#org.slf4j.simpleLogger.log.com.arangodb.internal.serde.JacksonUtils=debug #org.slf4j.simpleLogger.log.com.arangodb.internal.net.Communication=debug #org.slf4j.simpleLogger.log.io.netty.handler.logging.LoggingHandler=debug #org.slf4j.simpleLogger.log.io.netty.handler.codec.http2.Http2FrameLogger=debug diff --git a/test-perf/src/main/java/com/arangodb/SerdeBench.java b/test-perf/src/main/java/com/arangodb/SerdeBench.java index 1113495c1..55a5e6ae6 100644 --- a/test-perf/src/main/java/com/arangodb/SerdeBench.java +++ b/test-perf/src/main/java/com/arangodb/SerdeBench.java @@ -9,8 +9,6 @@ import com.arangodb.internal.serde.InternalSerdeProvider; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.JsonNode; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; @@ -27,6 +25,8 @@ import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; import java.io.BufferedReader; import java.io.IOException; @@ -75,7 +75,7 @@ public static class Data { public final InternalResponse jsonResp = new InternalResponse(); public Data() { - ObjectMapper jsonMapper = new ObjectMapper(); + JsonMapper jsonMapper = new JsonMapper(); try { JsonNode jn = readFile("/api-docs.json", jsonMapper); @@ -91,19 +91,21 @@ public Data() { } } - private JsonNode readFile(String filename, ObjectMapper mapper) throws IOException { + private JsonNode readFile(String filename, JsonMapper mapper) { InputStream inputStream = SerdeBench.class.getResourceAsStream(filename); String str = readFromInputStream(inputStream); return mapper.readTree(str); } - private String readFromInputStream(InputStream inputStream) throws IOException { + private String readFromInputStream(InputStream inputStream) { StringBuilder resultStringBuilder = new StringBuilder(); try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { String line; while ((line = br.readLine()) != null) { resultStringBuilder.append(line).append("\n"); } + } catch (IOException e) { + throw new RuntimeException(e); } return resultStringBuilder.toString(); } diff --git a/test-resilience/src/test/java/resilience/ClusterTest.java b/test-resilience/src/test/java/resilience/ClusterTest.java index f8332637b..869db0012 100644 --- a/test-resilience/src/test/java/resilience/ClusterTest.java +++ b/test-resilience/src/test/java/resilience/ClusterTest.java @@ -5,10 +5,10 @@ import com.arangodb.ArangoDBAsync; import com.arangodb.Protocol; import com.arangodb.Request; -import com.fasterxml.jackson.databind.node.ObjectNode; import eu.rekawek.toxiproxy.Proxy; import eu.rekawek.toxiproxy.ToxiproxyClient; import org.junit.jupiter.api.*; +import tools.jackson.databind.node.ObjectNode; import java.io.IOException; import java.util.Arrays; @@ -91,8 +91,7 @@ protected static String serverIdGET(ArangoDB adb) { .build(), ObjectNode.class) .getBody() .get("serverInfo") - .get("serverId") - .textValue(); + .get("serverId").stringValue(); } protected static String serverIdGET(ArangoDBAsync adb) { @@ -104,8 +103,7 @@ protected static String serverIdGET(ArangoDBAsync adb) { .get() .getBody() .get("serverInfo") - .get("serverId") - .textValue(); + .get("serverId").stringValue(); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } @@ -118,8 +116,7 @@ protected static String serverIdPOST(ArangoDB adb) { .build(), ObjectNode.class) .getBody() .get("serverInfo") - .get("serverId") - .textValue(); + .get("serverId").stringValue(); } protected static String serverIdPOST(ArangoDBAsync adb) { @@ -131,8 +128,7 @@ protected static String serverIdPOST(ArangoDBAsync adb) { .get() .getBody() .get("serverInfo") - .get("serverId") - .textValue(); + .get("serverId").stringValue(); } catch (ExecutionException e) { Throwable cause = e.getCause(); if (cause instanceof RuntimeException) { diff --git a/test-resilience/src/test/java/resilience/logging/RequestLoggingTest.java b/test-resilience/src/test/java/resilience/logging/RequestLoggingTest.java index 5b0ba1589..6fb6cbdef 100644 --- a/test-resilience/src/test/java/resilience/logging/RequestLoggingTest.java +++ b/test-resilience/src/test/java/resilience/logging/RequestLoggingTest.java @@ -5,11 +5,10 @@ import com.arangodb.ArangoDB; import com.arangodb.Protocol; import com.arangodb.internal.net.Communication; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.params.ParameterizedTest; import resilience.SingleServerTest; import resilience.utils.ProtocolSource; +import tools.jackson.databind.json.JsonMapper; import java.util.Collections; import java.util.Map; @@ -17,7 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class RequestLoggingTest extends SingleServerTest { - private final static ObjectMapper mapper = new ObjectMapper(); + private final static JsonMapper mapper = new JsonMapper(); public RequestLoggingTest() { super(Collections.singletonMap(Communication.class, Level.DEBUG)); @@ -73,7 +72,7 @@ private String meta(String log) { } @SuppressWarnings("unchecked") - private Map body(String log) throws JsonProcessingException { + private Map body(String log) { return mapper.readValue(log.substring(log.indexOf("} {") + 2), Map.class); } diff --git a/test-resilience/src/test/java/resilience/mock/SerdeTest.java b/test-resilience/src/test/java/resilience/mock/SerdeTest.java index c0285b4be..1835a7155 100644 --- a/test-resilience/src/test/java/resilience/mock/SerdeTest.java +++ b/test-resilience/src/test/java/resilience/mock/SerdeTest.java @@ -6,10 +6,9 @@ import com.arangodb.Response; import com.arangodb.entity.MultiDocumentEntity; import com.arangodb.util.RawJson; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.Test; import resilience.MockTest; +import tools.jackson.databind.JsonNode; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -49,7 +48,7 @@ void unparsableData() { assertThat(suppressed[0]) .isInstanceOf(ArangoDBException.class) .cause() - .isInstanceOf(JsonParseException.class); + .isInstanceOf(IllegalAccessError.class); assertThat(logs.getLogs()) .filteredOn(e -> e.getLevel().equals(Level.DEBUG)) .anySatisfy(e -> assertThat(e.getFormattedMessage()) @@ -132,16 +131,17 @@ void getDocumentsWithErrorField() { MultiDocumentEntity res = arangoDB.db().collection("col").getDocuments(keys, JsonNode.class); assertThat(res.getErrors()).isEmpty(); assertThat(res.getDocuments()).hasSize(3) - .anySatisfy(d -> assertThat(d.get("_key").textValue()).isEqualTo("1")) - .anySatisfy(d -> assertThat(d.get("_key").textValue()).isEqualTo("2")) - .anySatisfy(d -> assertThat(d.get("_key").textValue()).isEqualTo("3")); + .anySatisfy(d -> assertThat(d.get("_key").stringValue()).isEqualTo("1")) + .anySatisfy(d -> assertThat(d.get("_key").stringValue()).isEqualTo("2")) + .anySatisfy(d -> assertThat(d.get("_key").stringValue()).isEqualTo("3")); } @Test void getXArangoDumpJsonLines() { - String resp = "{\"a\":1}\n" + - "{\"b\":2}\n" + - "{\"c\":3}"; + String resp = """ + {"a":1} + {"b":2} + {"c":3}"""; mockServer .when( diff --git a/tutorial/Tutorial.md b/tutorial/Tutorial.md index 934c5b800..5438e8f18 100644 --- a/tutorial/Tutorial.md +++ b/tutorial/Tutorial.md @@ -188,7 +188,7 @@ Attribute b: 53 Some details you should know about the code: - The `getDocument()` method returns the stored document as instance of - `com.fasterxml.jackson.databind.JsonNode`. + `JsonNode`. ### Create a document from JSON String diff --git a/tutorial/maven/src/main/java/FirstProject.java b/tutorial/maven/src/main/java/FirstProject.java index eab073c13..d64e76b09 100644 --- a/tutorial/maven/src/main/java/FirstProject.java +++ b/tutorial/maven/src/main/java/FirstProject.java @@ -1,8 +1,6 @@ import com.arangodb.*; import com.arangodb.entity.BaseDocument; import com.arangodb.util.RawJson; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; import java.util.Collections; import java.util.Map; From 8d661c96a2c48619df79cde9fa7e8fdc5978cece Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 10 Apr 2026 15:49:42 +0200 Subject: [PATCH 03/14] fix resilience tests --- .../test/java/resilience/compression/CompressionTest.java | 6 +++--- .../src/test/java/resilience/mock/SerdeTest.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test-resilience/src/test/java/resilience/compression/CompressionTest.java b/test-resilience/src/test/java/resilience/compression/CompressionTest.java index 49cb0b0c5..97667fa5e 100644 --- a/test-resilience/src/test/java/resilience/compression/CompressionTest.java +++ b/test-resilience/src/test/java/resilience/compression/CompressionTest.java @@ -51,11 +51,11 @@ void doTest(Protocol protocol, Compression compression) { .compressionThreshold(0) .build(); - List data = IntStream.range(0, 500) + String data = IntStream.range(0, 10_000) .mapToObj(i -> UUID.randomUUID().toString()) - .collect(Collectors.toList()); + .collect(Collectors.joining()); - adb.db().query("FOR i IN @data RETURN i", String.class, + adb.db().query("RETURN @data", String.class, Collections.singletonMap("data", data)).asListRemaining(); adb.shutdown(); diff --git a/test-resilience/src/test/java/resilience/mock/SerdeTest.java b/test-resilience/src/test/java/resilience/mock/SerdeTest.java index 1835a7155..696126848 100644 --- a/test-resilience/src/test/java/resilience/mock/SerdeTest.java +++ b/test-resilience/src/test/java/resilience/mock/SerdeTest.java @@ -8,6 +8,7 @@ import com.arangodb.util.RawJson; import org.junit.jupiter.api.Test; import resilience.MockTest; +import tools.jackson.core.JacksonException; import tools.jackson.databind.JsonNode; import java.nio.charset.StandardCharsets; @@ -46,9 +47,8 @@ void unparsableData() { Throwable[] suppressed = thrown.getCause().getSuppressed(); assertThat(suppressed).hasSize(1); assertThat(suppressed[0]) - .isInstanceOf(ArangoDBException.class) - .cause() - .isInstanceOf(IllegalAccessError.class); + .isInstanceOf(JacksonException.class) + .hasMessageContaining("Unrecognized token"); assertThat(logs.getLogs()) .filteredOn(e -> e.getLevel().equals(Level.DEBUG)) .anySatisfy(e -> assertThat(e.getFormattedMessage()) From 9f497b6f6dbfad5622b1c6797782364ee961c024 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 13 Apr 2026 22:31:17 +0200 Subject: [PATCH 04/14] fix shaded driver --- .circleci/config.yml | 12 +--- .../java/com/arangodb/PackageVersion.java.in | 2 +- .../serde/InternalMapperProvider.java | 58 ------------------- .../internal/serde/InternalSerdeImpl.java | 27 +++++++-- .../internal/serde/InternalSerdeProvider.java | 4 +- .../arangodb/internal/serde/SerdeUtils.java | 14 ++--- http-protocol/pom.xml | 6 ++ pom.xml | 4 +- shaded/pom.xml | 21 ++++++- test-functional/pom.xml | 18 ++++++ 10 files changed, 76 insertions(+), 90 deletions(-) delete mode 100644 core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java diff --git a/.circleci/config.yml b/.circleci/config.yml index fe7510f46..6033ebeae 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -509,16 +509,8 @@ workflows: matrix: parameters: args: - - '-Dadb.jackson.version=2.21.1' - - '-Dadb.jackson.version=2.20.2' - - '-Dadb.jackson.version=2.19.4' - - '-Dadb.jackson.version=2.18.6' - - '-Dadb.jackson.version=2.17.3' - - '-Dadb.jackson.version=2.16.2' - - '-Dadb.jackson.version=2.15.4' - - '-Dadb.jackson.version=2.14.3' - - '-Dadb.jackson.version=2.13.5' - - '-Dadb.jackson.version=2.12.7' + - '-Dadb.jackson.version=3.0.4' + - '-Dadb.jackson.version=3.1.2' filters: tags: only: /^v.*/ diff --git a/core/src/main/java/com/arangodb/PackageVersion.java.in b/core/src/main/java/com/arangodb/PackageVersion.java.in index 47991a195..7db1e54ad 100644 --- a/core/src/main/java/com/arangodb/PackageVersion.java.in +++ b/core/src/main/java/com/arangodb/PackageVersion.java.in @@ -9,7 +9,7 @@ public final class PackageVersion { private static boolean isShaded() { try { - Class.forName("com.arangodb.shaded.fasterxml.jackson.core.JsonFactory"); + Class.forName("com.arangodb.shaded.jackson.core.json.JsonFactory"); return true; } catch (ClassNotFoundException e) { return false; diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java b/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java deleted file mode 100644 index c04f36ca6..000000000 --- a/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.arangodb.internal.serde; - -import com.arangodb.ArangoDBException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import tools.jackson.core.StreamReadConstraints; -import tools.jackson.core.StreamReadFeature; -import tools.jackson.core.StreamWriteConstraints; -import tools.jackson.core.TokenStreamFactory; -import tools.jackson.core.json.JsonFactory; -import tools.jackson.core.json.JsonWriteFeature; -import tools.jackson.databind.json.JsonMapper; - -import java.util.Iterator; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; - -class InternalMapperProvider { - private static final Logger LOG = LoggerFactory.getLogger(InternalMapperProvider.class); - - static JsonMapper load() { - ServiceLoader sl = ServiceLoader.load(TokenStreamFactory.class); - Iterator iterator = sl.iterator(); - while (iterator.hasNext()) { - TokenStreamFactory tsf; - try { - tsf = iterator.next(); - } catch (ServiceConfigurationError e) { - LOG.warn("ServiceLoader failed to load JsonFactory", e); - continue; - } - if (!"JSON".equals(tsf.getFormatName())) { - LOG.debug("JSON not supported by TokenStreamFactory: {}", tsf.getClass().getName()); - } else if (!(tsf instanceof JsonFactory jf)) { - LOG.debug("TokenStreamFactory is not instance of JsonFactory: {}", tsf.getClass().getName()); - } else { - return new JsonMapper( - jf.rebuild() - .disable(JsonWriteFeature.ESCAPE_FORWARD_SLASHES) - .disable(JsonWriteFeature.COMBINE_UNICODE_SURROGATES_IN_UTF8) - .enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION) - .streamReadConstraints(StreamReadConstraints.builder() - .maxNumberLength(Integer.MAX_VALUE) - .maxStringLength(Integer.MAX_VALUE) - .maxNestingDepth(Integer.MAX_VALUE) - .maxNameLength(Integer.MAX_VALUE) - .maxDocumentLength(Long.MAX_VALUE) - .maxTokenCount(Integer.MAX_VALUE) - .build()) - .streamWriteConstraints(StreamWriteConstraints.builder() - .maxNestingDepth(Integer.MAX_VALUE) - .build()) - .build()); - } - } - throw new ArangoDBException("No JsonFactory found for content type JSON"); - } -} diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java index 24b8960b9..4c3b841d3 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory; import tools.jackson.core.*; import tools.jackson.core.json.JsonFactory; +import tools.jackson.core.json.JsonWriteFeature; import tools.jackson.databind.*; import tools.jackson.databind.exc.MismatchedInputException; import tools.jackson.databind.json.JsonMapper; @@ -33,8 +34,25 @@ final class InternalSerdeImpl implements InternalSerde { private final ArangoSerde userSerde; private final JsonMapper mapper; - InternalSerdeImpl(final JsonMapper mapper, final ArangoSerde userSerde) { - var builder = mapper.rebuild() + InternalSerdeImpl(final ArangoSerde userSerde) { + var jsonFactory = JsonFactory.builder() + .disable(JsonWriteFeature.ESCAPE_FORWARD_SLASHES) + .disable(JsonWriteFeature.COMBINE_UNICODE_SURROGATES_IN_UTF8) + .enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION) + .streamReadConstraints(StreamReadConstraints.builder() + .maxNumberLength(Integer.MAX_VALUE) + .maxStringLength(Integer.MAX_VALUE) + .maxNestingDepth(Integer.MAX_VALUE) + .maxNameLength(Integer.MAX_VALUE) + .maxDocumentLength(Long.MAX_VALUE) + .maxTokenCount(Integer.MAX_VALUE) + .build()) + .streamWriteConstraints(StreamWriteConstraints.builder() + .maxNestingDepth(Integer.MAX_VALUE) + .build()) + .build(); + + var builder = JsonMapper.builder(jsonFactory) .deactivateDefaultTyping() .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .addModule(InternalModule.get(this)) @@ -45,7 +63,6 @@ final class InternalSerdeImpl implements InternalSerde { new UserDataDeserializer(this) )); - // JSON-P datatypes JSONPModule jsonPModule = null; try { @@ -132,7 +149,7 @@ public byte[] serializeUserData(Object value) { Class clazz = value.getClass(); if (RawBytes.class.equals(clazz)) { return ((RawBytes) value).get(); - } else if (RawJson.class.equals(clazz) && JsonFactory.FORMAT_NAME_JSON.equals(mapper.tokenStreamFactory().getFormatName())) { + } else if (RawJson.class.equals(clazz)) { return ((RawJson) value).get().getBytes(StandardCharsets.UTF_8); } else if (SerdeUtils.isManagedClass(clazz)) { return serialize(value); @@ -222,7 +239,7 @@ public T deserialize(final byte[] content, final Type type) { } if (RawBytes.class.equals(type)) { return (T) RawBytes.of(content); - } else if (RawJson.class.equals(type) && JsonFactory.FORMAT_NAME_JSON.equals(mapper.tokenStreamFactory().getFormatName())) { + } else if (RawJson.class.equals(type)) { return (T) RawJson.of(new String(content, StandardCharsets.UTF_8)); } else { return mapper.readerFor(mapper.constructType(type)).readValue(content); diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java index 32ba02623..dfbef7765 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java @@ -18,11 +18,11 @@ public InternalSerde create() { /** * Creates a new InternalSerde with default settings. * - * @param userSerde user serde + * @param userSerde user serde * @return the created InternalSerde */ public InternalSerde create(ArangoSerde userSerde) { - return new InternalSerdeImpl(InternalMapperProvider.load(), userSerde); + return new InternalSerdeImpl(userSerde); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java index 2681f4b91..128b496cd 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java @@ -25,10 +25,8 @@ public enum SerdeUtils { private static final Logger LOGGER = LoggerFactory.getLogger(SerdeUtils.class); - private final JsonMapper jsonMapper = new JsonMapper(); - public static Type constructListType(Class clazz) { - return INSTANCE.jsonMapper.getTypeFactory().constructCollectionType(List.class, clazz); + return JsonMapper.shared().getTypeFactory().constructCollectionType(List.class, clazz); } public static Type constructParametricType(Class rawType, Type... rawArgs) { @@ -55,16 +53,12 @@ static void checkSupportedJacksonVersion() { ).forEach(version -> { int major = version.getMajorVersion(); int minor = version.getMinorVersion(); - if (major != 2 || minor < 10 || minor > 21) { + if (major != 3 || minor > 1) { LOGGER.warn("Unsupported Jackson version: {}", version); } }); } - public JsonMapper getJsonMapper() { - return jsonMapper; - } - /** * Parse a JSON string. * @@ -72,7 +66,7 @@ public JsonMapper getJsonMapper() { * @return root of the parsed tree */ public JsonNode parseJson(final String json) { - return jsonMapper.readTree(json); + return JsonMapper.shared().readTree(json); } /** @@ -80,7 +74,7 @@ public JsonNode parseJson(final String json) { * @return JSON string */ public String writeJson(final JsonNode data) { - return jsonMapper.writeValueAsString(data); + return JsonMapper.shared().writeValueAsString(data); } /** diff --git a/http-protocol/pom.xml b/http-protocol/pom.xml index fa4277c7e..826ddb885 100644 --- a/http-protocol/pom.xml +++ b/http-protocol/pom.xml @@ -28,6 +28,12 @@ io.vertx vertx-web-client compile + + + com.fasterxml.jackson.core + jackson-core + + diff --git a/pom.xml b/pom.xml index 76a3a3e9a..1f701ce75 100644 --- a/pom.xml +++ b/pom.xml @@ -245,14 +245,14 @@ com.fasterxml.jackson jackson-bom - 2.21.1 + 2.21.2 import pom tools.jackson jackson-bom - 3.1.1 + 3.1.2 import pom diff --git a/shaded/pom.xml b/shaded/pom.xml index 197ec6f07..42ef68ba6 100644 --- a/shaded/pom.xml +++ b/shaded/pom.xml @@ -80,8 +80,12 @@ - com.fasterxml.jackson - com.arangodb.shaded.fasterxml.jackson + com.fasterxml.jackson.annotation + com.arangodb.shaded.fasterxml.jackson.annotation + + + tools.jackson + com.arangodb.shaded.jackson io.netty @@ -107,6 +111,13 @@ META-INF/maven/** + + tools.jackson.core:* + + META-INF/** + module-info.class + + io.netty:* @@ -121,6 +132,12 @@ META-INF/** + + tools.jackson.datatype:jackson-datatype-jakarta-jsonp + + META-INF/MANIFEST.MF + + diff --git a/test-functional/pom.xml b/test-functional/pom.xml index 59760adec..b9947e2d2 100644 --- a/test-functional/pom.xml +++ b/test-functional/pom.xml @@ -45,6 +45,24 @@ **/HttpProxyTest.**, **/RequestContextTest.** + + + tools.jackson.databind.JsonNode + com.arangodb.shaded.jackson.databind.JsonNode + + + tools.jackson.databind.ObjectNode + com.arangodb.shaded.jackson.databind.ObjectNode + + + tools.jackson.databind.node + com.arangodb.shaded.jackson.databind.node + + + tools.jackson.databind.json.JsonMapper + com.arangodb.shaded.jackson.databind.json.JsonMapper + + From 028260c72b01a51d9b403f174b5b97f2dd94ca60 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 14 Apr 2026 12:14:03 +0200 Subject: [PATCH 05/14] internal user serde refactoring --- .../internal/config/ArangoConfig.java | 3 +- .../internal/serde/InternalSerde.java | 37 +++++++++-- .../internal/serde/InternalSerdeImpl.java | 7 +-- .../internal/serde/InternalSerdeProvider.java | 28 --------- .../internal/serde/InternalUserSerde.java | 56 +++++++++++++++++ ...ternalUserSerdeAnnotationIntrospector.java | 62 +++++++++++++++++++ .../serde/InternalUserSerdeProvider.java | 18 ++++++ .../arangodb/serde/ArangoSerdeProvider.java | 4 +- .../ArangoSerdeAnnotationIntrospector.java | 5 +- .../jackson/internal/JacksonSerdeImpl.java | 2 - .../serde/JacksonConfigurationTest.java | 4 +- .../java/com/arangodb/serde/SerdeTest.java | 14 ++--- .../test/java/serde/InternalSerdePerson.java | 3 +- .../test/java/serde/InternalSerdeTest.java | 4 +- .../main/java/com/arangodb/SerdeBench.java | 7 +-- 15 files changed, 192 insertions(+), 62 deletions(-) delete mode 100644 core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java create mode 100644 core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java create mode 100644 core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeAnnotationIntrospector.java create mode 100644 core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeProvider.java diff --git a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java index 7d5c7ea88..5633d7857 100644 --- a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java +++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java @@ -9,7 +9,6 @@ import com.arangodb.entity.LoadBalancingStrategy; import com.arangodb.internal.ArangoDefaults; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.internal.serde.InternalSerdeProvider; import com.arangodb.serde.ArangoSerde; import com.arangodb.serde.ArangoSerdeProvider; @@ -312,7 +311,7 @@ public ArangoSerde getUserDataSerde() { public InternalSerde getInternalSerde() { if (internalSerde == null) { - internalSerde = new InternalSerdeProvider().create(getUserDataSerde()); + internalSerde = InternalSerde.create(getUserDataSerde()); } return internalSerde; } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java index 183913838..3ac08fd04 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java @@ -8,7 +8,17 @@ import java.lang.reflect.Type; @UsedInApi -public interface InternalSerde extends ArangoSerde { +public interface InternalSerde { + + /** + * Creates a new InternalSerde with default settings. + * + * @param userSerde user serde + * @return the created InternalSerde + */ + static InternalSerde create(ArangoSerde userSerde) { + return new InternalSerdeImpl(userSerde); + } /** * Used for logging and debugging. @@ -32,7 +42,7 @@ public interface InternalSerde extends ArangoSerde { /** * Deserializes the content and binds it to the target data type. * - * @param content UTF-8 byte encoded JSON string + * @param content UTF-8 byte encoded JSON string * @param type target data type * @return deserialized object */ @@ -41,7 +51,7 @@ public interface InternalSerde extends ArangoSerde { /** * Deserializes the parsed json node and binds it to the target data type. * - * @param node parsed json node + * @param node parsed JSON node * @param clazz class of target data type * @return deserialized object */ @@ -52,12 +62,21 @@ default T deserialize(JsonNode node, Class clazz) { /** * Deserializes the parsed json node and binds it to the target data type. * - * @param node parsed json node + * @param node parsed JSON node * @param type target data type * @return deserialized object */ T deserialize(JsonNode node, Type type); + /** + * Deserializes the content and binds it to the target data type. + * + * @param content UTF-8 byte encoded JSON string + * @param clazz class of target data type + * @return deserialized object + */ + T deserialize(byte[] content, Class clazz); + /** * Parses the content at json pointer. * @@ -91,6 +110,14 @@ default T deserialize(byte[] content, String jsonPointer, Type type) { return deserialize(extract(content, jsonPointer), type); } + /** + * Serializes the object to UTF-8 byte encoded JSON string + * + * @param value object to serialize + * @return serialized byte array + */ + byte[] serialize(Object value); + /** * Serializes the object into the target data type, using the user serde. * @@ -120,7 +147,7 @@ default T deserialize(byte[] content, String jsonPointer, Type type) { * Deserializes the content and binds it to the target data type, using the user serde. * * @param content byte array to deserialize - * @param clazz class of target data type + * @param clazz class of target data type * @return deserialized object */ T deserializeUserData(byte[] content, JavaType clazz); diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java index 4c3b841d3..7516636ba 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -11,7 +11,6 @@ import org.slf4j.LoggerFactory; import tools.jackson.core.*; import tools.jackson.core.json.JsonFactory; -import tools.jackson.core.json.JsonWriteFeature; import tools.jackson.databind.*; import tools.jackson.databind.exc.MismatchedInputException; import tools.jackson.databind.json.JsonMapper; @@ -20,6 +19,7 @@ import java.io.ByteArrayOutputStream; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; +import java.util.Objects; import static com.arangodb.internal.serde.SerdeUtils.checkSupportedJacksonVersion; import static com.arangodb.internal.serde.SerdeUtils.extractBytes; @@ -35,9 +35,8 @@ final class InternalSerdeImpl implements InternalSerde { private final JsonMapper mapper; InternalSerdeImpl(final ArangoSerde userSerde) { + Objects.requireNonNull(userSerde); var jsonFactory = JsonFactory.builder() - .disable(JsonWriteFeature.ESCAPE_FORWARD_SLASHES) - .disable(JsonWriteFeature.COMBINE_UNICODE_SURROGATES_IN_UTF8) .enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION) .streamReadConstraints(StreamReadConstraints.builder() .maxNumberLength(Integer.MAX_VALUE) @@ -54,9 +53,7 @@ final class InternalSerdeImpl implements InternalSerde { var builder = JsonMapper.builder(jsonFactory) .deactivateDefaultTyping() - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .addModule(InternalModule.get(this)) - .enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION) .changeDefaultPropertyInclusion(i -> i.withValueInclusion(JsonInclude.Include.NON_NULL)) .annotationIntrospector(new InternalAnnotationIntrospector( new UserDataSerializer(this), diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java deleted file mode 100644 index dfbef7765..000000000 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.arangodb.internal.serde; - -import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.ArangoSerdeProvider; - -public class InternalSerdeProvider implements ArangoSerdeProvider { - - /** - * Creates a new InternalSerde with default settings. - * - * @return the created InternalSerde - */ - @Override - public InternalSerde create() { - return create(null); - } - - /** - * Creates a new InternalSerde with default settings. - * - * @param userSerde user serde - * @return the created InternalSerde - */ - public InternalSerde create(ArangoSerde userSerde) { - return new InternalSerdeImpl(userSerde); - } - -} diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java new file mode 100644 index 000000000..e0de65da4 --- /dev/null +++ b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java @@ -0,0 +1,56 @@ +package com.arangodb.internal.serde; + +import com.arangodb.RequestContext; +import com.arangodb.serde.ArangoSerde; +import tools.jackson.core.*; +import tools.jackson.core.json.JsonFactory; +import tools.jackson.databind.cfg.ContextAttributes; +import tools.jackson.databind.json.JsonMapper; + +final class InternalUserSerde implements ArangoSerde { + public static final String SERDE_CONTEXT_ATTRIBUTE_NAME = "arangoRequestContext"; + + private final JsonMapper mapper; + + InternalUserSerde() { + var jsonFactory = JsonFactory.builder() + .streamReadConstraints(StreamReadConstraints.builder() + .maxNumberLength(Integer.MAX_VALUE) + .maxStringLength(Integer.MAX_VALUE) + .maxNestingDepth(Integer.MAX_VALUE) + .maxNameLength(Integer.MAX_VALUE) + .maxDocumentLength(Long.MAX_VALUE) + .maxTokenCount(Integer.MAX_VALUE) + .build()) + .streamWriteConstraints(StreamWriteConstraints.builder() + .maxNestingDepth(Integer.MAX_VALUE) + .build()) + .build(); + + var builder = JsonMapper.builder(jsonFactory) + .deactivateDefaultTyping() + .annotationIntrospector(new InternalUserSerdeAnnotationIntrospector()); + + this.mapper = builder.build(); + } + + @Override + public byte[] serialize(final Object value) { + return mapper.writeValueAsBytes(value); + } + + @Override + public T deserialize(final byte[] content, final Class type) { + return deserialize(content, type, RequestContext.EMPTY); + } + + @Override + public T deserialize(byte[] content, Class type, RequestContext ctx) { + if (content == null || content.length == 0) { + return null; + } + return mapper.readerFor(mapper.constructType(type)) + .with(ContextAttributes.getEmpty().withPerCallAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) + .readValue(content); + } +} diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeAnnotationIntrospector.java b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeAnnotationIntrospector.java new file mode 100644 index 000000000..33635155b --- /dev/null +++ b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeAnnotationIntrospector.java @@ -0,0 +1,62 @@ +package com.arangodb.internal.serde; + +import com.arangodb.serde.annotation.*; +import com.fasterxml.jackson.annotation.JsonInclude; +import tools.jackson.databind.PropertyName; +import tools.jackson.databind.cfg.MapperConfig; +import tools.jackson.databind.introspect.Annotated; +import tools.jackson.databind.introspect.JacksonAnnotationIntrospector; + +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +class InternalUserSerdeAnnotationIntrospector extends JacksonAnnotationIntrospector { + private static final JsonInclude JSON_INCLUDE_NON_NULL = JsonIncludeNonNull.class.getAnnotation(JsonInclude.class); + private static final Map, String> MAPPINGS; + private static final Class[] ANNOTATIONS; + + static { + MAPPINGS = new HashMap<>(); + MAPPINGS.put(Id.class, "_id"); + MAPPINGS.put(Key.class, "_key"); + MAPPINGS.put(Rev.class, "_rev"); + MAPPINGS.put(From.class, "_from"); + MAPPINGS.put(To.class, "_to"); + @SuppressWarnings("unchecked") + Class[] annotations = MAPPINGS.keySet().toArray(new Class[0]); + ANNOTATIONS = annotations; } + + @JsonInclude(JsonInclude.Include.NON_NULL) + private static class JsonIncludeNonNull { + } + + @Override + public PropertyName findNameForSerialization(MapperConfig config, Annotated a) { + return Optional.ofNullable(findMapping(a)).orElseGet(() -> super.findNameForSerialization(config, a)); + } + + @Override + public PropertyName findNameForDeserialization(MapperConfig config, Annotated a) { + return Optional.ofNullable(findMapping(a)).orElseGet(() -> super.findNameForDeserialization(config, a)); + } + + private PropertyName findMapping(Annotated a) { + for (Map.Entry, String> e : MAPPINGS.entrySet()) { + if (_hasAnnotation(a, e.getKey())) { + return PropertyName.construct(e.getValue()); + } + } + return null; + } + + @Override + public JsonInclude.Value findPropertyInclusion(MapperConfig config, Annotated a) { + if (_hasOneOf(a, ANNOTATIONS)) { + return new JsonInclude.Value(JSON_INCLUDE_NON_NULL); + } else { + return super.findPropertyInclusion(config, a); + } + } +} diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeProvider.java b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeProvider.java new file mode 100644 index 000000000..c21048256 --- /dev/null +++ b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeProvider.java @@ -0,0 +1,18 @@ +package com.arangodb.internal.serde; + +import com.arangodb.serde.ArangoSerde; +import com.arangodb.serde.ArangoSerdeProvider; + +public class InternalUserSerdeProvider implements ArangoSerdeProvider { + + /** + * Creates a new InternalSerde with default settings. + * + * @return the created InternalSerde + */ + @Override + public ArangoSerde create() { + return new InternalUserSerde(); + } + +} diff --git a/core/src/main/java/com/arangodb/serde/ArangoSerdeProvider.java b/core/src/main/java/com/arangodb/serde/ArangoSerdeProvider.java index 744132588..e9d279687 100644 --- a/core/src/main/java/com/arangodb/serde/ArangoSerdeProvider.java +++ b/core/src/main/java/com/arangodb/serde/ArangoSerdeProvider.java @@ -1,7 +1,7 @@ package com.arangodb.serde; import com.arangodb.ArangoDBException; -import com.arangodb.internal.serde.InternalSerdeProvider; +import com.arangodb.internal.serde.InternalUserSerdeProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +33,7 @@ static ArangoSerdeProvider load() { if (serdeProvider == null) { LOG.warn("No ArangoSerdeProvider found, using InternalSerdeProvider. Please consider registering a custom " + "ArangoSerdeProvider to avoid depending on internal classes which are not part of the public API."); - serdeProvider = new InternalSerdeProvider(); + serdeProvider = new InternalUserSerdeProvider(); } return serdeProvider; } diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java index 95110fb3b..572188327 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java @@ -24,8 +24,9 @@ class ArangoSerdeAnnotationIntrospector extends JacksonAnnotationIntrospector { MAPPINGS.put(Rev.class, "_rev"); MAPPINGS.put(From.class, "_from"); MAPPINGS.put(To.class, "_to"); - ANNOTATIONS = MAPPINGS.keySet().toArray(new Class[0]); - } + @SuppressWarnings("unchecked") + Class[] annotations = MAPPINGS.keySet().toArray(new Class[0]); + ANNOTATIONS = annotations; } @JsonInclude(JsonInclude.Include.NON_NULL) private static class JsonIncludeNonNull { diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java index c6c6e28bc..0c2021883 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java @@ -2,7 +2,6 @@ import com.arangodb.RequestContext; import com.arangodb.serde.jackson.JacksonSerde; -import tools.jackson.databind.DeserializationFeature; import tools.jackson.databind.cfg.ContextAttributes; import tools.jackson.databind.json.JsonMapper; @@ -17,7 +16,6 @@ public final class JacksonSerdeImpl implements JacksonSerde { public JacksonSerdeImpl(final JsonMapper mapper) { this.mapper = mapper.rebuild() - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .annotationIntrospector(new ArangoSerdeAnnotationIntrospector()) .build(); } diff --git a/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java b/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java index 0fcb4d994..53c67eecd 100644 --- a/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java @@ -1,6 +1,6 @@ package com.arangodb.serde; -import com.arangodb.internal.serde.InternalSerdeProvider; +import com.arangodb.internal.serde.InternalUserSerdeProvider; import com.arangodb.serde.jackson.JacksonSerde; import com.arangodb.util.SlowTest; import org.junit.jupiter.api.Test; @@ -14,7 +14,7 @@ public class JacksonConfigurationTest { @SlowTest @Test void bigStringInternalSerde() { - ArangoSerde s = new InternalSerdeProvider().create(); + ArangoSerde s = new InternalUserSerdeProvider().create(); StringBuilder sb = new StringBuilder(); while (sb.length() < 40_000_000) { diff --git a/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java b/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java index fd442c0e1..b46bacd90 100644 --- a/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java @@ -2,7 +2,7 @@ import com.arangodb.entity.BaseDocument; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.internal.serde.InternalSerdeProvider; +import com.arangodb.internal.serde.InternalUserSerdeProvider; import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; @@ -20,7 +20,7 @@ class SerdeTest { @Test void rawJsonSerde() { - InternalSerde s = new InternalSerdeProvider().create(); + InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); RawJson raw = RawJson.of(SerdeUtils.INSTANCE.writeJson(node)); byte[] serialized = s.serialize(raw); @@ -30,7 +30,7 @@ void rawJsonSerde() { @Test void rawBytesSerde() { - InternalSerde s = new InternalSerdeProvider().create(); + InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); RawBytes raw = RawBytes.of(s.serialize(node)); byte[] serialized = s.serializeUserData(raw); @@ -40,7 +40,7 @@ void rawBytesSerde() { @Test void deserializeBaseDocumentWithNestedProperties() { - InternalSerde s = new InternalSerdeProvider().create(); + InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); RawJson json = RawJson.of("{\"foo\":\"aaa\",\"properties\":{\"foo\":\"bbb\"}}"); BaseDocument deserialized = s.deserialize(s.serialize(json), BaseDocument.class); assertThat(deserialized.getAttribute("foo")).isEqualTo("aaa"); @@ -52,7 +52,7 @@ void deserializeBaseDocumentWithNestedProperties() { @Test void serializeBaseDocumentWithNestedProperties() { - InternalSerde s = new InternalSerdeProvider().create(); + InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); BaseDocument doc = new BaseDocument(); doc.addAttribute("foo", "aaa"); doc.addAttribute("properties", Collections.singletonMap("foo", "bbb")); @@ -64,7 +64,7 @@ void serializeBaseDocumentWithNestedProperties() { @Test void deserializeNull() { - InternalSerde s = new InternalSerdeProvider().create(); + InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); Void deser = s.deserialize((byte[]) null, Void.class); assertThat(deser).isNull(); } @@ -78,7 +78,7 @@ void deserializeNullUserSerde() { @Test void deserializeEmpty() { - InternalSerde s = new InternalSerdeProvider().create(); + InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); Void deser = s.deserialize(new byte[0], Void.class); assertThat(deser).isNull(); } diff --git a/test-non-functional/src/test/java/serde/InternalSerdePerson.java b/test-non-functional/src/test/java/serde/InternalSerdePerson.java index 9e2f3238a..42a68d8af 100644 --- a/test-non-functional/src/test/java/serde/InternalSerdePerson.java +++ b/test-non-functional/src/test/java/serde/InternalSerdePerson.java @@ -2,9 +2,10 @@ import com.arangodb.serde.InternalKey; +import com.arangodb.serde.annotation.Key; public record InternalSerdePerson( - @InternalKey + @Key String key, String name, int age diff --git a/test-non-functional/src/test/java/serde/InternalSerdeTest.java b/test-non-functional/src/test/java/serde/InternalSerdeTest.java index 3250863ce..f372bec7b 100644 --- a/test-non-functional/src/test/java/serde/InternalSerdeTest.java +++ b/test-non-functional/src/test/java/serde/InternalSerdeTest.java @@ -2,7 +2,7 @@ import com.arangodb.ArangoDB; import com.arangodb.config.ArangoConfigProperties; -import com.arangodb.internal.serde.InternalSerdeProvider; +import com.arangodb.internal.serde.InternalUserSerdeProvider; import com.arangodb.util.RawJson; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -23,7 +23,7 @@ class InternalSerdeTest { static void init() { adb = new ArangoDB.Builder() .loadProperties(ArangoConfigProperties.fromFile()) - .serde(new InternalSerdeProvider().create()) + .serde(new InternalUserSerdeProvider().create()) .build(); } diff --git a/test-perf/src/main/java/com/arangodb/SerdeBench.java b/test-perf/src/main/java/com/arangodb/SerdeBench.java index 55a5e6ae6..16fcbf980 100644 --- a/test-perf/src/main/java/com/arangodb/SerdeBench.java +++ b/test-perf/src/main/java/com/arangodb/SerdeBench.java @@ -6,7 +6,6 @@ import com.arangodb.internal.ArangoExecutor; import com.arangodb.internal.InternalResponse; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.internal.serde.InternalSerdeProvider; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import org.openjdk.jmh.annotations.Benchmark; @@ -135,7 +134,7 @@ public static void main(String[] args) throws RunnerException, IOException { @Benchmark public void rawJsonDeser(Data data, Blackhole bh) { - InternalSerde serde = new InternalSerdeProvider().create(); + InternalSerde serde = InternalSerde.create(null); bh.consume( serde.deserialize(data.json, RawJson.class) ); @@ -143,7 +142,7 @@ public void rawJsonDeser(Data data, Blackhole bh) { @Benchmark public void rawJsonSer(Data data, Blackhole bh) { - InternalSerde serde = new InternalSerdeProvider().create(); + InternalSerde serde = InternalSerde.create(null); bh.consume( serde.serialize(data.rawJson) ); @@ -151,7 +150,7 @@ public void rawJsonSer(Data data, Blackhole bh) { @Benchmark public void extractBytesJson(Data data, Blackhole bh) { - InternalSerde serde = new InternalSerdeProvider().create(); + InternalSerde serde = InternalSerde.create(null); bh.consume( serde.extract(data.json, "/definitions/put_api_simple_remove_by_example_opts") ); From 094dc44fef76a6786b2ff3d550f18c0e0aa8ce82 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 14 Apr 2026 12:57:19 +0200 Subject: [PATCH 06/14] jackson serde refactoring --- .../java/com/arangodb/serde/InternalFrom.java | 22 ------------------- .../java/com/arangodb/serde/InternalId.java | 22 ------------------- .../java/com/arangodb/serde/InternalKey.java | 22 ------------------- .../java/com/arangodb/serde/InternalRev.java | 22 ------------------- .../java/com/arangodb/serde/InternalTo.java | 22 ------------------- .../serde/jackson/JacksonSerdeProvider.java | 11 ++++++++++ .../json/JacksonJsonSerdeProvider.java | 13 ----------- .../reflect-config-spi.json | 2 +- .../com.arangodb.serde.ArangoSerdeProvider | 2 +- .../serde/JacksonInterferenceTest.java | 5 ++--- .../test/java/serde/InternalSerdePerson.java | 2 -- 11 files changed, 15 insertions(+), 130 deletions(-) delete mode 100644 core/src/main/java/com/arangodb/serde/InternalFrom.java delete mode 100644 core/src/main/java/com/arangodb/serde/InternalId.java delete mode 100644 core/src/main/java/com/arangodb/serde/InternalKey.java delete mode 100644 core/src/main/java/com/arangodb/serde/InternalRev.java delete mode 100644 core/src/main/java/com/arangodb/serde/InternalTo.java create mode 100644 jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerdeProvider.java delete mode 100644 jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java diff --git a/core/src/main/java/com/arangodb/serde/InternalFrom.java b/core/src/main/java/com/arangodb/serde/InternalFrom.java deleted file mode 100644 index 1963a5fa9..000000000 --- a/core/src/main/java/com/arangodb/serde/InternalFrom.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.arangodb.serde; - -import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - * Annotation for `_from` field used by the InternalSerde. It works with shaded driver and relocated Jackson. - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotationsInside -@JsonProperty("_from") -@JsonInclude(JsonInclude.Include.NON_NULL) -public @interface InternalFrom { -} diff --git a/core/src/main/java/com/arangodb/serde/InternalId.java b/core/src/main/java/com/arangodb/serde/InternalId.java deleted file mode 100644 index 7ac590fbf..000000000 --- a/core/src/main/java/com/arangodb/serde/InternalId.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.arangodb.serde; - -import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - * Annotation for `_id` field used by the InternalSerde. It works with shaded driver and relocated Jackson. - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotationsInside -@JsonProperty("_id") -@JsonInclude(JsonInclude.Include.NON_NULL) -public @interface InternalId { -} diff --git a/core/src/main/java/com/arangodb/serde/InternalKey.java b/core/src/main/java/com/arangodb/serde/InternalKey.java deleted file mode 100644 index 932ecc942..000000000 --- a/core/src/main/java/com/arangodb/serde/InternalKey.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.arangodb.serde; - -import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - * Annotation for `_key` field used by the InternalSerde. It works with shaded driver and relocated Jackson. - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotationsInside -@JsonProperty("_key") -@JsonInclude(JsonInclude.Include.NON_NULL) -public @interface InternalKey { -} diff --git a/core/src/main/java/com/arangodb/serde/InternalRev.java b/core/src/main/java/com/arangodb/serde/InternalRev.java deleted file mode 100644 index c528d18e1..000000000 --- a/core/src/main/java/com/arangodb/serde/InternalRev.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.arangodb.serde; - -import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - * Annotation for `_rev` field used by the InternalSerde. It works with shaded driver and relocated Jackson. - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotationsInside -@JsonProperty("_rev") -@JsonInclude(JsonInclude.Include.NON_NULL) -public @interface InternalRev { -} diff --git a/core/src/main/java/com/arangodb/serde/InternalTo.java b/core/src/main/java/com/arangodb/serde/InternalTo.java deleted file mode 100644 index 7505a337b..000000000 --- a/core/src/main/java/com/arangodb/serde/InternalTo.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.arangodb.serde; - -import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Michele Rastelli - * Annotation for `_to` field used by the InternalSerde. It works with shaded driver and relocated Jackson. - */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) -@Retention(RetentionPolicy.RUNTIME) -@JacksonAnnotationsInside -@JsonProperty("_to") -@JsonInclude(JsonInclude.Include.NON_NULL) -public @interface InternalTo { -} diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerdeProvider.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerdeProvider.java new file mode 100644 index 000000000..e62e83468 --- /dev/null +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerdeProvider.java @@ -0,0 +1,11 @@ +package com.arangodb.serde.jackson; + +import com.arangodb.serde.ArangoSerde; +import com.arangodb.serde.ArangoSerdeProvider; + +public class JacksonSerdeProvider implements ArangoSerdeProvider { + @Override + public ArangoSerde create() { + return JacksonSerde.create(); + } +} diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java deleted file mode 100644 index 1df637914..000000000 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.arangodb.serde.jackson.json; - -import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.ArangoSerdeProvider; -import com.arangodb.serde.jackson.JacksonSerde; -import tools.jackson.databind.json.JsonMapper; - -public class JacksonJsonSerdeProvider implements ArangoSerdeProvider { - @Override - public ArangoSerde create() { - return JacksonSerde.create(new JsonMapper()); - } -} diff --git a/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/reflect-config-spi.json b/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/reflect-config-spi.json index 932e86cf3..cee7b71af 100644 --- a/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/reflect-config-spi.json +++ b/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/reflect-config-spi.json @@ -1,6 +1,6 @@ [ { - "name": "com.arangodb.serde.jackson.json.JacksonJsonSerdeProvider", + "name": "com.arangodb.serde.jackson.JacksonSerdeProvider", "methods": [ { "name": "", diff --git a/jackson-serde-json/src/main/resources/META-INF/services/com.arangodb.serde.ArangoSerdeProvider b/jackson-serde-json/src/main/resources/META-INF/services/com.arangodb.serde.ArangoSerdeProvider index 1d8eb8bc7..198620d5b 100644 --- a/jackson-serde-json/src/main/resources/META-INF/services/com.arangodb.serde.ArangoSerdeProvider +++ b/jackson-serde-json/src/main/resources/META-INF/services/com.arangodb.serde.ArangoSerdeProvider @@ -1 +1 @@ -com.arangodb.serde.jackson.json.JacksonJsonSerdeProvider +com.arangodb.serde.jackson.JacksonSerdeProvider diff --git a/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java b/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java index cb2bc8ad5..d706b07fe 100644 --- a/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java @@ -1,8 +1,7 @@ package com.arangodb.serde; import com.arangodb.serde.annotation.*; -import com.arangodb.serde.jackson.*; -import com.arangodb.serde.jackson.json.JacksonJsonSerdeProvider; +import com.arangodb.serde.jackson.JacksonSerdeProvider; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import tools.jackson.databind.JsonNode; @@ -22,7 +21,7 @@ class JacksonInterferenceTest { private final JsonMapper mapper = new JsonMapper(); - private final ArangoSerde serde = new JacksonJsonSerdeProvider().create(); + private final ArangoSerde serde = new JacksonSerdeProvider().create(); private FooField fooField; private FooProp fooProp; diff --git a/test-non-functional/src/test/java/serde/InternalSerdePerson.java b/test-non-functional/src/test/java/serde/InternalSerdePerson.java index 42a68d8af..08da3693b 100644 --- a/test-non-functional/src/test/java/serde/InternalSerdePerson.java +++ b/test-non-functional/src/test/java/serde/InternalSerdePerson.java @@ -1,7 +1,5 @@ package serde; - -import com.arangodb.serde.InternalKey; import com.arangodb.serde.annotation.Key; public record InternalSerdePerson( From 094d32330b323b4e9c37504a6c38ace61e45971e Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 14 Apr 2026 13:14:26 +0200 Subject: [PATCH 07/14] fix shaded tests --- test-non-functional/pom.xml | 20 ++++++++++++++------ test-parent/pom.xml | 14 ++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/test-non-functional/pom.xml b/test-non-functional/pom.xml index 82a9b883c..ec3a2438f 100644 --- a/test-non-functional/pom.xml +++ b/test-non-functional/pom.xml @@ -13,12 +13,6 @@ test-non-functional - - 21 - 21 - 21 - - com.arangodb @@ -86,6 +80,20 @@ **/JacksonRequestContextTest.** + + + tools.jackson.databind.JsonNode + com.arangodb.shaded.jackson.databind.JsonNode + + + tools.jackson.databind.ObjectNode + com.arangodb.shaded.jackson.databind.ObjectNode + + + tools.jackson.databind.node.JsonNodeFactory + com.arangodb.shaded.jackson.databind.node.JsonNodeFactory + + diff --git a/test-parent/pom.xml b/test-parent/pom.xml index 8c8c4ceea..744e22aef 100644 --- a/test-parent/pom.xml +++ b/test-parent/pom.xml @@ -15,10 +15,8 @@ false - 2.21.1 + 3.1.2 true - 21 - 21 src/test/java @@ -64,7 +62,7 @@ - com.fasterxml.jackson + tools.jackson jackson-bom ${adb.jackson.version} import @@ -216,8 +214,12 @@ replacer - com.fasterxml - com.arangodb.shaded.fasterxml + com.fasterxml.jackson.annotation + com.arangodb.shaded.fasterxml.jackson.annotation + + + tools.jackson + com.arangodb.shaded.jackson io.vertx From f69048195d3e942b8811320c854e9d49ee9c658a Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 14 Apr 2026 15:09:53 +0200 Subject: [PATCH 08/14] fix tutorial --- tutorial/gradle/build.gradle | 2 +- tutorial/maven/src/main/java/FirstProject.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tutorial/gradle/build.gradle b/tutorial/gradle/build.gradle index 40d314933..b5a92df31 100644 --- a/tutorial/gradle/build.gradle +++ b/tutorial/gradle/build.gradle @@ -20,5 +20,5 @@ ext { } application { - mainClassName = javaMainClass + mainClass = javaMainClass } diff --git a/tutorial/maven/src/main/java/FirstProject.java b/tutorial/maven/src/main/java/FirstProject.java index d64e76b09..d7ac97a98 100644 --- a/tutorial/maven/src/main/java/FirstProject.java +++ b/tutorial/maven/src/main/java/FirstProject.java @@ -1,6 +1,8 @@ import com.arangodb.*; import com.arangodb.entity.BaseDocument; import com.arangodb.util.RawJson; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; import java.util.Collections; import java.util.Map; @@ -59,8 +61,8 @@ public static void main(String[] args) { { System.out.println("Reading document as Jackson JsonNode..."); JsonNode readJsonNode = collection.getDocument(keyJackson, JsonNode.class); - System.out.println("Key: " + readJsonNode.get("_key").textValue()); - System.out.println("Attribute a: " + readJsonNode.get("a").textValue()); + System.out.println("Key: " + readJsonNode.get("_key").stringValue()); + System.out.println("Attribute a: " + readJsonNode.get("a").stringValue()); System.out.println("Attribute b: " + readJsonNode.get("b").intValue()); } From e7af6b6d4e59b29a04e5a1facc8275e8c398d880 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 14 Apr 2026 15:34:35 +0200 Subject: [PATCH 09/14] SerdeUtils refactoring --- .../internal/serde/InternalDeserializers.java | 2 +- .../arangodb/internal/serde/InternalSerdeImpl.java | 2 +- .../arangodb/internal/serde/InternalSerializers.java | 2 +- .../java/com/arangodb/internal/serde/SerdeUtils.java | 11 ++++++----- .../java/com/arangodb/ArangoCollectionAsyncTest.java | 8 ++++---- .../test/java/com/arangodb/ArangoCollectionTest.java | 8 ++++---- .../src/test/java/com/arangodb/ArangoDBAsyncTest.java | 2 +- .../src/test/java/com/arangodb/ArangoDBTest.java | 2 +- .../src/test/java/com/arangodb/serde/SerdeTest.java | 2 +- 9 files changed, 20 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java b/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java index 3a47805f6..df7eb403b 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java @@ -122,7 +122,7 @@ public FieldLink[] deserialize(JsonParser p, DeserializationContext ctxt) { public static class CollectionSchemaRuleDeserializer extends ValueDeserializer { @Override public String deserialize(JsonParser p, DeserializationContext ctxt) { - return SerdeUtils.INSTANCE.writeJson(p.readValueAsTree()); + return SerdeUtils.writeJson(p.readValueAsTree()); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java index 7516636ba..b5350729c 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -92,7 +92,7 @@ public String toJsonString(final byte[] content) { return ""; } try { - return SerdeUtils.INSTANCE.writeJson(mapper.readTree(content)); + return SerdeUtils.writeJson(mapper.readTree(content)); } catch (Exception e) { return "[Unparsable data]"; } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerializers.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerializers.java index 81e30ffa9..d6d3c8d09 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerializers.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerializers.java @@ -59,7 +59,7 @@ private InternalSerializers() { public static class CollectionSchemaRuleSerializer extends ValueSerializer { @Override public void serialize(String value, JsonGenerator gen, SerializationContext ctxt) { - gen.writeTree(SerdeUtils.INSTANCE.parseJson(value)); + gen.writeTree(SerdeUtils.parseJson(value)); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java index 128b496cd..549d2606d 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java @@ -19,9 +19,10 @@ import java.util.Arrays; import java.util.List; -// TODO: make static methods instance methods -public enum SerdeUtils { - INSTANCE; +public final class SerdeUtils { + + private SerdeUtils() { + } private static final Logger LOGGER = LoggerFactory.getLogger(SerdeUtils.class); @@ -65,7 +66,7 @@ static void checkSupportedJacksonVersion() { * @param json JSON string to parse * @return root of the parsed tree */ - public JsonNode parseJson(final String json) { + public static JsonNode parseJson(final String json) { return JsonMapper.shared().readTree(json); } @@ -73,7 +74,7 @@ public JsonNode parseJson(final String json) { * @param data JsonNode * @return JSON string */ - public String writeJson(final JsonNode data) { + public static String writeJson(final JsonNode data) { return JsonMapper.shared().writeValueAsString(data); } diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 76b170c35..5f07c2ed3 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -2337,7 +2337,7 @@ void insertDocumentsRawDataReturnNew(ArangoCollectionAsync collection) throws Ex .isNotNull() .isInstanceOf(RawJson.class); - JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) d).get()); assertThat(jn.has("aaa")).isTrue(); assertThat(jn.get("aaa").intValue()).isEqualTo(33); } @@ -2857,7 +2857,7 @@ void deleteDocumentsRawDataByKeyReturnOld(ArangoCollectionAsync collection) thro for (final DocumentDeleteEntity i : deleteResult.getDocuments()) { assertThat(i.getKey()).isIn("1", "2"); assertThat(i.getOld()).isNotNull().isInstanceOf(RawJson.class); - JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) i.getOld()).get()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) i.getOld()).get()); assertThat(jn.get("_key").asString()).isEqualTo(i.getKey()); } assertThat(deleteResult.getErrors()).isEmpty(); @@ -3103,7 +3103,7 @@ void updateDocumentsRawDataReturnNew(ArangoCollectionAsync collection) throws Ex .isNotNull() .isInstanceOf(RawJson.class); - JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) d).get()); assertThat(jn.has("foo")).isTrue(); assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } @@ -3222,7 +3222,7 @@ void replaceDocumentsRawDataReturnNew(ArangoCollectionAsync collection) throws E .isNotNull() .isInstanceOf(RawJson.class); - JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) d).get()); assertThat(jn.has("foo")).isTrue(); assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java index 8a7ac6fcb..600c0634c 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -2414,7 +2414,7 @@ void insertDocumentsRawDataReturnNew(ArangoCollection collection) { .isNotNull() .isInstanceOf(RawJson.class); - JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) d).get()); assertThat(jn.has("aaa")).isTrue(); assertThat(jn.get("aaa").intValue()).isEqualTo(33); } @@ -2935,7 +2935,7 @@ void deleteDocumentsRawDataByKeyReturnOld(ArangoCollection collection) { for (final DocumentDeleteEntity i : deleteResult.getDocuments()) { assertThat(i.getKey()).isIn("1", "2"); assertThat(i.getOld()).isNotNull().isInstanceOf(RawJson.class); - JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) i.getOld()).get()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) i.getOld()).get()); assertThat(jn.get("_key").asString()).isEqualTo(i.getKey()); } assertThat(deleteResult.getErrors()).isEmpty(); @@ -3181,7 +3181,7 @@ void updateDocumentsRawDataReturnNew(ArangoCollection collection) { .isNotNull() .isInstanceOf(RawJson.class); - JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) d).get()); assertThat(jn.has("foo")).isTrue(); assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } @@ -3300,7 +3300,7 @@ void replaceDocumentsRawDataReturnNew(ArangoCollection collection) { .isNotNull() .isInstanceOf(RawJson.class); - JsonNode jn = SerdeUtils.INSTANCE.parseJson(((RawJson) d).get()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) d).get()); assertThat(jn.has("foo")).isTrue(); assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } diff --git a/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java index cceba10da..320831083 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java @@ -424,7 +424,7 @@ void executeGetVersion(ArangoDBAsync arangoDB) throws ExecutionException, Interr .queryParam("details", "true") .build(); final Response response = arangoDB.execute(request, RawJson.class).get(); - JsonNode body = SerdeUtils.INSTANCE.parseJson(response.getBody().get()); + JsonNode body = SerdeUtils.parseJson(response.getBody().get()); assertThat(body.get("version").isString()).isTrue(); assertThat(body.get("details").isObject()).isTrue(); assertThat(response.getResponseCode()).isEqualTo(200); diff --git a/test-functional/src/test/java/com/arangodb/ArangoDBTest.java b/test-functional/src/test/java/com/arangodb/ArangoDBTest.java index bc0c12850..65d3eab86 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDBTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDBTest.java @@ -418,7 +418,7 @@ void executeGetVersion(ArangoDB arangoDB) { .queryParam("details", "true") .build(); final Response response = arangoDB.execute(request, RawJson.class); - JsonNode body = SerdeUtils.INSTANCE.parseJson(response.getBody().get()); + JsonNode body = SerdeUtils.parseJson(response.getBody().get()); assertThat(body.get("version").isString()).isTrue(); assertThat(body.get("details").isObject()).isTrue(); assertThat(response.getResponseCode()).isEqualTo(200); diff --git a/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java b/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java index b46bacd90..a878d4ee5 100644 --- a/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java @@ -22,7 +22,7 @@ class SerdeTest { void rawJsonSerde() { InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); - RawJson raw = RawJson.of(SerdeUtils.INSTANCE.writeJson(node)); + RawJson raw = RawJson.of(SerdeUtils.writeJson(node)); byte[] serialized = s.serialize(raw); RawJson deserialized = s.deserialize(serialized, RawJson.class); assertThat(deserialized).isEqualTo(raw); From 7dd655c95237a7b14c585b51e61a19390dd9f64e Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 14 Apr 2026 15:49:46 +0200 Subject: [PATCH 10/14] ArangoAnnotationIntrospector refactoring --- .../arangodb/internal/serde/RawUserDataValue.java | 2 +- ...pector.java => ArangoAnnotationIntrospector.java} | 12 ++++-------- .../com/arangodb/serde/jackson/JacksonSerde.java | 4 +++- .../serde/jackson/internal/JacksonSerdeImpl.java | 4 +--- 4 files changed, 9 insertions(+), 13 deletions(-) rename jackson-serde-json/src/main/java/com/arangodb/serde/jackson/{internal/ArangoSerdeAnnotationIntrospector.java => ArangoAnnotationIntrospector.java} (81%) diff --git a/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java b/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java index fdd3d8da5..a617ebad2 100644 --- a/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java +++ b/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java @@ -7,7 +7,7 @@ import java.io.OutputStream; import java.nio.ByteBuffer; -// TODO: since VPACK has been dropped, we can simplify this +// see https://github.com/FasterXML/jackson-core/issues/914 class RawUserDataValue implements SerializableString { private final byte[] data; diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/ArangoAnnotationIntrospector.java similarity index 81% rename from jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java rename to jackson-serde-json/src/main/java/com/arangodb/serde/jackson/ArangoAnnotationIntrospector.java index 572188327..f638af48f 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/ArangoSerdeAnnotationIntrospector.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/ArangoAnnotationIntrospector.java @@ -1,4 +1,4 @@ -package com.arangodb.serde.jackson.internal; +package com.arangodb.serde.jackson; import com.arangodb.serde.annotation.*; import com.fasterxml.jackson.annotation.JsonInclude; @@ -12,8 +12,7 @@ import java.util.Map; import java.util.Optional; -class ArangoSerdeAnnotationIntrospector extends JacksonAnnotationIntrospector { - private static final JsonInclude JSON_INCLUDE_NON_NULL = JsonIncludeNonNull.class.getAnnotation(JsonInclude.class); +public final class ArangoAnnotationIntrospector extends JacksonAnnotationIntrospector { private static final Map, String> MAPPINGS; private static final Class[] ANNOTATIONS; @@ -26,10 +25,7 @@ class ArangoSerdeAnnotationIntrospector extends JacksonAnnotationIntrospector { MAPPINGS.put(To.class, "_to"); @SuppressWarnings("unchecked") Class[] annotations = MAPPINGS.keySet().toArray(new Class[0]); - ANNOTATIONS = annotations; } - - @JsonInclude(JsonInclude.Include.NON_NULL) - private static class JsonIncludeNonNull { + ANNOTATIONS = annotations; } @Override @@ -54,7 +50,7 @@ private PropertyName findMapping(Annotated a) { @Override public JsonInclude.Value findPropertyInclusion(MapperConfig config, Annotated a) { if (_hasOneOf(a, ANNOTATIONS)) { - return new JsonInclude.Value(JSON_INCLUDE_NON_NULL); + return JsonInclude.Value.ALL_NON_NULL; } else { return super.findPropertyInclusion(config, a); } diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerde.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerde.java index 485f06d9c..b1d97bfec 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerde.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/JacksonSerde.java @@ -19,7 +19,9 @@ public interface JacksonSerde extends ArangoSerde { * @return the created JacksonSerde */ static JacksonSerde create() { - return create(new JsonMapper()); + return create(JsonMapper.builder() + .annotationIntrospector(new ArangoAnnotationIntrospector()) + .build()); } /** diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java index 0c2021883..3bf17bcef 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java @@ -15,9 +15,7 @@ public final class JacksonSerdeImpl implements JacksonSerde { private final JsonMapper mapper; public JacksonSerdeImpl(final JsonMapper mapper) { - this.mapper = mapper.rebuild() - .annotationIntrospector(new ArangoSerdeAnnotationIntrospector()) - .build(); + this.mapper = mapper; } @Override From b482333b71c971c3e1a88a7cab2c99ddd3088b80 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 16 Apr 2026 17:22:29 +0200 Subject: [PATCH 11/14] pass RequestContext as method parameter instead of ThreadLocal --- .../com/arangodb/internal/ArangoExecutor.java | 7 +-- .../internal/ArangoExecutorAsync.java | 5 +- .../arangodb/internal/ArangoExecutorSync.java | 6 +-- .../internal/InternalArangoCollection.java | 36 ++++++------- .../arangodb/internal/InternalArangoDB.java | 22 ++++---- .../internal/InternalArangoDatabase.java | 46 ++++++++-------- .../InternalArangoEdgeCollection.java | 8 +-- .../internal/InternalArangoGraph.java | 12 ++--- .../InternalArangoVertexCollection.java | 8 +-- .../internal/RequestContextHolder.java | 52 ------------------- .../internal/net/ExtendedHostResolver.java | 4 +- .../internal/serde/InternalSerde.java | 33 +++++++----- .../internal/serde/InternalSerdeImpl.java | 29 ++++++----- .../internal/serde/InternalUserSerde.java | 2 +- .../MultiDocumentEntityDeserializer.java | 10 ++-- .../internal/serde/UserDataDeserializer.java | 7 ++- .../arangodb/internal/util/ResponseUtils.java | 3 +- .../java/com/arangodb/serde/ArangoSerde.java | 1 + .../jackson/internal/JacksonSerdeImpl.java | 2 +- .../arangodb/ArangoCollectionAsyncTest.java | 2 +- .../com/arangodb/ArangoCollectionTest.java | 2 +- .../com/arangodb/ArangoDatabaseAsyncTest.java | 3 +- .../java/com/arangodb/ArangoDatabaseTest.java | 3 +- .../java/com/arangodb/RequestContextTest.java | 31 ++++++++++- .../annotations/ArangoAnnotationsTest.java | 5 +- .../arangodb/serde/CustomSerdeAsyncTest.java | 7 +-- .../com/arangodb/serde/CustomSerdeTest.java | 7 +-- .../serde/JacksonInterferenceTest.java | 3 +- .../java/com/arangodb/serde/SerdeTest.java | 17 +++--- .../document/GetDocumentExampleTest.java | 4 +- .../main/java/com/arangodb/SerdeBench.java | 5 +- 31 files changed, 190 insertions(+), 192 deletions(-) delete mode 100644 core/src/main/java/com/arangodb/internal/RequestContextHolder.java diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutor.java b/core/src/main/java/com/arangodb/internal/ArangoExecutor.java index 3f491f701..854dafa95 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutor.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutor.java @@ -22,6 +22,7 @@ import com.arangodb.ArangoDBException; import com.arangodb.QueueTimeMetrics; +import com.arangodb.RequestContext; import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.net.CommunicationProtocol; import com.arangodb.internal.serde.InternalSerde; @@ -58,8 +59,8 @@ public void setJwt(String jwt) { protocol.setJwt(jwt); } - protected T createResult(final Type type, final InternalResponse response) { - return serde.deserialize(response.getBody(), type); + protected T createResult(final Type type, final InternalResponse response, final RequestContext ctx) { + return serde.deserialize(response.getBody(), type, ctx); } protected final void interceptResponse(InternalResponse response) { @@ -79,6 +80,6 @@ public QueueTimeMetrics getQueueTimeMetrics() { } public interface ResponseDeserializer { - T deserialize(InternalResponse response); + T deserialize(InternalResponse response, RequestContext ctx); } } diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java index cb1f1c2f3..6db961a0c 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java @@ -49,7 +49,7 @@ public CompletableFuture execute(final Supplier requestS } public CompletableFuture execute(final Supplier requestSupplier, final Type type, final HostHandle hostHandle) { - return execute(requestSupplier, (response) -> createResult(type, response), hostHandle); + return execute(requestSupplier, (response, ctx) -> createResult(type, response, ctx), hostHandle); } public CompletableFuture execute(final Supplier requestSupplier, final ResponseDeserializer responseDeserializer) { @@ -72,8 +72,7 @@ public CompletableFuture execute( throw ArangoDBException.of(e); } else { interceptResponse(r.response); - return RequestContextHolder.INSTANCE.runWithCtx(r.context, () -> - responseDeserializer.deserialize(r.response)); + return responseDeserializer.deserialize(r.response, r.context); } }); diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java index dfd9f986c..6140f2c84 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java @@ -40,7 +40,7 @@ public T execute(final InternalRequest request, final Type type) { } public T execute(final InternalRequest request, final Type type, final HostHandle hostHandle) { - return execute(request, (response) -> createResult(type, response), hostHandle); + return execute(request, (response, ctx) -> createResult(type, response, ctx), hostHandle); } public T execute(final InternalRequest request, final ResponseDeserializer responseDeserializer) { @@ -54,8 +54,8 @@ public T execute( final InternalResponse response = protocol.execute(interceptRequest(request), hostHandle); interceptResponse(response); - return RequestContextHolder.INSTANCE.runWithCtx(new RequestContextImpl(request), () -> - responseDeserializer.deserialize(response)); + RequestContextImpl ctx = new RequestContextImpl(request); + return responseDeserializer.deserialize(response, ctx); } } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java index a4d5ea622..8a937053f 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java @@ -109,10 +109,10 @@ private InternalRequest createInsertDocumentRequest(final DocumentCreateOptions } protected ResponseDeserializer>> insertDocumentsResponseDeserializer(Class userDataClass) { - return (response) -> { + return (response, ctx) -> { Type type = constructParametricType(MultiDocumentEntity.class, constructParametricType(DocumentCreateEntity.class, userDataClass)); - return getSerde().deserialize(response.getBody(), type); + return getSerde().deserialize(response.getBody(), type, ctx); }; } @@ -148,7 +148,7 @@ protected InternalRequest getDocumentRequest(final String key, final DocumentRea } protected ResponseDeserializer getDocumentResponseDeserializer(final Class type) { - return (response) -> getSerde().deserializeUserData(response.getBody(), type); + return (response, ctx) -> getSerde().deserializeUserData(response.getBody(), type, ctx); } protected InternalRequest getDocumentsRequest(final Iterable keys, final DocumentReadOptions options) { @@ -165,9 +165,9 @@ protected InternalRequest getDocumentsRequest(final Iterable keys, final } protected ResponseDeserializer> getDocumentsResponseDeserializer(final Class type) { - return (response) -> { + return (response, ctx) -> { MultiDocumentEntity multiDocument = getSerde().deserialize(response.getBody(), - constructParametricType(MultiDocumentEntity.class, type)); + constructParametricType(MultiDocumentEntity.class, type), ctx); boolean potentialDirtyRead = Boolean.parseBoolean(response.getMeta("X-Arango-Potential-Dirty-Read")); multiDocument.setPotentialDirtyRead(potentialDirtyRead); return multiDocument; @@ -210,10 +210,10 @@ private InternalRequest createReplaceDocumentRequest(final DocumentReplaceOption protected ResponseDeserializer>> replaceDocumentsResponseDeserializer( final Class returnType) { - return (response) -> { + return (response, ctx) -> { Type type = constructParametricType(MultiDocumentEntity.class, constructParametricType(DocumentUpdateEntity.class, returnType)); - return getSerde().deserialize(response.getBody(), type); + return getSerde().deserialize(response.getBody(), type, ctx); }; } @@ -254,10 +254,10 @@ private InternalRequest createUpdateDocumentRequest(final DocumentUpdateOptions protected ResponseDeserializer>> updateDocumentsResponseDeserializer( final Class returnType) { - return (response) -> { + return (response, ctx) -> { Type type = constructParametricType(MultiDocumentEntity.class, constructParametricType(DocumentUpdateEntity.class, returnType)); - return getSerde().deserialize(response.getBody(), type); + return getSerde().deserialize(response.getBody(), type, ctx); }; } @@ -292,10 +292,10 @@ private InternalRequest createDeleteDocumentRequest(final DocumentDeleteOptions protected ResponseDeserializer>> deleteDocumentsResponseDeserializer( final Class userDataClass) { - return (response) -> { + return (response, ctx) -> { Type type = constructParametricType(MultiDocumentEntity.class, constructParametricType(DocumentDeleteEntity.class, userDataClass)); - return getSerde().deserialize(response.getBody(), type); + return getSerde().deserialize(response.getBody(), type, ctx); }; } @@ -318,7 +318,7 @@ protected InternalRequest deleteIndexRequest(final String id) { } protected ResponseDeserializer deleteIndexResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), "/id", String.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), "/id", String.class, ctx); } private String createIndexId(final String id) { @@ -389,11 +389,11 @@ protected InternalRequest getIndexesRequest() { } protected ResponseDeserializer> getIndexesResponseDeserializer() { - return (response) -> { + return (response, ctx) -> { Collection indexes = new ArrayList<>(); for (JsonNode idx : getSerde().parse(response.getBody(), "/indexes")) { if (!"inverted".equals(idx.get("type").stringValue())) { - indexes.add(getSerde().deserialize(idx, IndexEntity.class)); + indexes.add(getSerde().deserialize(idx, IndexEntity.class, ctx)); } } return indexes; @@ -401,11 +401,11 @@ protected ResponseDeserializer> getIndexesResponseDeseri } protected ResponseDeserializer> getInvertedIndexesResponseDeserializer() { - return (response) -> { + return (response, ctx) -> { Collection indexes = new ArrayList<>(); for (JsonNode idx : getSerde().parse(response.getBody(), "/indexes")) { if ("inverted".equals(idx.get("type").stringValue())) { - indexes.add(getSerde().deserialize(idx, InvertedIndexEntity.class)); + indexes.add(getSerde().deserialize(idx, InvertedIndexEntity.class, ctx)); } } return indexes; @@ -477,8 +477,8 @@ protected InternalRequest getPermissionsRequest(final String user) { } protected ResponseDeserializer getPermissionsResponseDeserialzer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - Permissions.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + Permissions.class, ctx); } } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoDB.java b/core/src/main/java/com/arangodb/internal/InternalArangoDB.java index 0b3019054..31b07268e 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoDB.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoDB.java @@ -67,11 +67,11 @@ protected InternalRequest getServerIdRequest() { } protected ResponseDeserializer getRoleResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), "/role", ServerRole.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), "/role", ServerRole.class, ctx); } protected ResponseDeserializer getServerIdResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), "/id", String.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), "/id", String.class, ctx); } protected InternalRequest createDatabaseRequest(final DBCreateOptions options) { @@ -82,8 +82,8 @@ protected InternalRequest createDatabaseRequest(final DBCreateOptions options) { } protected ResponseDeserializer createDatabaseResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - Boolean.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + Boolean.class, ctx); } protected InternalRequest getDatabasesRequest(final String dbName) { @@ -91,8 +91,8 @@ protected InternalRequest getDatabasesRequest(final String dbName) { } protected ResponseDeserializer> getDatabaseResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(String.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(String.class), ctx); } protected InternalRequest getAccessibleDatabasesForRequest(final String dbName, final String user) { @@ -100,7 +100,7 @@ protected InternalRequest getAccessibleDatabasesForRequest(final String dbName, } protected ResponseDeserializer> getAccessibleDatabasesForResponseDeserializer() { - return (response) -> getSerde().parse(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER).propertyNames(); + return (response, ctx) -> getSerde().parse(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER).propertyNames(); } protected InternalRequest createUserRequest( @@ -129,8 +129,8 @@ protected InternalRequest getUserRequest(final String dbName, final String user) } protected ResponseDeserializer> getUsersResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(UserEntity.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(UserEntity.class), ctx); } protected InternalRequest updateUserRequest(final String dbName, final String user, final UserUpdateOptions options) { @@ -166,10 +166,10 @@ protected InternalRequest executeRequest(final Request request) { } protected ResponseDeserializer> responseDeserializer(Class type) { - return (response) -> new Response<>( + return (response, ctx) -> new Response<>( response.getResponseCode(), response.getMeta(), - getSerde().deserializeUserData(response.getBody(), type) + getSerde().deserializeUserData(response.getBody(), type, ctx) ); } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java b/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java index 905fd3506..c51e672ec 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java @@ -68,8 +68,8 @@ public String name() { } protected ResponseDeserializer> getDatabaseResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(String.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(String.class), ctx); } protected InternalRequest getAccessibleDatabasesRequest() { @@ -101,8 +101,8 @@ protected InternalRequest getCollectionsRequest(final CollectionsReadOptions opt } protected ResponseDeserializer> getCollectionsResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(CollectionEntity.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(CollectionEntity.class), ctx); } protected InternalRequest dropRequest() { @@ -110,8 +110,8 @@ protected InternalRequest dropRequest() { } protected ResponseDeserializer createDropResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - Boolean.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + Boolean.class, ctx); } protected InternalRequest grantAccessRequest(final String user, final Permissions permissions) { @@ -134,8 +134,8 @@ protected InternalRequest getPermissionsRequest(final String user) { } protected ResponseDeserializer getPermissionsResponseDeserialzer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - Permissions.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + Permissions.class, ctx); } protected InternalRequest queryRequest(final String query, final Map bindVars, @@ -218,8 +218,8 @@ protected InternalRequest killQueryRequest(final String id) { } public ResponseDeserializer> cursorEntityDeserializer(final Class type) { - return (response) -> { - CursorEntity e = getSerde().deserialize(response.getBody(), constructParametricType(CursorEntity.class, type)); + return (response, ctx) -> { + CursorEntity e = getSerde().deserialize(response.getBody(), constructParametricType(CursorEntity.class, type), ctx); boolean potentialDirtyRead = Boolean.parseBoolean(response.getMeta("X-Arango-Potential-Dirty-Read")); e.setPotentialDirtyRead(potentialDirtyRead); return e; @@ -235,7 +235,7 @@ protected InternalRequest createGraphRequest(final String name, final Iterable createGraphResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), "/graph", GraphEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), "/graph", GraphEntity.class, ctx); } protected InternalRequest getGraphsRequest() { @@ -243,8 +243,8 @@ protected InternalRequest getGraphsRequest() { } protected ResponseDeserializer> getGraphsResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), "/graphs", - constructListType(GraphEntity.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), "/graphs", + constructListType(GraphEntity.class), ctx); } protected InternalRequest beginStreamTransactionRequest(final StreamTransactionOptions options) { @@ -269,8 +269,8 @@ protected InternalRequest getStreamTransactionRequest(String id) { } protected ResponseDeserializer> transactionsResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), "/transactions", - constructListType(TransactionEntity.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), "/transactions", + constructListType(TransactionEntity.class), ctx); } protected InternalRequest commitStreamTransactionRequest(String id) { @@ -278,8 +278,8 @@ protected InternalRequest commitStreamTransactionRequest(String id) { } protected ResponseDeserializer streamTransactionResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - StreamTransactionEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + StreamTransactionEntity.class, ctx); } protected InternalRequest getInfoRequest() { @@ -287,8 +287,8 @@ protected InternalRequest getInfoRequest() { } protected ResponseDeserializer getInfoResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - DatabaseEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + DatabaseEntity.class, ctx); } protected InternalRequest getViewsRequest() { @@ -296,8 +296,8 @@ protected InternalRequest getViewsRequest() { } protected ResponseDeserializer> getViewsResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(ViewEntity.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(ViewEntity.class), ctx); } protected InternalRequest createViewRequest(final String name, final ViewType type) { @@ -322,8 +322,8 @@ protected InternalRequest getAnalyzersRequest() { } protected ResponseDeserializer> getSearchAnalyzersResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(SearchAnalyzer.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(SearchAnalyzer.class), ctx); } protected InternalRequest createAnalyzerRequest(final SearchAnalyzer options) { diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoEdgeCollection.java b/core/src/main/java/com/arangodb/internal/InternalArangoEdgeCollection.java index 33bc6d832..af53cf05e 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoEdgeCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoEdgeCollection.java @@ -72,7 +72,7 @@ protected InternalRequest insertEdgeRequest(final T value, final EdgeCreateO } protected ResponseDeserializer insertEdgeResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeEntity.class, ctx); } protected InternalRequest getEdgeRequest(final String key, final GraphDocumentReadOptions options) { @@ -89,7 +89,7 @@ protected InternalRequest getEdgeRequest(final String key, final GraphDocumentRe } protected ResponseDeserializer getEdgeResponseDeserializer(final Class type) { - return (response) -> getSerde().deserializeUserData(getSerde().extract(response.getBody(), EDGE_JSON_POINTER), type); + return (response, ctx) -> getSerde().deserializeUserData(getSerde().extract(response.getBody(), EDGE_JSON_POINTER), type, ctx); } protected InternalRequest replaceEdgeRequest(final String key, final T value, final EdgeReplaceOptions options) { @@ -104,7 +104,7 @@ protected InternalRequest replaceEdgeRequest(final String key, final T value } protected ResponseDeserializer replaceEdgeResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeUpdateEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeUpdateEntity.class, ctx); } protected InternalRequest updateEdgeRequest(final String key, final T value, final EdgeUpdateOptions options) { @@ -121,7 +121,7 @@ protected InternalRequest updateEdgeRequest(final String key, final T value, } protected ResponseDeserializer updateEdgeResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeUpdateEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeUpdateEntity.class, ctx); } protected InternalRequest deleteEdgeRequest(final String key, final EdgeDeleteOptions options) { diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoGraph.java b/core/src/main/java/com/arangodb/internal/InternalArangoGraph.java index 45e4a7bd3..ff0bd6578 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoGraph.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoGraph.java @@ -79,8 +79,8 @@ protected InternalRequest getVertexCollectionsRequest() { } protected ResponseDeserializer> getVertexCollectionsResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), "/collections", - constructListType(String.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), "/collections", + constructListType(String.class), ctx); } protected InternalRequest addVertexCollectionRequest(final String name, final VertexCollectionCreateOptions options) { @@ -98,8 +98,8 @@ protected InternalRequest getEdgeDefinitionsRequest() { } protected ResponseDeserializer> getEdgeDefinitionsDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), "/collections", - constructListType(String.class)); + return (response, ctx) -> getSerde().deserialize(response.getBody(), "/collections", + constructListType(String.class), ctx); } protected InternalRequest addEdgeDefinitionRequest(final EdgeDefinition definition) { @@ -109,7 +109,7 @@ protected InternalRequest addEdgeDefinitionRequest(final EdgeDefinition definiti } protected ResponseDeserializer addEdgeDefinitionResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), GRAPH, GraphEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), GRAPH, GraphEntity.class, ctx); } protected InternalRequest replaceEdgeDefinitionRequest(final EdgeDefinition definition, final ReplaceEdgeDefinitionOptions options) { @@ -122,7 +122,7 @@ protected InternalRequest replaceEdgeDefinitionRequest(final EdgeDefinition defi } protected ResponseDeserializer replaceEdgeDefinitionResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), GRAPH, GraphEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), GRAPH, GraphEntity.class, ctx); } } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoVertexCollection.java b/core/src/main/java/com/arangodb/internal/InternalArangoVertexCollection.java index 5706ec034..322ff4187 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoVertexCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoVertexCollection.java @@ -71,7 +71,7 @@ protected InternalRequest insertVertexRequest(final T value, final VertexCre } protected ResponseDeserializer insertVertexResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexEntity.class, ctx); } protected InternalRequest getVertexRequest(final String key, final GraphDocumentReadOptions options) { @@ -88,7 +88,7 @@ protected InternalRequest getVertexRequest(final String key, final GraphDocument } protected ResponseDeserializer getVertexResponseDeserializer(final Class type) { - return (response) -> getSerde().deserializeUserData(getSerde().extract(response.getBody(), VERTEX_JSON_POINTER), type); + return (response, ctx) -> getSerde().deserializeUserData(getSerde().extract(response.getBody(), VERTEX_JSON_POINTER), type, ctx); } protected InternalRequest replaceVertexRequest(final String key, final T value, final VertexReplaceOptions options) { @@ -103,7 +103,7 @@ protected InternalRequest replaceVertexRequest(final String key, final T val } protected ResponseDeserializer replaceVertexResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexUpdateEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexUpdateEntity.class, ctx); } protected InternalRequest updateVertexRequest(final String key, final T value, final VertexUpdateOptions options) { @@ -120,7 +120,7 @@ protected InternalRequest updateVertexRequest(final String key, final T valu } protected ResponseDeserializer updateVertexResponseDeserializer() { - return (response) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexUpdateEntity.class); + return (response, ctx) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexUpdateEntity.class, ctx); } protected InternalRequest deleteVertexRequest(final String key, final VertexDeleteOptions options) { diff --git a/core/src/main/java/com/arangodb/internal/RequestContextHolder.java b/core/src/main/java/com/arangodb/internal/RequestContextHolder.java deleted file mode 100644 index bde22f031..000000000 --- a/core/src/main/java/com/arangodb/internal/RequestContextHolder.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.arangodb.internal; - -import com.arangodb.RequestContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Objects; -import java.util.function.Supplier; - -public enum RequestContextHolder { - INSTANCE; - - private final static Logger LOGGER = LoggerFactory.getLogger(RequestContextHolder.class); - - private final ThreadLocal runningWithinCtx = ThreadLocal.withInitial(() -> false); - private final ThreadLocal ctx = ThreadLocal.withInitial(() -> RequestContext.EMPTY); - - public T runWithCtx(RequestContext requestContext, Supplier fun) { - Objects.requireNonNull(requestContext); - RequestContext old = null; - try { - if (runningWithinCtx.get()) { - // re-entrant invocation, keep track of old ctx to restore later - old = ctx.get(); - } - LOGGER.debug("setting RequestContext: {}", requestContext); - ctx.set(requestContext); - runningWithinCtx.set(true); - return fun.get(); - } finally { - if (old == null) { - LOGGER.debug("removing RequestContext"); - ctx.remove(); - runningWithinCtx.remove(); - } else { - // re-entrant invocation, restore old ctx - LOGGER.debug("restore RequestContext: {}", old); - ctx.set(old); - } - } - } - - public RequestContext getCtx() { - if (!runningWithinCtx.get()) { - throw new IllegalStateException("Not within ctx!"); - } - - RequestContext requestContext = ctx.get(); - LOGGER.debug("returning RequestContext: {}", requestContext); - return requestContext; - } -} diff --git a/core/src/main/java/com/arangodb/internal/net/ExtendedHostResolver.java b/core/src/main/java/com/arangodb/internal/net/ExtendedHostResolver.java index 7ba5b58de..3dd8e9c40 100644 --- a/core/src/main/java/com/arangodb/internal/net/ExtendedHostResolver.java +++ b/core/src/main/java/com/arangodb/internal/net/ExtendedHostResolver.java @@ -133,11 +133,11 @@ private Collection resolveFromServer() { try { response = executor.execute( new InternalRequest(ArangoRequestParam.SYSTEM, RequestType.GET, "/_api/cluster/endpoints"), - (r) -> { + (r, ctx) -> { final List> tmp = arangoSerialization.deserialize(r.getBody(), "/endpoints", constructParametricType(List.class, - constructParametricType(Map.class, String.class, String.class))); + constructParametricType(Map.class, String.class, String.class)), ctx); Collection endpoints = new ArrayList<>(); for (final Map map : tmp) { endpoints.add(map.get("endpoint")); diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java index 3ac08fd04..4133fa198 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java @@ -1,5 +1,6 @@ package com.arangodb.internal.serde; +import com.arangodb.RequestContext; import com.arangodb.arch.UsedInApi; import com.arangodb.serde.ArangoSerde; import tools.jackson.databind.JavaType; @@ -44,19 +45,21 @@ static InternalSerde create(ArangoSerde userSerde) { * * @param content UTF-8 byte encoded JSON string * @param type target data type + * @param ctx request context * @return deserialized object */ - T deserialize(byte[] content, Type type); + T deserialize(byte[] content, Type type, RequestContext ctx); /** * Deserializes the parsed json node and binds it to the target data type. * * @param node parsed JSON node * @param clazz class of target data type + * @param ctx request context * @return deserialized object */ - default T deserialize(JsonNode node, Class clazz) { - return deserialize(node, (Type) clazz); + default T deserialize(JsonNode node, Class clazz, RequestContext ctx) { + return deserialize(node, (Type) clazz, ctx); } /** @@ -64,18 +67,20 @@ default T deserialize(JsonNode node, Class clazz) { * * @param node parsed JSON node * @param type target data type + * @param ctx request context * @return deserialized object */ - T deserialize(JsonNode node, Type type); + T deserialize(JsonNode node, Type type, RequestContext ctx); /** * Deserializes the content and binds it to the target data type. * - * @param content UTF-8 byte encoded JSON string + * @param content UTF-8 byte encoded JSON string * @param clazz class of target data type + * @param ctx request context * @return deserialized object */ - T deserialize(byte[] content, Class clazz); + T deserialize(byte[] content, Class clazz, RequestContext ctx); /** * Parses the content at json pointer. @@ -92,10 +97,11 @@ default T deserialize(JsonNode node, Class clazz) { * @param content UTF-8 byte encoded JSON string * @param jsonPointer location of data to be deserialized * @param clazz class of target data type + * @param ctx request context * @return deserialized object */ - default T deserialize(byte[] content, String jsonPointer, Class clazz) { - return deserialize(content, jsonPointer, (Type) clazz); + default T deserialize(byte[] content, String jsonPointer, Class clazz, RequestContext ctx) { + return deserialize(content, jsonPointer, (Type) clazz, ctx); } /** @@ -104,10 +110,11 @@ default T deserialize(byte[] content, String jsonPointer, Class clazz) { * @param content UTF-8 byte encoded JSON string * @param jsonPointer location of data to be deserialized * @param type target data type + * @param ctx request context * @return deserialized object */ - default T deserialize(byte[] content, String jsonPointer, Type type) { - return deserialize(extract(content, jsonPointer), type); + default T deserialize(byte[] content, String jsonPointer, Type type, RequestContext ctx) { + return deserialize(extract(content, jsonPointer), type, ctx); } /** @@ -139,18 +146,20 @@ default T deserialize(byte[] content, String jsonPointer, Type type) { * * @param content byte array to deserialize * @param clazz class of target data type + * @param ctx request context * @return deserialized object */ - T deserializeUserData(byte[] content, Class clazz); + T deserializeUserData(byte[] content, Class clazz, RequestContext ctx); /** * Deserializes the content and binds it to the target data type, using the user serde. * * @param content byte array to deserialize * @param clazz class of target data type + * @param ctx request context * @return deserialized object */ - T deserializeUserData(byte[] content, JavaType clazz); + T deserializeUserData(byte[] content, JavaType clazz, RequestContext ctx); /** diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java index b5350729c..e1c382538 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -1,7 +1,7 @@ package com.arangodb.internal.serde; import com.arangodb.ArangoDBException; -import com.arangodb.internal.RequestContextHolder; +import com.arangodb.RequestContext; import com.arangodb.serde.ArangoSerde; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; @@ -14,6 +14,7 @@ import tools.jackson.databind.*; import tools.jackson.databind.exc.MismatchedInputException; import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.cfg.ContextAttributes; import tools.jackson.datatype.jsonp.JSONPModule; import java.io.ByteArrayOutputStream; @@ -82,8 +83,8 @@ public byte[] serialize(final Object value) { } @Override - public T deserialize(byte[] content, Class clazz) { - return deserialize(content, (Type) clazz); + public T deserialize(byte[] content, Class clazz, RequestContext ctx) { + return deserialize(content, (Type) clazz, ctx); } @Override @@ -170,21 +171,21 @@ public byte[] serializeCollectionUserData(Iterable value) { } @Override - public T deserializeUserData(byte[] content, Class clazz) { + public T deserializeUserData(byte[] content, Class clazz, RequestContext ctx) { if (SerdeUtils.isManagedClass(clazz)) { - return deserialize(content, clazz); + return deserialize(content, clazz, ctx); } else { - return userSerde.deserialize(content, clazz, RequestContextHolder.INSTANCE.getCtx()); + return userSerde.deserialize(content, clazz, ctx); } } @Override @SuppressWarnings("unchecked") - public T deserializeUserData(byte[] content, JavaType clazz) { + public T deserializeUserData(byte[] content, JavaType clazz, RequestContext ctx) { if (SerdeUtils.isManagedClass(clazz.getRawClass())) { return mapper.readerFor(clazz).readValue(content); } else { - return deserializeUserData(content, (Class) clazz.getRawClass()); + return deserializeUserData(content, (Class) clazz.getRawClass(), ctx); } } @@ -224,13 +225,15 @@ public ArangoSerde getUserSerde() { } @Override - public T deserialize(final JsonNode node, final Type type) { - return mapper.readerFor(mapper.constructType(type)).readValue(node); + public T deserialize(final JsonNode node, final Type type, RequestContext ctx) { + return mapper.readerFor(mapper.constructType(type)) + .with(ContextAttributes.getEmpty().withPerCallAttribute(InternalUserSerde.SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) + .readValue(node); } @Override @SuppressWarnings("unchecked") - public T deserialize(final byte[] content, final Type type) { + public T deserialize(final byte[] content, final Type type, RequestContext ctx) { if (content == null || content.length == 0) { return null; } @@ -239,7 +242,9 @@ public T deserialize(final byte[] content, final Type type) { } else if (RawJson.class.equals(type)) { return (T) RawJson.of(new String(content, StandardCharsets.UTF_8)); } else { - return mapper.readerFor(mapper.constructType(type)).readValue(content); + return mapper.readerFor(mapper.constructType(type)) + .with(ContextAttributes.getEmpty().withPerCallAttribute(InternalUserSerde.SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) + .readValue(content); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java index e0de65da4..dbaab89e1 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java @@ -41,7 +41,7 @@ public byte[] serialize(final Object value) { @Override public T deserialize(final byte[] content, final Class type) { - return deserialize(content, type, RequestContext.EMPTY); + throw new UnsupportedOperationException("FIXME"); } @Override diff --git a/core/src/main/java/com/arangodb/internal/serde/MultiDocumentEntityDeserializer.java b/core/src/main/java/com/arangodb/internal/serde/MultiDocumentEntityDeserializer.java index a27cb700b..23b77d81f 100644 --- a/core/src/main/java/com/arangodb/internal/serde/MultiDocumentEntityDeserializer.java +++ b/core/src/main/java/com/arangodb/internal/serde/MultiDocumentEntityDeserializer.java @@ -1,5 +1,5 @@ package com.arangodb.internal.serde; - +import com.arangodb.RequestContext; import com.arangodb.entity.ErrorEntity; import com.arangodb.entity.MultiDocumentEntity; import tools.jackson.core.JsonParser; @@ -41,17 +41,21 @@ public MultiDocumentEntity deserialize(JsonParser p, DeserializationContext c throw MismatchedInputException.from(p, "Expected START_ARRAY but got " + p.currentToken()); } p.nextToken(); + RequestContext ctx = (RequestContext) ctxt.getAttribute(InternalUserSerde.SERDE_CONTEXT_ATTRIBUTE_NAME); + if (ctx == null) { + ctx = RequestContext.EMPTY; + } while (p.currentToken() != JsonToken.END_ARRAY) { if (p.currentToken() != JsonToken.START_OBJECT) { throw MismatchedInputException.from(p, "Expected START_OBJECT but got " + p.currentToken()); } byte[] element = SerdeUtils.extractBytes(p); if (serde.isDocument(element)) { - Object d = serde.deserializeUserData(element, containedType); + Object d = serde.deserializeUserData(element, containedType, ctx); multiDocument.getDocuments().add(d); multiDocument.getDocumentsAndErrors().add(d); } else { - ErrorEntity e = serde.deserialize(element, ErrorEntity.class); + ErrorEntity e = serde.deserialize(element, ErrorEntity.class, ctx); multiDocument.getErrors().add(e); multiDocument.getDocumentsAndErrors().add(e); } diff --git a/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java b/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java index f84232712..a0f206986 100644 --- a/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java +++ b/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java @@ -1,5 +1,6 @@ package com.arangodb.internal.serde; +import com.arangodb.RequestContext; import tools.jackson.core.JsonParser; import tools.jackson.databind.BeanProperty; import tools.jackson.databind.DeserializationContext; @@ -31,7 +32,11 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) { if (SerdeUtils.isManagedClass(clazz)) { return p.readValueAs(clazz); } else { - return serde.deserializeUserData(SerdeUtils.extractBytes(p), clazz); + RequestContext ctx = (RequestContext) ctxt.getAttribute(InternalUserSerde.SERDE_CONTEXT_ATTRIBUTE_NAME); + if (ctx == null) { + ctx = RequestContext.EMPTY; + } + return serde.deserializeUserData(SerdeUtils.extractBytes(p), clazz, ctx); } } diff --git a/core/src/main/java/com/arangodb/internal/util/ResponseUtils.java b/core/src/main/java/com/arangodb/internal/util/ResponseUtils.java index 57b69c319..dbd686e38 100644 --- a/core/src/main/java/com/arangodb/internal/util/ResponseUtils.java +++ b/core/src/main/java/com/arangodb/internal/util/ResponseUtils.java @@ -21,6 +21,7 @@ package com.arangodb.internal.util; import com.arangodb.ArangoDBException; +import com.arangodb.RequestContext; import com.arangodb.entity.ErrorEntity; import com.arangodb.internal.ArangoErrors; import com.arangodb.internal.InternalResponse; @@ -69,7 +70,7 @@ public static ArangoDBException translateError(InternalSerde serde, InternalResp ErrorEntity errorEntity; try { - errorEntity = serde.deserialize(body, ErrorEntity.class); + errorEntity = serde.deserialize(body, ErrorEntity.class, RequestContext.EMPTY); } catch (Exception e) { ArangoDBException adbEx = new ArangoDBException("Response Code: " + responseCode + " [Unparsable data] Response: " + response, responseCode); diff --git a/core/src/main/java/com/arangodb/serde/ArangoSerde.java b/core/src/main/java/com/arangodb/serde/ArangoSerde.java index 5e6713b4c..4b3bfc54c 100644 --- a/core/src/main/java/com/arangodb/serde/ArangoSerde.java +++ b/core/src/main/java/com/arangodb/serde/ArangoSerde.java @@ -30,6 +30,7 @@ public interface ArangoSerde { * @param clazz class of target data type * @return deserialized object */ + // TODO: remove T deserialize(byte[] content, Class clazz); /** diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java index 3bf17bcef..189496562 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java @@ -25,7 +25,7 @@ public byte[] serialize(final Object value) { @Override public T deserialize(final byte[] content, final Class type) { - return deserialize(content, type, RequestContext.EMPTY); + throw new UnsupportedOperationException("FIXME"); } @Override diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 5f07c2ed3..c2b950ea1 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -523,7 +523,7 @@ void insertDocumentAsBytes(ArangoCollectionAsync collection) throws ExecutionExc assertThat(createEntity.getKey()).isEqualTo(key); assertThat(createEntity.getRev()).isNotNull(); assertThat(createEntity.getNew()).isNotNull().isInstanceOf(RawBytes.class); - @SuppressWarnings("unchecked") Map newDoc = collection.getSerde().getUserSerde().deserialize(createEntity.getNew().get(), Map.class); + @SuppressWarnings("unchecked") Map newDoc = collection.getSerde().getUserSerde().deserialize(createEntity.getNew().get(), Map.class, RequestContext.EMPTY); assertThat(newDoc).containsAllEntriesOf(doc); } diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java index 600c0634c..e1d257ccb 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -526,7 +526,7 @@ void insertDocumentAsBytes(ArangoCollection collection) { assertThat(createEntity.getKey()).isEqualTo(key); assertThat(createEntity.getRev()).isNotNull(); assertThat(createEntity.getNew()).isNotNull().isInstanceOf(RawBytes.class); - Map newDoc = collection.getSerde().getUserSerde().deserialize(createEntity.getNew().get(), Map.class); + Map newDoc = collection.getSerde().getUserSerde().deserialize(createEntity.getNew().get(), Map.class, RequestContext.EMPTY); assertThat(newDoc).containsAllEntriesOf(doc); } diff --git a/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java index c9b38f202..9d61501d7 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java @@ -20,6 +20,7 @@ package com.arangodb; +import com.arangodb.RequestContext; import com.arangodb.entity.*; import com.arangodb.entity.QueryCachePropertiesEntity.CacheMode; import com.arangodb.internal.serde.InternalSerde; @@ -683,7 +684,7 @@ void queryRawBytes(ArangoDatabaseAsync db) throws ExecutionException, Interrupte RawBytes doc = RawBytes.of(serde.serialize(Collections.singletonMap("value", 1))); RawBytes res = db.query("RETURN @doc", RawBytes.class, Collections.singletonMap("doc", doc)).get() .getResult().getFirst(); - JsonNode data = serde.deserialize(res.get(), JsonNode.class); + JsonNode data = serde.deserialize(res.get(), JsonNode.class, RequestContext.EMPTY); assertThat(data.isObject()).isTrue(); assertThat(data.get("value").isNumber()).isTrue(); assertThat(data.get("value").numberValue()).isEqualTo(1); diff --git a/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java b/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java index f891f67c0..27a4ce528 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java @@ -20,6 +20,7 @@ package com.arangodb; +import com.arangodb.RequestContext; import com.arangodb.entity.*; import com.arangodb.entity.QueryCachePropertiesEntity.CacheMode; import com.arangodb.internal.serde.InternalSerde; @@ -773,7 +774,7 @@ void queryRawBytes(ArangoDatabase db) { InternalSerde serde = db.getSerde(); RawBytes doc = RawBytes.of(serde.serialize(Collections.singletonMap("value", 1))); RawBytes res = db.query("RETURN @doc", RawBytes.class, Collections.singletonMap("doc", doc)).next(); - JsonNode data = serde.deserialize(res.get(), JsonNode.class); + JsonNode data = serde.deserialize(res.get(), JsonNode.class, RequestContext.EMPTY); assertThat(data.isObject()).isTrue(); assertThat(data.get("value").isNumber()).isTrue(); assertThat(data.get("value").numberValue()).isEqualTo(1); diff --git a/test-functional/src/test/java/com/arangodb/RequestContextTest.java b/test-functional/src/test/java/com/arangodb/RequestContextTest.java index b1224a9e9..885a4d426 100644 --- a/test-functional/src/test/java/com/arangodb/RequestContextTest.java +++ b/test-functional/src/test/java/com/arangodb/RequestContextTest.java @@ -24,6 +24,7 @@ import com.arangodb.entity.BaseDocument; import com.arangodb.entity.DocumentCreateEntity; import com.arangodb.entity.StreamTransactionEntity; +import com.arangodb.model.AqlQueryOptions; import com.arangodb.model.DocumentReadOptions; import com.arangodb.model.StreamTransactionOptions; import com.arangodb.serde.ArangoSerde; @@ -50,6 +51,7 @@ class RequestContextTest { private static ArangoDB arangoDB; private static ArangoDatabase db; + private static ArangoDatabaseAsync dbAsync; private static ArangoCollection collection; private static ArangoCollectionAsync collectionAsync; @@ -94,7 +96,8 @@ public T deserialize(byte[] content, Class clazz, RequestContext ctx) { } collection = db.collection(COLLECTION_NAME); - collectionAsync = arangoDB.async().db(TEST_DB).collection(COLLECTION_NAME); + dbAsync = arangoDB.async().db(TEST_DB); + collectionAsync = dbAsync.collection(COLLECTION_NAME); if (!collection.exists()) { collection.create(); } @@ -152,4 +155,30 @@ void asyncGetDocumentWithinTx() throws ExecutionException, InterruptedException db.abortStreamTransaction(tx.getId()); } + @Test + void queryWithinTx() { + StreamTransactionEntity tx = db.beginStreamTransaction(new StreamTransactionOptions()); + Person res = db.query(""" + RETURN {"name":"foo"} + """, Person.class, new AqlQueryOptions().streamTransactionId(tx.getId())).next(); + + assertThat(res.name).isEqualTo("foo"); + assertThat(res.txId).isEqualTo(tx.getId()); + + db.abortStreamTransaction(tx.getId()); + } + + @Test + void asyncQueryWithinTx() throws ExecutionException, InterruptedException { + StreamTransactionEntity tx = db.beginStreamTransaction(new StreamTransactionOptions()); + Person res = dbAsync.query(""" + RETURN {"name":"foo"} + """, Person.class, new AqlQueryOptions().streamTransactionId(tx.getId())).get().getResult().getFirst(); + + assertThat(res.name).isEqualTo("foo"); + assertThat(res.txId).isEqualTo(tx.getId()); + + db.abortStreamTransaction(tx.getId()); + } + } diff --git a/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java b/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java index 4b25d24e7..9dc59e850 100644 --- a/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java +++ b/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java @@ -20,6 +20,7 @@ package com.arangodb.mapping.annotations; +import com.arangodb.RequestContext; import com.arangodb.serde.ArangoSerde; import com.arangodb.serde.jackson.JacksonSerde; import org.junit.jupiter.api.Test; @@ -45,7 +46,7 @@ void documentFieldAnnotations() { e.setTo("To"); byte[] serialized = mapper.serialize(e); - @SuppressWarnings("unchecked") Map deserialized = mapper.deserialize(serialized, Map.class); + @SuppressWarnings("unchecked") Map deserialized = mapper.deserialize(serialized, Map.class, RequestContext.EMPTY); assertThat(deserialized) .containsEntry("_id", e.getId()) .containsEntry("_key", e.getKey()) @@ -54,7 +55,7 @@ void documentFieldAnnotations() { .containsEntry("_to", e.getTo()) .hasSize(5); - AnnotatedEntity deserializedEntity = mapper.deserialize(serialized, AnnotatedEntity.class); + AnnotatedEntity deserializedEntity = mapper.deserialize(serialized, AnnotatedEntity.class, RequestContext.EMPTY); assertThat(deserializedEntity).isEqualTo(e); } diff --git a/test-functional/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java b/test-functional/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java index c1abab038..cf02dd9fe 100644 --- a/test-functional/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java @@ -23,7 +23,6 @@ import com.arangodb.*; import com.arangodb.config.ConfigUtils; -import com.arangodb.internal.RequestContextHolder; import com.arangodb.internal.serde.InternalSerde; import com.arangodb.model.DocumentCreateOptions; import com.arangodb.serde.jackson.JacksonSerde; @@ -110,8 +109,7 @@ void manualCustomPersonDeserializer() { person.name = "Joe"; InternalSerde serialization = arangoDB.getSerde(); byte[] serialized = serialization.serializeUserData(person); - Person deserializedPerson = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> - serialization.deserializeUserData(serialized, Person.class)); + Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class, RequestContext.EMPTY); assertThat(deserializedPerson.name).isEqualTo(PERSON_DESERIALIZER_ADDED_PREFIX + PERSON_SERIALIZER_ADDED_PREFIX + person.name); } @@ -207,8 +205,7 @@ void getDocument() throws ExecutionException, InterruptedException { @Test void parseNullString() { - final String json = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> - arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class)); + final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class, RequestContext.EMPTY); assertThat(json).isNull(); } diff --git a/test-functional/src/test/java/com/arangodb/serde/CustomSerdeTest.java b/test-functional/src/test/java/com/arangodb/serde/CustomSerdeTest.java index e0396af9a..32e6e7a29 100644 --- a/test-functional/src/test/java/com/arangodb/serde/CustomSerdeTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/CustomSerdeTest.java @@ -23,7 +23,6 @@ import com.arangodb.*; import com.arangodb.config.ConfigUtils; -import com.arangodb.internal.RequestContextHolder; import com.arangodb.internal.serde.InternalSerde; import com.arangodb.model.DocumentCreateOptions; import com.arangodb.serde.jackson.JacksonSerde; @@ -106,8 +105,7 @@ void manualCustomPersonDeserializer() { person.name = "Joe"; InternalSerde serialization = arangoDB.getSerde(); byte[] serialized = serialization.serializeUserData(person); - Person deserializedPerson = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> - serialization.deserializeUserData(serialized, Person.class)); + Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class, RequestContext.EMPTY); assertThat(deserializedPerson.name).isEqualTo(PERSON_DESERIALIZER_ADDED_PREFIX + PERSON_SERIALIZER_ADDED_PREFIX + person.name); } @@ -204,8 +202,7 @@ void getDocument() { @Test void parseNullString() { - final String json = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> - arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class)); + final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class, RequestContext.EMPTY); assertThat(json).isNull(); } diff --git a/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java b/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java index d706b07fe..175c463eb 100644 --- a/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/JacksonInterferenceTest.java @@ -1,5 +1,6 @@ package com.arangodb.serde; +import com.arangodb.RequestContext; import com.arangodb.serde.annotation.*; import com.arangodb.serde.jackson.JacksonSerdeProvider; import org.junit.jupiter.api.BeforeEach; @@ -222,6 +223,6 @@ private T jacksonDeserialize(byte[] bytes, Class clazz) { } private T serdeDeserialize(byte[] bytes, Class clazz) { - return serde.deserialize(bytes, clazz); + return serde.deserialize(bytes, clazz, RequestContext.EMPTY); } } diff --git a/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java b/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java index a878d4ee5..2f1005103 100644 --- a/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/SerdeTest.java @@ -1,5 +1,6 @@ package com.arangodb.serde; +import com.arangodb.RequestContext; import com.arangodb.entity.BaseDocument; import com.arangodb.internal.serde.InternalSerde; import com.arangodb.internal.serde.InternalUserSerdeProvider; @@ -24,7 +25,7 @@ void rawJsonSerde() { ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); RawJson raw = RawJson.of(SerdeUtils.writeJson(node)); byte[] serialized = s.serialize(raw); - RawJson deserialized = s.deserialize(serialized, RawJson.class); + RawJson deserialized = s.deserialize(serialized, RawJson.class, RequestContext.EMPTY); assertThat(deserialized).isEqualTo(raw); } @@ -34,7 +35,7 @@ void rawBytesSerde() { ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); RawBytes raw = RawBytes.of(s.serialize(node)); byte[] serialized = s.serializeUserData(raw); - RawBytes deserialized = s.deserializeUserData(serialized, RawBytes.class); + RawBytes deserialized = s.deserializeUserData(serialized, RawBytes.class, RequestContext.EMPTY); assertThat(deserialized).isEqualTo(raw); } @@ -42,7 +43,7 @@ void rawBytesSerde() { void deserializeBaseDocumentWithNestedProperties() { InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); RawJson json = RawJson.of("{\"foo\":\"aaa\",\"properties\":{\"foo\":\"bbb\"}}"); - BaseDocument deserialized = s.deserialize(s.serialize(json), BaseDocument.class); + BaseDocument deserialized = s.deserialize(s.serialize(json), BaseDocument.class, RequestContext.EMPTY); assertThat(deserialized.getAttribute("foo")).isEqualTo("aaa"); assertThat(deserialized.getAttribute("properties")) .isInstanceOf(Map.class) @@ -57,7 +58,7 @@ void serializeBaseDocumentWithNestedProperties() { doc.addAttribute("foo", "aaa"); doc.addAttribute("properties", Collections.singletonMap("foo", "bbb")); byte[] ser = s.serialize(doc); - ObjectNode on = s.deserializeUserData(ser, ObjectNode.class); + ObjectNode on = s.deserializeUserData(ser, ObjectNode.class, RequestContext.EMPTY); assertThat(on.get("foo").stringValue()).isEqualTo("aaa"); assertThat(on.get("properties").get("foo").stringValue()).isEqualTo("bbb"); } @@ -65,28 +66,28 @@ void serializeBaseDocumentWithNestedProperties() { @Test void deserializeNull() { InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); - Void deser = s.deserialize((byte[]) null, Void.class); + Void deser = s.deserialize((byte[]) null, Void.class, RequestContext.EMPTY); assertThat(deser).isNull(); } @Test void deserializeNullUserSerde() { ArangoSerde s = ArangoSerdeProvider.load().create(); - Void deser = s.deserialize(null, Void.class); + Void deser = s.deserialize(null, Void.class, RequestContext.EMPTY); assertThat(deser).isNull(); } @Test void deserializeEmpty() { InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); - Void deser = s.deserialize(new byte[0], Void.class); + Void deser = s.deserialize(new byte[0], Void.class, RequestContext.EMPTY); assertThat(deser).isNull(); } @Test void deserializeEmptyUserSerde() { ArangoSerde s = ArangoSerdeProvider.load().create(); - Void deser = s.deserialize(new byte[0], Void.class); + Void deser = s.deserialize(new byte[0], Void.class, RequestContext.EMPTY); assertThat(deser).isNull(); } } diff --git a/test-non-functional/src/test/java/example/document/GetDocumentExampleTest.java b/test-non-functional/src/test/java/example/document/GetDocumentExampleTest.java index 4f69e65b2..72a40b087 100644 --- a/test-non-functional/src/test/java/example/document/GetDocumentExampleTest.java +++ b/test-non-functional/src/test/java/example/document/GetDocumentExampleTest.java @@ -22,7 +22,6 @@ import com.arangodb.RequestContext; import com.arangodb.entity.BaseDocument; -import com.arangodb.internal.RequestContextHolder; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import example.ExampleBase; @@ -95,8 +94,7 @@ void getAsBytes() { final RawBytes doc = collection.getDocument(key, RawBytes.class); assertThat(doc.get()).isNotNull(); @SuppressWarnings("unchecked") - Map mapDoc = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> - collection.getSerde().deserializeUserData(doc.get(), Map.class)); + Map mapDoc = collection.getSerde().deserializeUserData(doc.get(), Map.class, RequestContext.EMPTY); assertThat(mapDoc).containsEntry("foo", "bar"); } diff --git a/test-perf/src/main/java/com/arangodb/SerdeBench.java b/test-perf/src/main/java/com/arangodb/SerdeBench.java index 16fcbf980..29ec08c1a 100644 --- a/test-perf/src/main/java/com/arangodb/SerdeBench.java +++ b/test-perf/src/main/java/com/arangodb/SerdeBench.java @@ -135,8 +135,7 @@ public static void main(String[] args) throws RunnerException, IOException { @Benchmark public void rawJsonDeser(Data data, Blackhole bh) { InternalSerde serde = InternalSerde.create(null); - bh.consume( - serde.deserialize(data.json, RawJson.class) + bh.consume(serde.deserialize(data.json, RawJson.class, RequestContext.EMPTY) ); } @@ -159,7 +158,7 @@ public void extractBytesJson(Data data, Blackhole bh) { @Benchmark public void deserializeDocsJson(Data data, Blackhole bh) { bh.consume( - data.jsonCol.getDocumentsResponseDeserializer(RawBytes.class).deserialize(data.jsonResp) + data.jsonCol.getDocumentsResponseDeserializer(RawBytes.class).deserialize(data.jsonResp, RequestContext.EMPTY) ); } From 066c8ba497b9add6d160762cb87e941db97e40bb Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 16 Apr 2026 19:31:07 +0200 Subject: [PATCH 12/14] fix javadocs --- driver/pom.xml | 7 +++++++ pom.xml | 7 +++++-- .../java/com/arangodb/serde/JacksonConfigurationTest.java | 8 +++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/driver/pom.xml b/driver/pom.xml index e7e83a076..696a20fb9 100644 --- a/driver/pom.xml +++ b/driver/pom.xml @@ -26,6 +26,13 @@ maven-javadoc-plugin true + + + jakarta.json.bind + jakarta.json.bind-api + ${jsonb.version} + + diff --git a/pom.xml b/pom.xml index 1f701ce75..3435b92ad 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ target/spotbugsXml.xml site/jacoco/jacoco.xml 25.0.0 + 3.0.0 @@ -158,7 +159,9 @@ com.arangodb.internal, com.arangodb.internal.*, com.arangodb.serde.jackson.internal, - javax.* + javax.*, + graal.*, + com.arangodb.arch.* none @@ -274,7 +277,7 @@ jakarta.json.bind jakarta.json.bind-api - 3.0.0 + ${jsonb.version} com.arangodb diff --git a/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java b/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java index 53c67eecd..f5e7f236e 100644 --- a/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java +++ b/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java @@ -1,8 +1,8 @@ package com.arangodb.serde; +import com.arangodb.RequestContext; import com.arangodb.internal.serde.InternalUserSerdeProvider; import com.arangodb.serde.jackson.JacksonSerde; -import com.arangodb.util.SlowTest; import org.junit.jupiter.api.Test; import java.util.UUID; @@ -11,7 +11,6 @@ public class JacksonConfigurationTest { - @SlowTest @Test void bigStringInternalSerde() { ArangoSerde s = new InternalUserSerdeProvider().create(); @@ -22,11 +21,10 @@ void bigStringInternalSerde() { } String in = sb.toString(); byte[] bytes = s.serialize(in); - String out = s.deserialize(bytes, String.class); + String out = s.deserialize(bytes, String.class, RequestContext.EMPTY); assertThat(out).isEqualTo(in); } - @SlowTest @Test void bigStringUserSerde() { ArangoSerde s = JacksonSerde.create(); @@ -37,7 +35,7 @@ void bigStringUserSerde() { } String in = sb.toString(); byte[] bytes = s.serialize(in); - String out = s.deserialize(bytes, String.class); + String out = s.deserialize(bytes, String.class, RequestContext.EMPTY); assertThat(out).isEqualTo(in); } From adabdd38c9ba0ee7f87e0fce47dcc61266c8d536 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 16 Apr 2026 21:49:14 +0200 Subject: [PATCH 13/14] simplified ArangoSerde --- .../internal/serde/InternalUserSerde.java | 5 ----- .../java/com/arangodb/serde/ArangoSerde.java | 19 ++----------------- .../jackson/internal/JacksonSerdeImpl.java | 5 ----- .../com/arangodb/serde/jsonb/JsonbSerde.java | 3 ++- .../java/com/arangodb/RequestContextTest.java | 5 ----- 5 files changed, 4 insertions(+), 33 deletions(-) diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java index dbaab89e1..7cabb0e33 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java @@ -39,11 +39,6 @@ public byte[] serialize(final Object value) { return mapper.writeValueAsBytes(value); } - @Override - public T deserialize(final byte[] content, final Class type) { - throw new UnsupportedOperationException("FIXME"); - } - @Override public T deserialize(byte[] content, Class type, RequestContext ctx) { if (content == null || content.length == 0) { diff --git a/core/src/main/java/com/arangodb/serde/ArangoSerde.java b/core/src/main/java/com/arangodb/serde/ArangoSerde.java index 4b3bfc54c..090cc5b12 100644 --- a/core/src/main/java/com/arangodb/serde/ArangoSerde.java +++ b/core/src/main/java/com/arangodb/serde/ArangoSerde.java @@ -2,8 +2,6 @@ import com.arangodb.RequestContext; -import java.util.Objects; - /** * Contract for serialization/deserialization of user data. * Implementations of this interface could be used for customizing serialization/deserialization of user related data @@ -26,23 +24,10 @@ public interface ArangoSerde { /** * Deserializes the content and binds it to the target data type. * - * @param content UTF-8 byte encoded JSON string - * @param clazz class of target data type - * @return deserialized object - */ - // TODO: remove - T deserialize(byte[] content, Class clazz); - - /** - * Deserializes the content and binds it to the target data type. - * - * @param content UTF-8 byte encoded JSON string + * @param content UTF-8 byte encoded JSON string * @param clazz class of target data type * @param ctx serde context, cannot be null * @return deserialized object */ - default T deserialize(byte[] content, Class clazz, RequestContext ctx) { - Objects.requireNonNull(ctx); - return deserialize(content, clazz); - } + T deserialize(byte[] content, Class clazz, RequestContext ctx); } diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java index 189496562..ec0dec9fd 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java @@ -23,11 +23,6 @@ public byte[] serialize(final Object value) { return mapper.writeValueAsBytes(value); } - @Override - public T deserialize(final byte[] content, final Class type) { - throw new UnsupportedOperationException("FIXME"); - } - @Override public T deserialize(byte[] content, Class type, RequestContext ctx) { if (content == null || content.length == 0) { diff --git a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/JsonbSerde.java b/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/JsonbSerde.java index b1d2baa36..20c631169 100644 --- a/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/JsonbSerde.java +++ b/jsonb-serde/src/main/java/com/arangodb/serde/jsonb/JsonbSerde.java @@ -1,5 +1,6 @@ package com.arangodb.serde.jsonb; +import com.arangodb.RequestContext; import com.arangodb.serde.ArangoSerde; import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; @@ -28,7 +29,7 @@ public byte[] serialize(Object value) { } @Override - public T deserialize(byte[] content, Class type) { + public T deserialize(byte[] content, Class type, RequestContext ctx) { return jsonb.fromJson(new String(content, StandardCharsets.UTF_8), type); } diff --git a/test-functional/src/test/java/com/arangodb/RequestContextTest.java b/test-functional/src/test/java/com/arangodb/RequestContextTest.java index 885a4d426..85a94c784 100644 --- a/test-functional/src/test/java/com/arangodb/RequestContextTest.java +++ b/test-functional/src/test/java/com/arangodb/RequestContextTest.java @@ -67,11 +67,6 @@ public byte[] serialize(Object value) { throw new UnsupportedOperationException(); } - @Override - public T deserialize(byte[] content, Class clazz) { - throw new UnsupportedOperationException(); - } - @Override public T deserialize(byte[] content, Class clazz, RequestContext ctx) { Objects.requireNonNull(ctx); From c5d1df8a19d1470c30f65712c4ea1dce7bd60832 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 16 Apr 2026 21:54:08 +0200 Subject: [PATCH 14/14] rm VST response deserializer --- .../internal/serde/InternalDeserializers.java | 18 ------------------ .../internal/serde/InternalModule.java | 2 -- 2 files changed, 20 deletions(-) diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java b/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java index df7eb403b..99b56f72a 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java @@ -7,7 +7,6 @@ import com.arangodb.entity.arangosearch.FieldLink; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; -import com.arangodb.internal.InternalResponse; import tools.jackson.core.JsonParser; import tools.jackson.core.TreeNode; import tools.jackson.databind.DeserializationContext; @@ -18,7 +17,6 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; import java.util.Map; public final class InternalDeserializers { @@ -56,22 +54,6 @@ public ReplicationFactor deserialize(final JsonParser p, final DeserializationCo } }; - @SuppressWarnings("unchecked") - static final ValueDeserializer RESPONSE = new ValueDeserializer<>() { - @Override - public InternalResponse deserialize(final JsonParser p, final DeserializationContext ctxt) { - final InternalResponse response = new InternalResponse(); - Iterator it = ((ArrayNode) p.readValueAsTree()).iterator(); - response.setVersion(it.next().intValue()); - response.setType(it.next().intValue()); - response.setResponseCode(it.next().intValue()); - if (it.hasNext()) { - response.putMetas(readTreeAsValue(p, ctxt, it.next(), Map.class)); - } - return response; - } - }; - static final ValueDeserializer INVERTED_INDEX_PRIMARY_SORT_FIELD = new ValueDeserializer<>() { @Override public InvertedIndexPrimarySort.Field deserialize(final JsonParser p, final DeserializationContext ctxt) { diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalModule.java b/core/src/main/java/com/arangodb/internal/serde/InternalModule.java index 5d9471a77..7f9c2e924 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalModule.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalModule.java @@ -7,7 +7,6 @@ import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import com.arangodb.internal.InternalRequest; -import com.arangodb.internal.InternalResponse; import tools.jackson.databind.JacksonModule; import tools.jackson.databind.module.SimpleModule; @@ -26,7 +25,6 @@ static JacksonModule get(InternalSerde serde) { module.addDeserializer(RawBytes.class, InternalDeserializers.RAW_BYTES_DESERIALIZER); module.addDeserializer(CollectionType.class, InternalDeserializers.COLLECTION_TYPE); module.addDeserializer(ReplicationFactor.class, InternalDeserializers.REPLICATION_FACTOR); - module.addDeserializer(InternalResponse.class, InternalDeserializers.RESPONSE); module.addDeserializer(InvertedIndexPrimarySort.Field.class, InternalDeserializers.INVERTED_INDEX_PRIMARY_SORT_FIELD); return module;