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/pom.xml b/core/pom.xml index 3eabaeb7f..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 @@ -49,6 +49,12 @@ jsr305 provided + + jakarta.json.bind + jakarta.json.bind-api + provided + true + 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/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/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/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 1ff995d86..8a937053f 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; @@ -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").textValue())) { - indexes.add(getSerde().deserialize(idx, IndexEntity.class)); + if (!"inverted".equals(idx.get("type").stringValue())) { + 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").textValue())) { - indexes.add(getSerde().deserialize(idx, InvertedIndexEntity.class)); + if ("inverted".equals(idx.get("type").stringValue())) { + 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 a07fe4c07..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,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, ctx) -> getSerde().parse(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER).propertyNames(); } protected InternalRequest createUserRequest( @@ -137,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) { @@ -174,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/config/ArangoConfig.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java index f4c08e0cc..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,10 +9,8 @@ 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; -import com.fasterxml.jackson.databind.Module; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; @@ -57,7 +55,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 +311,7 @@ public ArangoSerde getUserDataSerde() { public InternalSerde getInternalSerde() { if (internalSerde == null) { - internalSerde = new InternalSerdeProvider().create(getUserDataSerde(), protocolModule); + internalSerde = InternalSerde.create(getUserDataSerde()); } return internalSerde; } @@ -335,10 +332,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/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/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..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,89 +7,58 @@ import com.arangodb.entity.arangosearch.FieldLink; 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 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.io.IOException; -import java.io.StringWriter; 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 { - 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() { - @Override - public InternalResponse deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException { - 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 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 +68,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 +86,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,10 +101,10 @@ 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 { - return SerdeUtils.INSTANCE.writeJson(p.readValueAsTree()); + public String deserialize(JsonParser p, DeserializationContext ctxt) { + return SerdeUtils.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 deleted file mode 100644 index eed6cfb18..000000000 --- a/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -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 java.util.Iterator; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; - -class InternalMapperProvider { - private static final Logger LOG = LoggerFactory.getLogger(InternalMapperProvider.class); - - 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/core/src/main/java/com/arangodb/internal/serde/InternalModule.java b/core/src/main/java/com/arangodb/internal/serde/InternalModule.java index 9cfecd8bb..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,13 +7,12 @@ import com.arangodb.util.RawBytes; 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)); @@ -26,7 +25,6 @@ static Module 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; 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..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,14 +1,25 @@ package com.arangodb.internal.serde; +import com.arangodb.RequestContext; 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; @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,31 +43,44 @@ 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 + * @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 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); } /** * 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 + * @param ctx request context + * @return deserialized object + */ + 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 clazz class of target data type + * @param ctx request context * @return deserialized object */ - T deserialize(JsonNode node, Type type); + T deserialize(byte[] content, Class clazz, RequestContext ctx); /** * Parses the content at json pointer. @@ -73,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); } /** @@ -85,12 +110,21 @@ 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); } + /** + * 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. * @@ -112,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 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 8bd24ba31..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,31 +1,26 @@ 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; 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.databind.cfg.ContextAttributes; +import tools.jackson.datatype.jsonp.JSONPModule; import java.io.ByteArrayOutputStream; -import java.io.IOException; 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; @@ -38,44 +33,58 @@ final class InternalSerdeImpl implements InternalSerde { } private final ArangoSerde userSerde; - private final ObjectMapper mapper; - - 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) - )); + private final JsonMapper mapper; + + InternalSerdeImpl(final ArangoSerde userSerde) { + Objects.requireNonNull(userSerde); + var jsonFactory = JsonFactory.builder() + .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() + .addModule(InternalModule.get(this)) + .changeDefaultPropertyInclusion(i -> i.withValueInclusion(JsonInclude.Include.NON_NULL)) + .annotationIntrospector(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 - 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 @@ -84,7 +93,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]"; } @@ -96,7 +105,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 +123,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 +131,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 +147,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)) { return ((RawJson) value).get().getBytes(StandardCharsets.UTF_8); } else if (SerdeUtils.isManagedClass(clazz)) { return serialize(value); @@ -156,45 +159,39 @@ 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(); } @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) { - 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); + 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(), ctx); } } @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 +199,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 +213,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; } @@ -230,30 +225,26 @@ 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); - } + 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; } 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)) { 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)) + .with(ContextAttributes.getEmpty().withPerCallAttribute(InternalUserSerde.SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) + .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 deleted file mode 100644 index 069068370..000000000 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.arangodb.internal.serde; - -import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.ArangoSerdeProvider; -import com.fasterxml.jackson.databind.Module; - -public class InternalSerdeProvider implements ArangoSerdeProvider { - - /** - * Creates a new InternalSerde with default settings. - * - * @return the created InternalSerde - */ - @Override - public InternalSerde create() { - return create(null, 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); - } - -} 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..d6d3c8d09 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 { - gen.writeTree(SerdeUtils.INSTANCE.parseJson(value)); + public void serialize(String value, JsonGenerator gen, SerializationContext ctxt) { + gen.writeTree(SerdeUtils.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/InternalUserSerde.java b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java new file mode 100644 index 000000000..7cabb0e33 --- /dev/null +++ b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerde.java @@ -0,0 +1,51 @@ +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(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/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeAnnotationIntrospector.java similarity index 85% rename from jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java rename to core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeAnnotationIntrospector.java index d11cc435d..33635155b 100644 --- a/jackson3-serde-json/src/main/java/com/arangodb/serde/jackson3/internal/ArangoSerdeAnnotationIntrospector.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalUserSerdeAnnotationIntrospector.java @@ -1,6 +1,6 @@ -package com.arangodb.serde.jackson3.internal; +package com.arangodb.internal.serde; -import com.arangodb.serde.jackson3.*; +import com.arangodb.serde.annotation.*; import com.fasterxml.jackson.annotation.JsonInclude; import tools.jackson.databind.PropertyName; import tools.jackson.databind.cfg.MapperConfig; @@ -12,7 +12,7 @@ import java.util.Map; import java.util.Optional; -class ArangoSerdeAnnotationIntrospector extends JacksonAnnotationIntrospector { +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; @@ -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/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/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..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,19 +1,17 @@ package com.arangodb.internal.serde; - +import com.arangodb.RequestContext; 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,25 +33,29 @@ 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(); + 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 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)) { - 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); } @@ -63,7 +65,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..a617ebad2 100644 --- a/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java +++ b/core/src/main/java/com/arangodb/internal/serde/RawUserDataValue.java @@ -1,12 +1,13 @@ package com.arangodb.internal.serde; -import com.fasterxml.jackson.core.SerializableString; + +import tools.jackson.core.SerializableString; import java.io.IOException; 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/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java index e8e903fe9..549d2606d 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,29 @@ 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; -public enum SerdeUtils { - INSTANCE; +public final class SerdeUtils { - private static final Logger LOGGER = LoggerFactory.getLogger(SerdeUtils.class); + private SerdeUtils() { + } - private final ObjectMapper jsonMapper = new ObjectMapper(); + private static final Logger LOGGER = LoggerFactory.getLogger(SerdeUtils.class); public static Type constructListType(Class clazz) { - return TypeFactory.defaultInstance().constructCollectionType(List.class, clazz); + return JsonMapper.shared().getTypeFactory().constructCollectionType(List.class, clazz); } public static Type constructParametricType(Class rawType, Type... rawArgs) { @@ -53,62 +49,48 @@ 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(); - if (major != 2 || minor < 10 || minor > 21) { + if (major != 3 || minor > 1) { LOGGER.warn("Unsupported Jackson version: {}", version); } }); } - public ObjectMapper getJsonMapper() { - return jsonMapper; - } - /** * Parse a JSON string. * * @param json JSON string to parse * @return root of the parsed tree */ - public JsonNode parseJson(final String json) { - try { - return jsonMapper.readTree(json); - } catch (JsonProcessingException e) { - throw ArangoDBException.of(e); - } + public static JsonNode parseJson(final String json) { + return JsonMapper.shared().readTree(json); } /** * @param data JsonNode * @return JSON string */ - public String writeJson(final JsonNode data) { - try { - return jsonMapper.writeValueAsString(data); - } catch (JsonProcessingException e) { - throw ArangoDBException.of(e); - } + public static String writeJson(final JsonNode data) { + return JsonMapper.shared().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 +103,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..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,19 +1,18 @@ 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 com.arangodb.RequestContext; +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,22 +27,26 @@ 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); } 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); } } @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/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/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/core/src/main/java/com/arangodb/serde/ArangoSerde.java b/core/src/main/java/com/arangodb/serde/ArangoSerde.java index 5e6713b4c..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,22 +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 - */ - 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/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/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/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/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/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/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/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/internal/ArangoSerdeAnnotationIntrospector.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/ArangoAnnotationIntrospector.java similarity index 52% 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 d91fb31f6..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,18 +1,18 @@ -package com.arangodb.serde.jackson.internal; +package com.arangodb.serde.jackson; -import com.arangodb.serde.jackson.*; +import com.arangodb.serde.annotation.*; 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; 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; @@ -23,21 +23,19 @@ 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]); - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - private static class JsonIncludeNonNull { + @SuppressWarnings("unchecked") + Class[] annotations = MAPPINGS.keySet().toArray(new Class[0]); + ANNOTATIONS = annotations; } @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) { @@ -50,11 +48,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); + return JsonInclude.Value.ALL_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/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/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..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 @@ -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,23 @@ 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(JsonMapper.builder() + .annotationIntrospector(new ArangoAnnotationIntrospector()) + .build()); } /** - * 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 +44,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/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/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/JacksonSerdeImpl.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonSerdeImpl.java index f7c5b2a5a..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 @@ -2,14 +2,8 @@ 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.cfg.ContextAttributes; +import tools.jackson.databind.json.JsonMapper; /** @@ -18,47 +12,24 @@ 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) { + public JacksonSerdeImpl(final JsonMapper mapper) { this.mapper = mapper; - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - mapper.setAnnotationIntrospector(new ArangoSerdeAnnotationIntrospector()); } @Override public byte[] serialize(final Object value) { - try { - return mapper.writeValueAsBytes(value); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - @Override - public T deserialize(final byte[] content, final Class type) { - return deserialize(content, type, RequestContext.EMPTY); + return mapper.writeValueAsBytes(value); } @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 deleted file mode 100644 index 7a3ba8967..000000000 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/json/JacksonJsonSerdeProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.arangodb.serde.jackson.json; - -import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.ArangoSerdeProvider; -import com.arangodb.serde.jackson.JacksonSerde; - -public class JacksonJsonSerdeProvider implements ArangoSerdeProvider { - @Override - public ArangoSerde create() { - return JacksonSerde.load(); - } -} 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/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/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/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/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/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/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/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/pom.xml b/pom.xml index 604b0bdc5..3435b92ad 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,6 @@ driver shaded jackson-serde-json - jackson3-serde-json jsonb-serde http-protocol @@ -31,15 +30,16 @@ - 8 - 8 - 8 + 21 + 21 + 21 UTF-8 https://sonarcloud.io arangodb-1 target/spotbugsXml.xml site/jacoco/jacoco.xml 25.0.0 + 3.0.0 @@ -159,7 +159,9 @@ com.arangodb.internal, com.arangodb.internal.*, com.arangodb.serde.jackson.internal, - javax.* + javax.*, + graal.*, + com.arangodb.arch.* none @@ -246,7 +248,14 @@ com.fasterxml.jackson jackson-bom - 2.21.1 + 2.21.2 + import + pom + + + tools.jackson + jackson-bom + 3.1.2 import pom @@ -265,6 +274,11 @@ jakarta.json-api 2.1.3 + + jakarta.json.bind + jakarta.json.bind-api + ${jsonb.version} + com.arangodb arangodb-java-driver @@ -285,11 +299,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..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 @@ -108,7 +112,7 @@ - com.fasterxml.jackson.core:* + tools.jackson.core:* META-INF/** module-info.class @@ -129,7 +133,7 @@ - com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp + tools.jackson.datatype:jackson-datatype-jakarta-jsonp META-INF/MANIFEST.MF diff --git a/test-functional/pom.xml b/test-functional/pom.xml index 8d7f45af4..b9947e2d2 100644 --- a/test-functional/pom.xml +++ b/test-functional/pom.xml @@ -47,24 +47,20 @@ - com.fasterxml.jackson.databind.JsonNode - com.arangodb.shaded.fasterxml.jackson.databind.JsonNode + tools.jackson.databind.JsonNode + com.arangodb.shaded.jackson.databind.JsonNode - com.fasterxml.jackson.databind.ObjectNode - com.arangodb.shaded.fasterxml.jackson.databind.ObjectNode + tools.jackson.databind.ObjectNode + com.arangodb.shaded.jackson.databind.ObjectNode - com.fasterxml.jackson.databind.node - com.arangodb.shaded.fasterxml.jackson.databind.node + tools.jackson.databind.node + com.arangodb.shaded.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 + tools.jackson.databind.json.JsonMapper + com.arangodb.shaded.jackson.databind.json.JsonMapper diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 6af96a7cd..c2b950ea1 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -24,21 +24,18 @@ 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; -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; @@ -59,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); @@ -526,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, RequestContext.EMPTY); assertThat(newDoc).containsAllEntriesOf(doc); } @@ -1093,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"); } @@ -1120,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"); } @@ -1575,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); } @@ -1943,7 +1940,6 @@ void createAndGetVectorIndex(ArangoCollectionAsync collection) throws ExecutionE } - @ParameterizedTest @MethodSource("asyncCols") void createMDIndex(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { @@ -2108,7 +2104,6 @@ void indexDeduplicateFalse(ArangoCollectionAsync collection) throws ExecutionExc } - @ParameterizedTest @MethodSource("asyncCols") void createTtlIndexWithoutOptions(ArangoCollectionAsync collection) { @@ -2342,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); } @@ -2410,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 @@ -2632,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()))); @@ -2648,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(); @@ -2667,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(); @@ -2687,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(); @@ -2706,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(); @@ -2726,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(); @@ -2757,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(); @@ -2778,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(); @@ -2790,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()), @@ -2801,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(); @@ -2862,8 +2857,8 @@ 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()); - assertThat(jn.get("_key").asText()).isEqualTo(i.getKey()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) i.getOld()).get()); + assertThat(jn.get("_key").asString()).isEqualTo(i.getKey()); } assertThat(deleteResult.getErrors()).isEmpty(); } @@ -2993,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,9 +3103,9 @@ 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").textValue()).isEqualTo("bar"); + assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } } @@ -3227,9 +3222,9 @@ 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").textValue()).isEqualTo("bar"); + assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } } @@ -3548,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 9e43f7a64..e1d257ccb 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -24,21 +24,18 @@ 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; -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; @@ -58,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() @@ -529,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); } @@ -587,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)); } @@ -1625,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); } @@ -1850,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 @@ -1993,7 +1990,6 @@ void createAndGetVectorIndex(ArangoCollection collection) { } - @ParameterizedTest @MethodSource("cols") void createMDIndex(ArangoCollection collection) { @@ -2158,7 +2154,6 @@ void indexDeduplicateFalse(ArangoCollection collection) { } - @ParameterizedTest @MethodSource("cols") void createTtlIndexWithoutOptions(ArangoCollection collection) { @@ -2419,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); } @@ -2488,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 @@ -2710,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()))); @@ -2726,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(); @@ -2745,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(); @@ -2765,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(); @@ -2784,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(); @@ -2804,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(); @@ -2835,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(); @@ -2856,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(); @@ -2868,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()), @@ -2879,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(); @@ -2940,8 +2935,8 @@ 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()); - assertThat(jn.get("_key").asText()).isEqualTo(i.getKey()); + JsonNode jn = SerdeUtils.parseJson(((RawJson) i.getOld()).get()); + assertThat(jn.get("_key").asString()).isEqualTo(i.getKey()); } assertThat(deleteResult.getErrors()).isEmpty(); } @@ -3071,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,9 +3181,9 @@ 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").textValue()).isEqualTo("bar"); + assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } } @@ -3305,9 +3300,9 @@ 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").textValue()).isEqualTo("bar"); + assertThat(jn.get("foo").stringValue()).isEqualTo("bar"); } } @@ -3357,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); @@ -3648,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..320831083 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(); @@ -424,8 +424,8 @@ 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()); - assertThat(body.get("version").isTextual()).isTrue(); + JsonNode body = SerdeUtils.parseJson(response.getBody().get()); + 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..65d3eab86 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() @@ -419,29 +418,14 @@ void executeGetVersion(ArangoDB arangoDB) { .queryParam("details", "true") .build(); final Response response = arangoDB.execute(request, RawJson.class); - JsonNode body = SerdeUtils.INSTANCE.parseJson(response.getBody().get()); - assertThat(body.get("version").isTextual()).isTrue(); + JsonNode body = SerdeUtils.parseJson(response.getBody().get()); + 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..9d61501d7 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java @@ -20,18 +20,16 @@ package com.arangodb; +import com.arangodb.RequestContext; import com.arangodb.entity.*; import com.arangodb.entity.QueryCachePropertiesEntity.CacheMode; 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 +103,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 +171,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,8 +683,8 @@ 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); - JsonNode data = serde.deserialize(res.get(), JsonNode.class); + .getResult().getFirst(); + 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); @@ -796,8 +794,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 +811,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 +829,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 +847,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 +911,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 +1084,6 @@ private String getExplainQuery(ArangoDatabaseAsync db) throws ExecutionException } - - void checkUntypedExecutionPlan(AqlQueryExplainEntity.ExecutionPlan plan) { assertThat(plan).isNotNull(); assertThat(plan.get("estimatedNrItems")) @@ -1304,7 +1296,6 @@ void getAndClearSlowQueries(ArangoDatabaseAsync db) throws ExecutionException, I } - @ParameterizedTest @MethodSource("asyncDbs") void createGraph(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { @@ -1325,13 +1316,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 +1369,6 @@ void getGraphs(ArangoDatabaseAsync db) throws ExecutionException, InterruptedExc } - - - - - - - - - - - - @ParameterizedTest @MethodSource("asyncDbs") void getInfo(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { @@ -1408,5 +1387,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..27a4ce528 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java @@ -20,18 +20,16 @@ package com.arangodb; +import com.arangodb.RequestContext; import com.arangodb.entity.*; import com.arangodb.entity.QueryCachePropertiesEntity.CacheMode; 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 +107,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) @@ -776,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); @@ -1039,7 +1037,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 +1148,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 +1192,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 +1429,6 @@ void getAndClearSlowQueries(ArangoDatabase db) { } - @ParameterizedTest @MethodSource("dbs") void createGraph(ArangoDatabase db) { @@ -1455,7 +1449,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 +1502,6 @@ void getGraphs(ArangoDatabase db) { } - - - - - - - - - - - - @ParameterizedTest @MethodSource("dbs") void getInfo(ArangoDatabase db) { @@ -1538,5 +1520,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..85a94c784 100644 --- a/test-functional/src/test/java/com/arangodb/RequestContextTest.java +++ b/test-functional/src/test/java/com/arangodb/RequestContextTest.java @@ -24,17 +24,17 @@ 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; 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; @@ -51,25 +51,22 @@ class RequestContextTest { private static ArangoDB arangoDB; private static ArangoDatabase db; + private static ArangoDatabaseAsync dbAsync; private static ArangoCollection collection; private static ArangoCollectionAsync collectionAsync; @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) { 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); @@ -78,13 +75,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; } }; @@ -98,7 +91,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(); } @@ -156,4 +150,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/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/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/mapping/annotations/ArangoAnnotationsTest.java b/test-functional/src/test/java/com/arangodb/mapping/annotations/ArangoAnnotationsTest.java index 2af8441b7..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; @@ -35,7 +36,7 @@ class ArangoAnnotationsTest { @Test void documentFieldAnnotations() { - ArangoSerde mapper = JacksonSerde.load(); + ArangoSerde mapper = JacksonSerde.create(); AnnotatedEntity e = new AnnotatedEntity(); e.setId("Id"); @@ -45,7 +46,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, 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 ec47e5385..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,20 +23,19 @@ 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; -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 +43,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 +63,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) @@ -113,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); } @@ -131,11 +126,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 +149,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 +192,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(); @@ -210,29 +205,28 @@ 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(); } - 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..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,28 +23,25 @@ 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; -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 +60,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) @@ -110,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); } @@ -128,6 +122,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 +146,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 +189,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); @@ -207,29 +202,28 @@ 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(); } - 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/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/JacksonConfigurationTest.java b/test-functional/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java index 3b0606fd5..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.internal.serde.InternalSerdeProvider; +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,10 +11,9 @@ 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) { @@ -22,14 +21,13 @@ 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.load(); + ArangoSerde s = JacksonSerde.create(); StringBuilder sb = new StringBuilder(); while (sb.length() < 40_000_000) { @@ -37,10 +35,9 @@ 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); } - } 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..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,15 +1,15 @@ package com.arangodb.serde; -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 com.arangodb.RequestContext; +import com.arangodb.serde.annotation.*; +import com.arangodb.serde.jackson.JacksonSerdeProvider; 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; @@ -21,8 +21,8 @@ */ class JacksonInterferenceTest { - private final ObjectMapper mapper = new ObjectMapper(); - private final ArangoSerde serde = new JacksonJsonSerdeProvider().create(); + private final JsonMapper mapper = new JsonMapper(); + private final ArangoSerde serde = new JacksonSerdeProvider().create(); private FooField fooField; private FooProp fooProp; @@ -158,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); @@ -177,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); @@ -202,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); @@ -211,30 +211,18 @@ 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) { - 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 d7848dd95..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,15 +1,16 @@ package com.arangodb.serde; +import com.arangodb.RequestContext; 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; -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.*; @@ -20,29 +21,29 @@ 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)); + 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); } @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); - RawBytes deserialized = s.deserializeUserData(serialized, RawBytes.class); + RawBytes deserialized = s.deserializeUserData(serialized, RawBytes.class, RequestContext.EMPTY); assertThat(deserialized).isEqualTo(raw); } @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); + BaseDocument deserialized = s.deserialize(s.serialize(json), BaseDocument.class, RequestContext.EMPTY); assertThat(deserialized.getAttribute("foo")).isEqualTo("aaa"); assertThat(deserialized.getAttribute("properties")) .isInstanceOf(Map.class) @@ -52,41 +53,41 @@ 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")); 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"); + 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"); } @Test void deserializeNull() { - InternalSerde s = new InternalSerdeProvider().create(); - Void deser = s.deserialize((byte[]) null, Void.class); + InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); + 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 = new InternalSerdeProvider().create(); - Void deser = s.deserialize(new byte[0], Void.class); + InternalSerde s = InternalSerde.create(new InternalUserSerdeProvider().create()); + 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-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..ec3a2438f 100644 --- a/test-non-functional/pom.xml +++ b/test-non-functional/pom.xml @@ -13,18 +13,7 @@ test-non-functional - - 21 - 21 - 21 - - - - com.arangodb - jackson3-serde-json - compile - com.arangodb jsonb-serde @@ -93,16 +82,16 @@ - com.fasterxml.jackson.databind.JsonNode - com.arangodb.shaded.fasterxml.jackson.databind.JsonNode + tools.jackson.databind.JsonNode + com.arangodb.shaded.jackson.databind.JsonNode - com.fasterxml.jackson.databind.ObjectNode - com.arangodb.shaded.fasterxml.jackson.databind.ObjectNode + tools.jackson.databind.ObjectNode + com.arangodb.shaded.jackson.databind.ObjectNode - com.fasterxml.jackson.databind.node.JsonNodeFactory - com.arangodb.shaded.fasterxml.jackson.databind.node.JsonNodeFactory + tools.jackson.databind.node.JsonNodeFactory + com.arangodb.shaded.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..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,13 +22,12 @@ 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 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 +66,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 +77,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,8 +93,8 @@ void getAsJson() { void getAsBytes() { final RawBytes doc = collection.getDocument(key, RawBytes.class); assertThat(doc.get()).isNotNull(); - Map mapDoc = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> - collection.getSerde().deserializeUserData(doc.get(), Map.class)); + @SuppressWarnings("unchecked") + Map mapDoc = collection.getSerde().deserializeUserData(doc.get(), Map.class, RequestContext.EMPTY); 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/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/InternalSerdePerson.java b/test-non-functional/src/test/java/serde/InternalSerdePerson.java index 9e2f3238a..08da3693b 100644 --- a/test-non-functional/src/test/java/serde/InternalSerdePerson.java +++ b/test-non-functional/src/test/java/serde/InternalSerdePerson.java @@ -1,10 +1,9 @@ package serde; - -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 d425ee50f..f372bec7b 100644 --- a/test-non-functional/src/test/java/serde/InternalSerdeTest.java +++ b/test-non-functional/src/test/java/serde/InternalSerdeTest.java @@ -2,13 +2,13 @@ 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.internal.serde.InternalUserSerdeProvider; 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; @@ -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-non-functional/src/test/java/serde/Jackson3Person.java b/test-non-functional/src/test/java/serde/Jackson3Person.java deleted file mode 100644 index fd28e47c1..000000000 --- a/test-non-functional/src/test/java/serde/Jackson3Person.java +++ /dev/null @@ -1,13 +0,0 @@ -package serde; - -import com.arangodb.serde.jackson3.Key; -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/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/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/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; 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-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 diff --git a/test-perf/src/main/java/com/arangodb/SerdeBench.java b/test-perf/src/main/java/com/arangodb/SerdeBench.java index 1113495c1..29ec08c1a 100644 --- a/test-perf/src/main/java/com/arangodb/SerdeBench.java +++ b/test-perf/src/main/java/com/arangodb/SerdeBench.java @@ -6,11 +6,8 @@ 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 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 +24,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 +74,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 +90,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(); } @@ -133,15 +134,14 @@ public static void main(String[] args) throws RunnerException, IOException { @Benchmark public void rawJsonDeser(Data data, Blackhole bh) { - InternalSerde serde = new InternalSerdeProvider().create(); - bh.consume( - serde.deserialize(data.json, RawJson.class) + InternalSerde serde = InternalSerde.create(null); + bh.consume(serde.deserialize(data.json, RawJson.class, RequestContext.EMPTY) ); } @Benchmark public void rawJsonSer(Data data, Blackhole bh) { - InternalSerde serde = new InternalSerdeProvider().create(); + InternalSerde serde = InternalSerde.create(null); bh.consume( serde.serialize(data.rawJson) ); @@ -149,7 +149,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") ); @@ -158,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) ); } 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/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/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..696126848 100644 --- a/test-resilience/src/test/java/resilience/mock/SerdeTest.java +++ b/test-resilience/src/test/java/resilience/mock/SerdeTest.java @@ -6,10 +6,10 @@ 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.core.JacksonException; +import tools.jackson.databind.JsonNode; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -47,9 +47,8 @@ void unparsableData() { Throwable[] suppressed = thrown.getCause().getSuppressed(); assertThat(suppressed).hasSize(1); assertThat(suppressed[0]) - .isInstanceOf(ArangoDBException.class) - .cause() - .isInstanceOf(JsonParseException.class); + .isInstanceOf(JacksonException.class) + .hasMessageContaining("Unrecognized token"); 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/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 eab073c13..d7ac97a98 100644 --- a/tutorial/maven/src/main/java/FirstProject.java +++ b/tutorial/maven/src/main/java/FirstProject.java @@ -1,8 +1,8 @@ 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 tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.JsonNodeFactory; import java.util.Collections; import java.util.Map; @@ -61,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()); }