From 3a9aff895d8992e596e253c36c9b45bdba274ad4 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 4 Apr 2024 18:45:00 +0200 Subject: [PATCH 1/9] added SerdeContext.EMPTY --- .../com/arangodb/internal/serde/InternalSerdeImpl.java | 2 +- .../com/arangodb/internal/serde/SerdeContextImpl.java | 1 - .../java/com/arangodb/internal/util/ResponseUtils.java | 6 +++--- core/src/main/java/com/arangodb/serde/SerdeContext.java | 5 +++++ .../java/com/arangodb/ArangoCollectionAsyncTest.java | 3 ++- .../src/test/java/com/arangodb/ArangoCollectionTest.java | 3 ++- .../example/document/GetDocumentExampleTest.java | 4 ++-- .../java/com/arangodb/serde/CustomSerdeAsyncTest.java | 5 ++--- .../test/java/com/arangodb/serde/CustomSerdeTest.java | 5 ++--- .../com/arangodb/serde/JacksonConfigurationTest.java | 3 +-- driver/src/test/java/com/arangodb/serde/SerdeTest.java | 9 ++++----- .../serde/jackson/internal/JacksonSerdeImpl.java | 3 +-- .../com/arangodb/vst/internal/VstConnectionAsync.java | 4 ++-- 13 files changed, 27 insertions(+), 26 deletions(-) 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 0c8f5d092..3ce1d75db 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -132,7 +132,7 @@ public byte[] serializeCollectionUserData(Iterable value) { @Override public T deserializeUserData(byte[] content, Class clazz, SerdeContext ctx) { if (isManagedClass(clazz)) { - return deserialize(content, clazz, SerdeContextImpl.EMPTY); + return deserialize(content, clazz, SerdeContext.EMPTY); } else { return userSerde.deserialize(content, clazz, ctx); } diff --git a/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java b/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java index 0d866407b..39436895b 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java @@ -3,7 +3,6 @@ import com.arangodb.serde.SerdeContext; public class SerdeContextImpl implements SerdeContext { - public static final SerdeContext EMPTY = new SerdeContextImpl(null); private final String streamTransactionId; public SerdeContextImpl(String streamTransactionId) { 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 1220d4887..722e23d14 100644 --- a/core/src/main/java/com/arangodb/internal/util/ResponseUtils.java +++ b/core/src/main/java/com/arangodb/internal/util/ResponseUtils.java @@ -23,11 +23,11 @@ import com.arangodb.ArangoDBException; import com.arangodb.entity.ErrorEntity; import com.arangodb.internal.ArangoErrors; +import com.arangodb.internal.InternalResponse; import com.arangodb.internal.net.ArangoDBRedirectException; import com.arangodb.internal.net.ArangoDBUnavailableException; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.internal.InternalResponse; -import com.arangodb.internal.serde.SerdeContextImpl; +import com.arangodb.serde.SerdeContext; import java.util.concurrent.TimeoutException; @@ -54,7 +54,7 @@ public static ArangoDBException translateError(final InternalSerde util, final I response.getMeta(HEADER_ENDPOINT)); } if (response.getBody() != null) { - final ErrorEntity errorEntity = util.deserialize(response.getBody(), ErrorEntity.class, SerdeContextImpl.EMPTY); + final ErrorEntity errorEntity = util.deserialize(response.getBody(), ErrorEntity.class, SerdeContext.EMPTY); if (errorEntity.getCode() == ERROR_INTERNAL && errorEntity.getErrorNum() == ERROR_INTERNAL) { return ArangoDBUnavailableException.from(errorEntity); } diff --git a/core/src/main/java/com/arangodb/serde/SerdeContext.java b/core/src/main/java/com/arangodb/serde/SerdeContext.java index 2f4a4a99a..54bb54697 100644 --- a/core/src/main/java/com/arangodb/serde/SerdeContext.java +++ b/core/src/main/java/com/arangodb/serde/SerdeContext.java @@ -1,9 +1,14 @@ package com.arangodb.serde; +import com.arangodb.internal.serde.SerdeContextImpl; + /** * Context holding information about the current request and response. */ public interface SerdeContext { + + SerdeContext EMPTY = new SerdeContextImpl(null); + /** * @return the stream transaction id of the request (if any) or {@code null} */ diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 562b1b605..6c958a0b5 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -25,6 +25,7 @@ import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.model.*; import com.arangodb.model.DocumentImportOptions.OnDuplicate; +import com.arangodb.serde.SerdeContext; import com.arangodb.serde.jackson.Id; import com.arangodb.serde.jackson.JacksonSerde; import com.arangodb.serde.jackson.Key; @@ -558,7 +559,7 @@ void insertDocumentAsBytes(ArangoCollectionAsync collection) throws ExecutionExc assertThat(createEntity.getRev()).isNotNull(); assertThat(createEntity.getNew()).isNotNull().isInstanceOf(RawBytes.class); Map newDoc = collection.getSerde().deserializeUserData(createEntity.getNew().get(), - Map.class, SerdeContextImpl.EMPTY); + Map.class, SerdeContext.EMPTY); assertThat(newDoc).containsAllEntriesOf(doc); } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java index cb6f9dc6e..be49fd9a9 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -25,6 +25,7 @@ import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.model.*; import com.arangodb.model.DocumentImportOptions.OnDuplicate; +import com.arangodb.serde.SerdeContext; import com.arangodb.serde.jackson.Id; import com.arangodb.serde.jackson.JacksonSerde; import com.arangodb.serde.jackson.Key; @@ -562,7 +563,7 @@ void insertDocumentAsBytes(ArangoCollection collection) { assertThat(createEntity.getRev()).isNotNull(); assertThat(createEntity.getNew()).isNotNull().isInstanceOf(RawBytes.class); Map newDoc = collection.getSerde().deserializeUserData(createEntity.getNew().get(), - Map.class, SerdeContextImpl.EMPTY); + Map.class, SerdeContext.EMPTY); assertThat(newDoc).containsAllEntriesOf(doc); } diff --git a/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java b/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java index 520cd9a6e..166852daf 100644 --- a/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java +++ b/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java @@ -22,7 +22,7 @@ import com.arangodb.entity.BaseDocument; import com.arangodb.example.ExampleBase; -import com.arangodb.internal.serde.SerdeContextImpl; +import com.arangodb.serde.SerdeContext; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import com.fasterxml.jackson.databind.JsonNode; @@ -92,7 +92,7 @@ void getAsJson() { void getAsBytes() { final RawBytes doc = collection.getDocument(key, RawBytes.class); assertThat(doc.get()).isNotNull(); - Map mapDoc = collection.getSerde().deserializeUserData(doc.get(), Map.class, SerdeContextImpl.EMPTY); + Map mapDoc = collection.getSerde().deserializeUserData(doc.get(), Map.class, SerdeContext.EMPTY); assertThat(mapDoc).containsEntry("foo", "bar"); } diff --git a/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java b/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java index cb9405503..7330c1cbf 100644 --- a/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java +++ b/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java @@ -24,7 +24,6 @@ import com.arangodb.*; import com.arangodb.config.ConfigUtils; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.internal.serde.SerdeContextImpl; import com.arangodb.model.DocumentCreateOptions; import com.arangodb.serde.jackson.JacksonSerde; import com.fasterxml.jackson.core.JsonGenerator; @@ -113,7 +112,7 @@ void manualCustomPersonDeserializer() { person.name = "Joe"; InternalSerde serialization = arangoDB.getSerde(); byte[] serialized = serialization.serializeUserData(person); - Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class, SerdeContextImpl.EMPTY); + Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class, SerdeContext.EMPTY); assertThat(deserializedPerson.name).isEqualTo(PERSON_DESERIALIZER_ADDED_PREFIX + PERSON_SERIALIZER_ADDED_PREFIX + person.name); } @@ -210,7 +209,7 @@ void getDocument() throws ExecutionException, InterruptedException { @Test void parseNullString() { final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), - String.class, SerdeContextImpl.EMPTY); + String.class, SerdeContext.EMPTY); assertThat(json).isNull(); } diff --git a/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java b/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java index e7d65cac7..6106605f9 100644 --- a/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java +++ b/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java @@ -24,7 +24,6 @@ import com.arangodb.*; import com.arangodb.config.ConfigUtils; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.internal.serde.SerdeContextImpl; import com.arangodb.model.DocumentCreateOptions; import com.arangodb.serde.jackson.JacksonSerde; import com.fasterxml.jackson.core.JsonGenerator; @@ -110,7 +109,7 @@ void manualCustomPersonDeserializer() { person.name = "Joe"; InternalSerde serialization = arangoDB.getSerde(); byte[] serialized = serialization.serializeUserData(person); - Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class, SerdeContextImpl.EMPTY); + Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class, SerdeContext.EMPTY); assertThat(deserializedPerson.name).isEqualTo(PERSON_DESERIALIZER_ADDED_PREFIX + PERSON_SERIALIZER_ADDED_PREFIX + person.name); } @@ -207,7 +206,7 @@ void getDocument() { @Test void parseNullString() { final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), - String.class, SerdeContextImpl.EMPTY); + String.class, SerdeContext.EMPTY); assertThat(json).isNull(); } diff --git a/driver/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java b/driver/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java index d232e6a98..33ad0d9c0 100644 --- a/driver/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java +++ b/driver/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java @@ -2,7 +2,6 @@ import com.arangodb.ContentType; import com.arangodb.internal.serde.InternalSerdeProvider; -import com.arangodb.internal.serde.SerdeContextImpl; import com.arangodb.serde.jackson.JacksonSerde; import com.arangodb.util.SlowTest; import org.junit.jupiter.params.ParameterizedTest; @@ -26,7 +25,7 @@ void bigStringInternalSerde(ContentType type) { } String in = sb.toString(); byte[] bytes = s.serialize(in); - String out = s.deserialize(bytes, String.class, SerdeContextImpl.EMPTY); + String out = s.deserialize(bytes, String.class, SerdeContext.EMPTY); assertThat(out).isEqualTo(in); } diff --git a/driver/src/test/java/com/arangodb/serde/SerdeTest.java b/driver/src/test/java/com/arangodb/serde/SerdeTest.java index 923fb0fc3..968b99da8 100644 --- a/driver/src/test/java/com/arangodb/serde/SerdeTest.java +++ b/driver/src/test/java/com/arangodb/serde/SerdeTest.java @@ -4,7 +4,6 @@ import com.arangodb.entity.BaseDocument; import com.arangodb.internal.serde.InternalSerde; import com.arangodb.internal.serde.InternalSerdeProvider; -import com.arangodb.internal.serde.SerdeContextImpl; import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; @@ -29,7 +28,7 @@ void rawJsonSerde(ContentType type) { ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); RawJson raw = RawJson.of(SerdeUtils.INSTANCE.writeJson(node)); byte[] serialized = s.serialize(raw); - RawJson deserialized = s.deserialize(serialized, RawJson.class, SerdeContextImpl.EMPTY); + RawJson deserialized = s.deserialize(serialized, RawJson.class, SerdeContext.EMPTY); assertThat(deserialized).isEqualTo(raw); } @@ -40,7 +39,7 @@ void rawBytesSerde(ContentType type) { ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); RawBytes raw = RawBytes.of(s.serialize(node)); byte[] serialized = s.serialize(raw); - RawBytes deserialized = s.deserialize(serialized, RawBytes.class, SerdeContextImpl.EMPTY); + RawBytes deserialized = s.deserialize(serialized, RawBytes.class, SerdeContext.EMPTY); assertThat(deserialized).isEqualTo(raw); } @@ -49,7 +48,7 @@ void rawBytesSerde(ContentType type) { void deserializeBaseDocumentWithNestedProperties(ContentType type) { InternalSerde s = new InternalSerdeProvider(type).create(); RawJson json = RawJson.of("{\"foo\":\"aaa\",\"properties\":{\"foo\":\"bbb\"}}"); - BaseDocument deserialized = s.deserialize(s.serialize(json), BaseDocument.class, SerdeContextImpl.EMPTY); + BaseDocument deserialized = s.deserialize(s.serialize(json), BaseDocument.class, SerdeContext.EMPTY); assertThat(deserialized.getAttribute("foo")).isEqualTo("aaa"); assertThat(deserialized.getAttribute("properties")) .isInstanceOf(Map.class) @@ -65,7 +64,7 @@ void serializeBaseDocumentWithNestedProperties(ContentType type) { doc.addAttribute("foo", "aaa"); doc.addAttribute("properties", Collections.singletonMap("foo", "bbb")); byte[] ser = s.serialize(doc); - ObjectNode on = s.deserializeUserData(ser, ObjectNode.class, SerdeContextImpl.EMPTY); + ObjectNode on = s.deserializeUserData(ser, ObjectNode.class, SerdeContext.EMPTY); assertThat(on.get("foo").textValue()).isEqualTo("aaa"); assertThat(on.get("properties").get("foo").textValue()).isEqualTo("bbb"); } 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 b878ea8b6..7bdb30709 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 @@ -1,6 +1,5 @@ package com.arangodb.serde.jackson.internal; -import com.arangodb.internal.serde.SerdeContextImpl; import com.arangodb.serde.SerdeContext; import com.arangodb.serde.jackson.JacksonSerde; import com.fasterxml.jackson.core.JsonProcessingException; @@ -38,7 +37,7 @@ public byte[] serialize(final Object value) { @Override public T deserialize(final byte[] content, final Class type) { - return deserialize(content, type, SerdeContextImpl.EMPTY); + return deserialize(content, type, SerdeContext.EMPTY); } @Override diff --git a/vst/src/main/java/com/arangodb/vst/internal/VstConnectionAsync.java b/vst/src/main/java/com/arangodb/vst/internal/VstConnectionAsync.java index 9ad4ca58e..a3eb90498 100644 --- a/vst/src/main/java/com/arangodb/vst/internal/VstConnectionAsync.java +++ b/vst/src/main/java/com/arangodb/vst/internal/VstConnectionAsync.java @@ -26,7 +26,7 @@ import com.arangodb.internal.InternalResponse; import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.internal.serde.SerdeContextImpl; +import com.arangodb.serde.SerdeContext; import com.arangodb.velocypack.VPackSlice; import com.arangodb.velocypack.exception.VPackParserException; import com.arangodb.vst.internal.utils.CompletableFutureUtils; @@ -152,7 +152,7 @@ private Collection buildChunks(final Message message) { } private InternalResponse createResponse(final Message message) throws VPackParserException { - InternalResponse response = serde.deserialize(message.getHead().toByteArray(), InternalResponse.class, SerdeContextImpl.EMPTY); + InternalResponse response = serde.deserialize(message.getHead().toByteArray(), InternalResponse.class, SerdeContext.EMPTY); if (message.getBody() != null) { response.setBody(message.getBody().toByteArray()); } From ae779d46f4e91729f6e0088998d3c76850486c8b Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 5 Apr 2024 12:13:58 +0200 Subject: [PATCH 2/9] make SerdeContext#getStreamTransactionId() return Optional --- .../java/com/arangodb/internal/serde/SerdeContextImpl.java | 6 ++++-- core/src/main/java/com/arangodb/serde/SerdeContext.java | 4 +++- .../src/test/java/com/arangodb/JacksonSerdeContextTest.java | 2 +- driver/src/test/java/com/arangodb/SerdeContextTest.java | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java b/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java index 39436895b..5c47fe90f 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java @@ -2,6 +2,8 @@ import com.arangodb.serde.SerdeContext; +import java.util.Optional; + public class SerdeContextImpl implements SerdeContext { private final String streamTransactionId; @@ -10,7 +12,7 @@ public SerdeContextImpl(String streamTransactionId) { } @Override - public String getStreamTransactionId() { - return streamTransactionId; + public Optional getStreamTransactionId() { + return Optional.ofNullable(streamTransactionId); } } diff --git a/core/src/main/java/com/arangodb/serde/SerdeContext.java b/core/src/main/java/com/arangodb/serde/SerdeContext.java index 54bb54697..79af9a6b1 100644 --- a/core/src/main/java/com/arangodb/serde/SerdeContext.java +++ b/core/src/main/java/com/arangodb/serde/SerdeContext.java @@ -2,6 +2,8 @@ import com.arangodb.internal.serde.SerdeContextImpl; +import java.util.Optional; + /** * Context holding information about the current request and response. */ @@ -12,5 +14,5 @@ public interface SerdeContext { /** * @return the stream transaction id of the request (if any) or {@code null} */ - String getStreamTransactionId(); + Optional getStreamTransactionId(); } diff --git a/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java b/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java index f68b67da9..dbeab7a93 100644 --- a/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java +++ b/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java @@ -87,7 +87,7 @@ static class PersonDeserializer extends JsonDeserializer { 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.getSerdeContext(ctx).getStreamTransactionId(); + person.txId = JacksonSerde.getSerdeContext(ctx).getStreamTransactionId().get(); return person; } } diff --git a/driver/src/test/java/com/arangodb/SerdeContextTest.java b/driver/src/test/java/com/arangodb/SerdeContextTest.java index d056a2d40..bed8b6651 100644 --- a/driver/src/test/java/com/arangodb/SerdeContextTest.java +++ b/driver/src/test/java/com/arangodb/SerdeContextTest.java @@ -79,7 +79,7 @@ public T deserialize(byte[] content, Class clazz, SerdeContext ctx) { try { Person res = mapper.readValue(content, Person.class); - res.txId = ctx.getStreamTransactionId(); + res.txId = ctx.getStreamTransactionId().get(); return (T) res; } catch (IOException e) { throw new RuntimeException(e); From 77a87b1b704128921a5151eacbc0658feebc862c Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 8 Apr 2024 18:06:57 +0200 Subject: [PATCH 3/9] thread local SerdeContextHolder --- .../com/arangodb/internal/ArangoExecutor.java | 7 +-- .../internal/ArangoExecutorAsync.java | 13 +++-- .../arangodb/internal/ArangoExecutorSync.java | 6 +- .../internal/InternalArangoCollection.java | 46 +++++++-------- .../arangodb/internal/InternalArangoDB.java | 22 ++++---- .../internal/InternalArangoDatabase.java | 56 +++++++++---------- .../InternalArangoEdgeCollection.java | 8 +-- .../internal/InternalArangoGraph.java | 12 ++-- .../InternalArangoVertexCollection.java | 8 +-- .../internal/net/ExtendedHostResolver.java | 4 +- .../internal/serde/InternalSerde.java | 36 +++++------- .../internal/serde/InternalSerdeImpl.java | 38 ++++--------- .../internal/serde/SerdeContextHolder.java | 17 ++++++ .../arangodb/internal/serde/SerdeUtils.java | 2 - .../internal/serde/UserDataDeserializer.java | 7 +-- .../arangodb/internal/util/ResponseUtils.java | 3 +- .../arangodb/ArangoCollectionAsyncTest.java | 5 +- .../com/arangodb/ArangoCollectionTest.java | 6 +- .../com/arangodb/JacksonSerdeContextTest.java | 25 ++++++++- .../java/com/arangodb/SerdeContextTest.java | 25 ++++++++- .../document/GetDocumentExampleTest.java | 3 +- .../arangodb/serde/CustomSerdeAsyncTest.java | 5 +- .../com/arangodb/serde/CustomSerdeTest.java | 5 +- .../serde/JacksonConfigurationTest.java | 2 +- .../java/com/arangodb/serde/SerdeTest.java | 8 +-- .../vst/internal/VstConnectionAsync.java | 3 +- 26 files changed, 197 insertions(+), 175 deletions(-) create mode 100644 core/src/main/java/com/arangodb/internal/serde/SerdeContextHolder.java diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutor.java b/core/src/main/java/com/arangodb/internal/ArangoExecutor.java index 69ce79ba8..3f491f701 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutor.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutor.java @@ -25,7 +25,6 @@ import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.net.CommunicationProtocol; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.serde.SerdeContext; import java.io.IOException; import java.lang.reflect.Type; @@ -59,8 +58,8 @@ public void setJwt(String jwt) { protocol.setJwt(jwt); } - protected T createResult(final Type type, final InternalResponse response, final SerdeContext ctx) { - return serde.deserialize(response.getBody(), type, ctx); + protected T createResult(final Type type, final InternalResponse response) { + return serde.deserialize(response.getBody(), type); } protected final void interceptResponse(InternalResponse response) { @@ -80,6 +79,6 @@ public QueueTimeMetrics getQueueTimeMetrics() { } public interface ResponseDeserializer { - T deserialize(InternalResponse response, SerdeContext ctx); + T deserialize(InternalResponse response); } } diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java index b09d1bc81..446309257 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java @@ -24,6 +24,7 @@ import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.net.CommunicationProtocol; import com.arangodb.internal.net.HostHandle; +import com.arangodb.internal.serde.SerdeContextHolder; import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.serde.SerdeContext; @@ -50,7 +51,7 @@ public CompletableFuture execute(final Supplier requestS } public CompletableFuture execute(final Supplier requestSupplier, final Type type, final HostHandle hostHandle) { - return execute(requestSupplier, (response, ctx) -> createResult(type, response, ctx), hostHandle); + return execute(requestSupplier, (response) -> createResult(type, response), hostHandle); } public CompletableFuture execute(final Supplier requestSupplier, final ResponseDeserializer responseDeserializer) { @@ -66,14 +67,15 @@ public CompletableFuture execute( .thenApply(Supplier::get) .thenCompose(request -> protocol .executeAsync(interceptRequest(request), hostHandle) - .thenApply(resp -> new ResponseWithContext(resp, SerdeUtils.createSerdeContext(request))) + .thenApply(resp -> new ResponseWithRequest(resp, SerdeUtils.createSerdeContext(request))) ) .handle((r, e) -> { if (e != null) { throw ArangoDBException.of(e); } else { interceptResponse(r.response); - return responseDeserializer.deserialize(r.response, r.context); + SerdeContextHolder.INSTANCE.setCtx(r.context); + return responseDeserializer.deserialize(r.response); } }); @@ -84,15 +86,14 @@ public CompletableFuture execute( } } - private static class ResponseWithContext { + private static class ResponseWithRequest { final InternalResponse response; final SerdeContext context; - ResponseWithContext(InternalResponse response, SerdeContext context) { + ResponseWithRequest(InternalResponse response, SerdeContext context) { this.response = response; this.context = context; } } - } diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java index a34750aa0..9023e7f82 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java @@ -23,6 +23,7 @@ import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.net.CommunicationProtocol; import com.arangodb.internal.net.HostHandle; +import com.arangodb.internal.serde.SerdeContextHolder; import com.arangodb.internal.serde.SerdeUtils; import java.lang.reflect.Type; @@ -41,7 +42,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, ctx) -> createResult(type, response, ctx), hostHandle); + return execute(request, (response) -> createResult(type, response), hostHandle); } public T execute(final InternalRequest request, final ResponseDeserializer responseDeserializer) { @@ -55,7 +56,8 @@ public T execute( final InternalResponse response = protocol.execute(interceptRequest(request), hostHandle); interceptResponse(response); - return responseDeserializer.deserialize(response, SerdeUtils.createSerdeContext(request)); + SerdeContextHolder.INSTANCE.setCtx(SerdeUtils.createSerdeContext(request)); + return responseDeserializer.deserialize(response); } } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java index 8df197f64..ec5aef96b 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoCollection.java @@ -110,7 +110,7 @@ private InternalRequest createInsertDocumentRequest(final DocumentCreateOptions } protected ResponseDeserializer>> insertDocumentsResponseDeserializer(Class userDataClass) { - return (response, ctx) -> { + return (response) -> { final MultiDocumentEntity> multiDocument = new MultiDocumentEntity<>(); final List> docs = new ArrayList<>(); final List errors = new ArrayList<>(); @@ -119,12 +119,12 @@ protected ResponseDeserializer>> for (final JsonNode next : body) { JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME); if (isError != null && isError.booleanValue()) { - final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class, ctx); + final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class); errors.add(error); documentsAndErrors.add(error); } else { Type type = constructParametricType(DocumentCreateEntity.class, userDataClass); - final DocumentCreateEntity doc = getSerde().deserialize(next, type, ctx); + final DocumentCreateEntity doc = getSerde().deserialize(next, type); docs.add(doc); documentsAndErrors.add(doc); } @@ -168,7 +168,7 @@ protected InternalRequest getDocumentRequest(final String key, final DocumentRea } protected ResponseDeserializer getDocumentResponseDeserializer(final Class type) { - return (response, ctx) -> getSerde().deserializeUserData(response.getBody(), type, ctx); + return (response) -> getSerde().deserializeUserData(response.getBody(), type); } protected InternalRequest getDocumentsRequest(final Iterable keys, final DocumentReadOptions options) { @@ -186,7 +186,7 @@ protected InternalRequest getDocumentsRequest(final Iterable keys, final protected ResponseDeserializer> getDocumentsResponseDeserializer( final Class type) { - return (response, ctx) -> { + return (response) -> { final MultiDocumentEntity multiDocument = new MultiDocumentEntity<>(); boolean potentialDirtyRead = Boolean.parseBoolean(response.getMeta("X-Arango-Potential-Dirty-Read")); multiDocument.setPotentialDirtyRead(potentialDirtyRead); @@ -197,11 +197,11 @@ protected ResponseDeserializer> getDocumentsResponseD for (final JsonNode next : body) { JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME); if (isError != null && isError.booleanValue()) { - final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class, ctx); + final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class); errors.add(error); documentsAndErrors.add(error); } else { - final T doc = getSerde().deserializeUserData(getSerde().serialize(next), type, ctx); + final T doc = getSerde().deserializeUserData(getSerde().serialize(next), type); docs.add(doc); documentsAndErrors.add(doc); } @@ -249,7 +249,7 @@ private InternalRequest createReplaceDocumentRequest(final DocumentReplaceOption protected ResponseDeserializer>> replaceDocumentsResponseDeserializer( final Class returnType) { - return (response, ctx) -> { + return (response) -> { final MultiDocumentEntity> multiDocument = new MultiDocumentEntity<>(); final List> docs = new ArrayList<>(); final List errors = new ArrayList<>(); @@ -258,12 +258,12 @@ protected ResponseDeserializer>> for (final JsonNode next : body) { JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME); if (isError != null && isError.booleanValue()) { - final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class, ctx); + final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class); errors.add(error); documentsAndErrors.add(error); } else { Type type = constructParametricType(DocumentUpdateEntity.class, returnType); - final DocumentUpdateEntity doc = getSerde().deserialize(next, type, ctx); + final DocumentUpdateEntity doc = getSerde().deserialize(next, type); docs.add(doc); documentsAndErrors.add(doc); } @@ -312,7 +312,7 @@ private InternalRequest createUpdateDocumentRequest(final DocumentUpdateOptions protected ResponseDeserializer>> updateDocumentsResponseDeserializer( final Class returnType) { - return (response, ctx) -> { + return (response) -> { final MultiDocumentEntity> multiDocument = new MultiDocumentEntity<>(); final List> docs = new ArrayList<>(); final List errors = new ArrayList<>(); @@ -321,12 +321,12 @@ protected ResponseDeserializer>> for (final JsonNode next : body) { JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME); if (isError != null && isError.booleanValue()) { - final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class, ctx); + final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class); errors.add(error); documentsAndErrors.add(error); } else { Type type = constructParametricType(DocumentUpdateEntity.class, returnType); - final DocumentUpdateEntity doc = getSerde().deserialize(next, type, ctx); + final DocumentUpdateEntity doc = getSerde().deserialize(next, type); docs.add(doc); documentsAndErrors.add(doc); } @@ -368,7 +368,7 @@ private InternalRequest createDeleteDocumentRequest(final DocumentDeleteOptions protected ResponseDeserializer>> deleteDocumentsResponseDeserializer( final Class userDataClass) { - return (response, ctx) -> { + return (response) -> { final MultiDocumentEntity> multiDocument = new MultiDocumentEntity<>(); final List> docs = new ArrayList<>(); final List errors = new ArrayList<>(); @@ -377,12 +377,12 @@ protected ResponseDeserializer>> for (final JsonNode next : body) { JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME); if (isError != null && isError.booleanValue()) { - final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class, ctx); + final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class); errors.add(error); documentsAndErrors.add(error); } else { Type type = constructParametricType(DocumentDeleteEntity.class, userDataClass); - final DocumentDeleteEntity doc = getSerde().deserialize(next, type, ctx); + final DocumentDeleteEntity doc = getSerde().deserialize(next, type); docs.add(doc); documentsAndErrors.add(doc); } @@ -413,7 +413,7 @@ protected InternalRequest deleteIndexRequest(final String id) { } protected ResponseDeserializer deleteIndexResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), "/id", String.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/id", String.class); } private String createIndexId(final String id) { @@ -495,11 +495,11 @@ protected InternalRequest getIndexesRequest() { } protected ResponseDeserializer> getIndexesResponseDeserializer() { - return (response, ctx) -> { + return (response) -> { 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, ctx)); + indexes.add(getSerde().deserialize(idx, IndexEntity.class)); } } return indexes; @@ -507,11 +507,11 @@ protected ResponseDeserializer> getIndexesResponseDeseri } protected ResponseDeserializer> getInvertedIndexesResponseDeserializer() { - return (response, ctx) -> { + return (response) -> { 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, ctx)); + indexes.add(getSerde().deserialize(idx, InvertedIndexEntity.class)); } } return indexes; @@ -583,8 +583,8 @@ protected InternalRequest getPermissionsRequest(final String user) { } protected ResponseDeserializer getPermissionsResponseDeserialzer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - Permissions.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + Permissions.class); } } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoDB.java b/core/src/main/java/com/arangodb/internal/InternalArangoDB.java index 47cd5b085..6cefb34f2 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoDB.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoDB.java @@ -66,11 +66,11 @@ protected InternalRequest getServerIdRequest() { } protected ResponseDeserializer getRoleResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), "/role", ServerRole.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/role", ServerRole.class); } protected ResponseDeserializer getServerIdResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), "/id", String.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/id", String.class); } protected InternalRequest createDatabaseRequest(final DBCreateOptions options) { @@ -81,8 +81,8 @@ protected InternalRequest createDatabaseRequest(final DBCreateOptions options) { } protected ResponseDeserializer createDatabaseResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - Boolean.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + Boolean.class); } protected InternalRequest getDatabasesRequest(final String dbName) { @@ -90,8 +90,8 @@ protected InternalRequest getDatabasesRequest(final String dbName) { } protected ResponseDeserializer> getDatabaseResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(String.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(String.class)); } protected InternalRequest getAccessibleDatabasesForRequest(final String dbName, final String user) { @@ -99,7 +99,7 @@ protected InternalRequest getAccessibleDatabasesForRequest(final String dbName, } protected ResponseDeserializer> getAccessibleDatabasesForResponseDeserializer() { - return (response, ctx) -> { + return (response) -> { Iterator names = getSerde().parse(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER).fieldNames(); final Collection dbs = new ArrayList<>(); @@ -136,8 +136,8 @@ protected InternalRequest getUserRequest(final String dbName, final String user) } protected ResponseDeserializer> getUsersResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(UserEntity.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(UserEntity.class)); } protected InternalRequest updateUserRequest(final String dbName, final String user, final UserUpdateOptions options) { @@ -173,10 +173,10 @@ protected InternalRequest executeRequest(final Request request) { } protected ResponseDeserializer> responseDeserializer(Class type) { - return (response, ctx) -> new Response<>( + return (response) -> new Response<>( response.getResponseCode(), response.getMeta(), - getSerde().deserializeUserData(response.getBody(), type, ctx) + getSerde().deserializeUserData(response.getBody(), type) ); } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java b/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java index 5ad1fc963..32a126f11 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java @@ -70,8 +70,8 @@ public String name() { } protected ResponseDeserializer> getDatabaseResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(String.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(String.class)); } protected InternalRequest getAccessibleDatabasesRequest() { @@ -103,8 +103,8 @@ protected InternalRequest getCollectionsRequest(final CollectionsReadOptions opt } protected ResponseDeserializer> getCollectionsResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(CollectionEntity.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(CollectionEntity.class)); } protected InternalRequest dropRequest() { @@ -112,8 +112,8 @@ protected InternalRequest dropRequest() { } protected ResponseDeserializer createDropResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - Boolean.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + Boolean.class); } protected InternalRequest grantAccessRequest(final String user, final Permissions permissions) { @@ -136,8 +136,8 @@ protected InternalRequest getPermissionsRequest(final String user) { } protected ResponseDeserializer getPermissionsResponseDeserialzer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - Permissions.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + Permissions.class); } protected InternalRequest queryRequest(final String query, final Map bindVars, @@ -232,8 +232,8 @@ protected InternalRequest deleteAqlFunctionRequest(final String name, final AqlF } public ResponseDeserializer> cursorEntityDeserializer(final Class type) { - return (response, ctx) -> { - CursorEntity e = getSerde().deserialize(response.getBody(), constructParametricType(CursorEntity.class, type), ctx); + return (response) -> { + CursorEntity e = getSerde().deserialize(response.getBody(), constructParametricType(CursorEntity.class, type)); boolean potentialDirtyRead = Boolean.parseBoolean(response.getMeta("X-Arango-Potential-Dirty-Read")); e.setPotentialDirtyRead(potentialDirtyRead); return e; @@ -241,7 +241,7 @@ public ResponseDeserializer> cursorEntityDeserializer(final } protected ResponseDeserializer deleteAqlFunctionResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), "/deletedCount", Integer.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/deletedCount", Integer.class); } protected InternalRequest getAqlFunctionsRequest(final AqlFunctionGetOptions options) { @@ -252,8 +252,8 @@ protected InternalRequest getAqlFunctionsRequest(final AqlFunctionGetOptions opt } protected ResponseDeserializer> getAqlFunctionsResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(AqlFunctionEntity.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(AqlFunctionEntity.class)); } protected InternalRequest createGraphRequest(final String name, final Iterable edgeDefinitions, @@ -265,7 +265,7 @@ protected InternalRequest createGraphRequest(final String name, final Iterable createGraphResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), "/graph", GraphEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/graph", GraphEntity.class); } protected InternalRequest getGraphsRequest() { @@ -273,8 +273,8 @@ protected InternalRequest getGraphsRequest() { } protected ResponseDeserializer> getGraphsResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), "/graphs", - constructListType(GraphEntity.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/graphs", + constructListType(GraphEntity.class)); } protected InternalRequest transactionRequest(final String action, final TransactionOptions options) { @@ -282,9 +282,9 @@ protected InternalRequest transactionRequest(final String action, final Transact } protected ResponseDeserializer transactionResponseDeserializer(final Class type) { - return (response, ctx) -> { + return (response) -> { byte[] userContent = getSerde().extract(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER); - return getSerde().deserializeUserData(userContent, type, ctx); + return getSerde().deserializeUserData(userContent, type); }; } @@ -310,8 +310,8 @@ protected InternalRequest getStreamTransactionRequest(String id) { } protected ResponseDeserializer> transactionsResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), "/transactions", - constructListType(TransactionEntity.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/transactions", + constructListType(TransactionEntity.class)); } protected InternalRequest commitStreamTransactionRequest(String id) { @@ -319,8 +319,8 @@ protected InternalRequest commitStreamTransactionRequest(String id) { } protected ResponseDeserializer streamTransactionResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - StreamTransactionEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + StreamTransactionEntity.class); } protected InternalRequest getInfoRequest() { @@ -328,8 +328,8 @@ protected InternalRequest getInfoRequest() { } protected ResponseDeserializer getInfoResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - DatabaseEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + DatabaseEntity.class); } protected InternalRequest reloadRoutingRequest() { @@ -341,8 +341,8 @@ protected InternalRequest getViewsRequest() { } protected ResponseDeserializer> getViewsResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(ViewEntity.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(ViewEntity.class)); } protected InternalRequest createViewRequest(final String name, final ViewType type) { @@ -367,8 +367,8 @@ protected InternalRequest getAnalyzersRequest() { } protected ResponseDeserializer> getSearchAnalyzersResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, - constructListType(SearchAnalyzer.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER, + constructListType(SearchAnalyzer.class)); } 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 c0497771f..2c035f435 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoEdgeCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoEdgeCollection.java @@ -79,7 +79,7 @@ protected InternalRequest insertEdgeRequest(final T value, final EdgeCreateO } protected ResponseDeserializer insertEdgeResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeEntity.class); } protected InternalRequest getEdgeRequest(final String key, final GraphDocumentReadOptions options) { @@ -96,7 +96,7 @@ protected InternalRequest getEdgeRequest(final String key, final GraphDocumentRe } protected ResponseDeserializer getEdgeResponseDeserializer(final Class type) { - return (response, ctx) -> getSerde().deserializeUserData(getSerde().extract(response.getBody(), EDGE_JSON_POINTER), type, ctx); + return (response) -> getSerde().deserializeUserData(getSerde().extract(response.getBody(), EDGE_JSON_POINTER), type); } protected InternalRequest replaceEdgeRequest(final String key, final T value, final EdgeReplaceOptions options) { @@ -111,7 +111,7 @@ protected InternalRequest replaceEdgeRequest(final String key, final T value } protected ResponseDeserializer replaceEdgeResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeUpdateEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeUpdateEntity.class); } protected InternalRequest updateEdgeRequest(final String key, final T value, final EdgeUpdateOptions options) { @@ -128,7 +128,7 @@ protected InternalRequest updateEdgeRequest(final String key, final T value, } protected ResponseDeserializer updateEdgeResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeUpdateEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), EDGE_JSON_POINTER, EdgeUpdateEntity.class); } 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 ff0bd6578..45e4a7bd3 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, ctx) -> getSerde().deserialize(response.getBody(), "/collections", - constructListType(String.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/collections", + constructListType(String.class)); } protected InternalRequest addVertexCollectionRequest(final String name, final VertexCollectionCreateOptions options) { @@ -98,8 +98,8 @@ protected InternalRequest getEdgeDefinitionsRequest() { } protected ResponseDeserializer> getEdgeDefinitionsDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), "/collections", - constructListType(String.class), ctx); + return (response) -> getSerde().deserialize(response.getBody(), "/collections", + constructListType(String.class)); } protected InternalRequest addEdgeDefinitionRequest(final EdgeDefinition definition) { @@ -109,7 +109,7 @@ protected InternalRequest addEdgeDefinitionRequest(final EdgeDefinition definiti } protected ResponseDeserializer addEdgeDefinitionResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), GRAPH, GraphEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), GRAPH, GraphEntity.class); } protected InternalRequest replaceEdgeDefinitionRequest(final EdgeDefinition definition, final ReplaceEdgeDefinitionOptions options) { @@ -122,7 +122,7 @@ protected InternalRequest replaceEdgeDefinitionRequest(final EdgeDefinition defi } protected ResponseDeserializer replaceEdgeDefinitionResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), GRAPH, GraphEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), GRAPH, GraphEntity.class); } } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoVertexCollection.java b/core/src/main/java/com/arangodb/internal/InternalArangoVertexCollection.java index ed1ec87d0..991201661 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoVertexCollection.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoVertexCollection.java @@ -77,7 +77,7 @@ protected InternalRequest insertVertexRequest(final T value, final VertexCre } protected ResponseDeserializer insertVertexResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexEntity.class); } protected InternalRequest getVertexRequest(final String key, final GraphDocumentReadOptions options) { @@ -94,7 +94,7 @@ protected InternalRequest getVertexRequest(final String key, final GraphDocument } protected ResponseDeserializer getVertexResponseDeserializer(final Class type) { - return (response, ctx) -> getSerde().deserializeUserData(getSerde().extract(response.getBody(), VERTEX_JSON_POINTER), type, ctx); + return (response) -> getSerde().deserializeUserData(getSerde().extract(response.getBody(), VERTEX_JSON_POINTER), type); } protected InternalRequest replaceVertexRequest(final String key, final T value, final VertexReplaceOptions options) { @@ -109,7 +109,7 @@ protected InternalRequest replaceVertexRequest(final String key, final T val } protected ResponseDeserializer replaceVertexResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexUpdateEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexUpdateEntity.class); } protected InternalRequest updateVertexRequest(final String key, final T value, final VertexUpdateOptions options) { @@ -126,7 +126,7 @@ protected InternalRequest updateVertexRequest(final String key, final T valu } protected ResponseDeserializer updateVertexResponseDeserializer() { - return (response, ctx) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexUpdateEntity.class, ctx); + return (response) -> getSerde().deserialize(response.getBody(), VERTEX_JSON_POINTER, VertexUpdateEntity.class); } protected InternalRequest deleteVertexRequest(final String key, final VertexDeleteOptions options) { 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 3dd8e9c40..7ba5b58de 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, ctx) -> { + (r) -> { final List> tmp = arangoSerialization.deserialize(r.getBody(), "/endpoints", constructParametricType(List.class, - constructParametricType(Map.class, String.class, String.class)), ctx); + constructParametricType(Map.class, String.class, String.class))); Collection endpoints = new ArrayList<>(); for (final Map map : tmp) { endpoints.add(map.get("endpoint")); diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java b/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java index e5ab9d689..758cc550a 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerde.java @@ -3,7 +3,6 @@ import com.arangodb.arch.UsedInApi; import com.arangodb.serde.ArangoSerde; import com.arangodb.ContentType; -import com.arangodb.serde.SerdeContext; import com.fasterxml.jackson.databind.JsonNode; import java.lang.reflect.Type; @@ -35,21 +34,19 @@ public interface InternalSerde extends ArangoSerde { * * @param content byte array to deserialize * @param type target data type - * @param ctx serde context * @return deserialized object */ - T deserialize(byte[] content, Type type, SerdeContext ctx); + T deserialize(byte[] content, Type type); /** * Deserializes the parsed json node and binds it to the target data type. * * @param node parsed json node * @param clazz class of target data type - * @param ctx serde context * @return deserialized object */ - default T deserialize(JsonNode node, Class clazz, SerdeContext ctx) { - return deserialize(node, (Type) clazz, ctx); + default T deserialize(JsonNode node, Class clazz) { + return deserialize(node, (Type) clazz); } /** @@ -57,10 +54,9 @@ default T deserialize(JsonNode node, Class clazz, SerdeContext ctx) { * * @param node parsed json node * @param type target data type - * @param ctx serde context * @return deserialized object */ - T deserialize(JsonNode node, Type type, SerdeContext ctx); + T deserialize(JsonNode node, Type type); /** * Parses the content. @@ -86,11 +82,10 @@ default T deserialize(JsonNode node, Class clazz, SerdeContext ctx) { * @param content byte array to deserialize * @param jsonPointer location of data to be deserialized * @param clazz class of target data type - * @param ctx serde context * @return deserialized object */ - default T deserialize(byte[] content, String jsonPointer, Class clazz, SerdeContext ctx) { - return deserialize(content, jsonPointer, (Type) clazz, ctx); + default T deserialize(byte[] content, String jsonPointer, Class clazz) { + return deserialize(content, jsonPointer, (Type) clazz); } /** @@ -100,11 +95,10 @@ default T deserialize(byte[] content, String jsonPointer, Class clazz, Se * @param content byte array to deserialize * @param jsonPointer location of data to be deserialized * @param type target data type - * @param ctx serde context * @return deserialized object */ - default T deserialize(byte[] content, String jsonPointer, Type type, SerdeContext ctx) { - return deserialize(parse(content, jsonPointer), type, ctx); + default T deserialize(byte[] content, String jsonPointer, Type type) { + return deserialize(parse(content, jsonPointer), type); } /** @@ -128,31 +122,28 @@ default T deserialize(byte[] content, String jsonPointer, Type type, SerdeCo * * @param content byte array to deserialize * @param clazz class of target data type - * @param ctx serde context * @return deserialized object */ - T deserializeUserData(byte[] content, Class clazz, SerdeContext ctx); + T deserializeUserData(byte[] content, Class clazz); /** * Deserializes the content and binds it to the target data type, using the user serde. * * @param content byte array to deserialize * @param type target data type - * @param ctx serde context * @return deserialized object */ - T deserializeUserData(byte[] content, Type type, SerdeContext ctx); + T deserializeUserData(byte[] content, Type type); /** * Deserializes the parsed json node and binds it to the target data type, using the user serde. * * @param node parsed json node * @param clazz class of target data type - * @param ctx serde context * @return deserialized object */ - default T deserializeUserData(JsonNode node, Class clazz, SerdeContext ctx) { - return deserializeUserData(node, (Type) clazz, ctx); + default T deserializeUserData(JsonNode node, Class clazz) { + return deserializeUserData(node, (Type) clazz); } /** @@ -160,10 +151,9 @@ default T deserializeUserData(JsonNode node, Class clazz, SerdeContext ct * * @param node parsed json node * @param type target data type - * @param ctx serde context * @return deserialized object */ - T deserializeUserData(JsonNode node, Type type, SerdeContext ctx); + T deserializeUserData(JsonNode node, Type type); /** * @return the user serde 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 3ce1d75db..3c5c4f013 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -4,7 +4,6 @@ import com.arangodb.entity.BaseDocument; import com.arangodb.entity.BaseEdgeDocument; import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.SerdeContext; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import com.fasterxml.jackson.annotation.JsonInclude; @@ -13,16 +12,13 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.cfg.ContextAttributes; import java.io.IOException; import java.lang.reflect.Type; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import static com.arangodb.internal.serde.SerdeUtils.SERDE_CONTEXT_ATTRIBUTE_NAME; import static com.arangodb.internal.serde.SerdeUtils.checkSupportedJacksonVersion; final class InternalSerdeImpl implements InternalSerde { @@ -61,13 +57,7 @@ public byte[] serialize(final Object value) { @Override public T deserialize(byte[] content, Class clazz) { - throw new IllegalArgumentException("Deserialization without context should never be invoked."); - } - - @Override - public T deserialize(byte[] content, Class clazz, SerdeContext ctx) { - Objects.requireNonNull(ctx); - return deserialize(content, (Type) clazz, ctx); + return deserialize(content, (Type) clazz); } @Override @@ -130,27 +120,27 @@ public byte[] serializeCollectionUserData(Iterable value) { } @Override - public T deserializeUserData(byte[] content, Class clazz, SerdeContext ctx) { + public T deserializeUserData(byte[] content, Class clazz) { if (isManagedClass(clazz)) { - return deserialize(content, clazz, SerdeContext.EMPTY); + return deserialize(content, clazz); } else { - return userSerde.deserialize(content, clazz, ctx); + return userSerde.deserialize(content, clazz, SerdeContextHolder.INSTANCE.getCtx()); } } @Override @SuppressWarnings("unchecked") - public T deserializeUserData(byte[] content, Type type, SerdeContext ctx) { + public T deserializeUserData(byte[] content, Type type) { if (type instanceof Class) { - return deserializeUserData(content, (Class) type, ctx); + return deserializeUserData(content, (Class) type); } else { throw new UnsupportedOperationException(); } } @Override - public T deserializeUserData(JsonNode node, Type type, SerdeContext ctx) { - return deserializeUserData(serialize(node), type, ctx); + public T deserializeUserData(JsonNode node, Type type) { + return deserializeUserData(serialize(node), type); } @Override @@ -159,25 +149,21 @@ public ArangoSerde getUserSerde() { } @Override - public T deserialize(final JsonNode node, final Type type, final SerdeContext ctx) { + public T deserialize(final JsonNode node, final Type type) { try { - return mapper.readerFor(mapper.constructType(type)) - .with(ContextAttributes.getEmpty().withPerCallAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) - .readValue(node); + return mapper.readerFor(mapper.constructType(type)).readValue(node); } catch (IOException e) { throw ArangoDBException.of(e); } } @Override - public T deserialize(final byte[] content, final Type type, final SerdeContext ctx) { + public T deserialize(final byte[] content, final Type type) { if (content == null) { return null; } try { - return mapper.readerFor(mapper.constructType(type)) - .with(ContextAttributes.getEmpty().withPerCallAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME, ctx)) - .readValue(content); + return mapper.readerFor(mapper.constructType(type)).readValue(content); } catch (IOException e) { throw ArangoDBException.of(e); } diff --git a/core/src/main/java/com/arangodb/internal/serde/SerdeContextHolder.java b/core/src/main/java/com/arangodb/internal/serde/SerdeContextHolder.java new file mode 100644 index 000000000..1a29e256b --- /dev/null +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeContextHolder.java @@ -0,0 +1,17 @@ +package com.arangodb.internal.serde; + +import com.arangodb.serde.SerdeContext; + +public enum SerdeContextHolder { + INSTANCE; + + private final ThreadLocal ctx = ThreadLocal.withInitial(() -> SerdeContext.EMPTY); + + public SerdeContext getCtx() { + return ctx.get(); + } + + public void setCtx(SerdeContext ctx) { + this.ctx.set(ctx != null ? ctx : SerdeContext.EMPTY); + } +} 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 93d6bedb9..38985a953 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java @@ -1,9 +1,7 @@ package com.arangodb.internal.serde; import com.arangodb.ArangoDBException; -import com.arangodb.Request; import com.arangodb.internal.InternalRequest; -import com.arangodb.model.TransactionalOptions; import com.arangodb.serde.SerdeContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; 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 221658dc2..91220088b 100644 --- a/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java +++ b/core/src/main/java/com/arangodb/internal/serde/UserDataDeserializer.java @@ -1,6 +1,5 @@ package com.arangodb.internal.serde; -import com.arangodb.serde.SerdeContext; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.DeserializationContext; @@ -11,9 +10,7 @@ import java.io.IOException; import java.lang.reflect.Type; -import java.util.Objects; -import static com.arangodb.internal.serde.SerdeUtils.SERDE_CONTEXT_ATTRIBUTE_NAME; import static com.arangodb.internal.serde.SerdeUtils.convertToType; class UserDataDeserializer extends JsonDeserializer implements ContextualDeserializer { @@ -32,9 +29,7 @@ private UserDataDeserializer(final JavaType targetType, final InternalSerde serd @Override public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - SerdeContext serdeContext = (SerdeContext) ctxt.getAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME); - Objects.requireNonNull(serdeContext); - return serde.deserializeUserData(p.readValueAsTree(), targetType, serdeContext); + return serde.deserializeUserData(p.readValueAsTree(), targetType); } @Override 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 722e23d14..4a927b878 100644 --- a/core/src/main/java/com/arangodb/internal/util/ResponseUtils.java +++ b/core/src/main/java/com/arangodb/internal/util/ResponseUtils.java @@ -27,7 +27,6 @@ import com.arangodb.internal.net.ArangoDBRedirectException; import com.arangodb.internal.net.ArangoDBUnavailableException; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.serde.SerdeContext; import java.util.concurrent.TimeoutException; @@ -54,7 +53,7 @@ public static ArangoDBException translateError(final InternalSerde util, final I response.getMeta(HEADER_ENDPOINT)); } if (response.getBody() != null) { - final ErrorEntity errorEntity = util.deserialize(response.getBody(), ErrorEntity.class, SerdeContext.EMPTY); + final ErrorEntity errorEntity = util.deserialize(response.getBody(), ErrorEntity.class); if (errorEntity.getCode() == ERROR_INTERNAL && errorEntity.getErrorNum() == ERROR_INTERNAL) { return ArangoDBUnavailableException.from(errorEntity); } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 6c958a0b5..645f8e01c 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -21,11 +21,9 @@ package com.arangodb; import com.arangodb.entity.*; -import com.arangodb.internal.serde.SerdeContextImpl; import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.model.*; import com.arangodb.model.DocumentImportOptions.OnDuplicate; -import com.arangodb.serde.SerdeContext; import com.arangodb.serde.jackson.Id; import com.arangodb.serde.jackson.JacksonSerde; import com.arangodb.serde.jackson.Key; @@ -558,8 +556,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().deserializeUserData(createEntity.getNew().get(), - Map.class, SerdeContext.EMPTY); + Map newDoc = collection.getSerde().deserializeUserData(createEntity.getNew().get(), Map.class); assertThat(newDoc).containsAllEntriesOf(doc); } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java index be49fd9a9..d4fd36123 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -21,11 +21,9 @@ package com.arangodb; import com.arangodb.entity.*; -import com.arangodb.internal.serde.SerdeContextImpl; import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.model.*; import com.arangodb.model.DocumentImportOptions.OnDuplicate; -import com.arangodb.serde.SerdeContext; import com.arangodb.serde.jackson.Id; import com.arangodb.serde.jackson.JacksonSerde; import com.arangodb.serde.jackson.Key; @@ -42,7 +40,6 @@ import org.junit.jupiter.params.provider.MethodSource; import java.util.*; -import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -562,8 +559,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().deserializeUserData(createEntity.getNew().get(), - Map.class, SerdeContext.EMPTY); + Map newDoc = collection.getSerde().deserializeUserData(createEntity.getNew().get(), Map.class); assertThat(newDoc).containsAllEntriesOf(doc); } diff --git a/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java b/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java index dbeab7a93..5cc5152f2 100644 --- a/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java +++ b/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java @@ -38,6 +38,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.concurrent.ExecutionException; import static com.arangodb.util.TestUtils.TEST_DB; import static org.assertj.core.api.Assertions.assertThat; @@ -52,6 +53,7 @@ class JacksonSerdeContextTest { private static ArangoDB arangoDB; private static ArangoDatabase db; private static ArangoCollection collection; + private static ArangoCollectionAsync collectionAsync; @BeforeAll static void init() { @@ -71,6 +73,7 @@ static void init() { } collection = db.collection(COLLECTION_NAME); + collectionAsync = arangoDB.async().db(TEST_DB).collection(COLLECTION_NAME); if (!collection.exists()) { collection.create(); } @@ -78,8 +81,10 @@ static void init() { @AfterAll static void shutdown() { - if (db.exists()) + if (db.exists()) { db.drop(); + } + arangoDB.shutdown(); } static class PersonDeserializer extends JsonDeserializer { @@ -118,4 +123,22 @@ void getDocumentWithinTx() { 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/driver/src/test/java/com/arangodb/SerdeContextTest.java b/driver/src/test/java/com/arangodb/SerdeContextTest.java index bed8b6651..bbfd7399a 100644 --- a/driver/src/test/java/com/arangodb/SerdeContextTest.java +++ b/driver/src/test/java/com/arangodb/SerdeContextTest.java @@ -38,6 +38,7 @@ import java.io.IOException; import java.util.Collections; import java.util.Objects; +import java.util.concurrent.ExecutionException; import static com.arangodb.util.TestUtils.TEST_DB; import static org.assertj.core.api.Assertions.assertThat; @@ -52,6 +53,7 @@ class SerdeContextTest { private static ArangoDB arangoDB; private static ArangoDatabase db; private static ArangoCollection collection; + private static ArangoCollectionAsync collectionAsync; @BeforeAll static void init() { @@ -97,6 +99,7 @@ public T deserialize(byte[] content, Class clazz, SerdeContext ctx) { } collection = db.collection(COLLECTION_NAME); + collectionAsync = arangoDB.async().db(TEST_DB).collection(COLLECTION_NAME); if (!collection.exists()) { collection.create(); } @@ -104,8 +107,10 @@ public T deserialize(byte[] content, Class clazz, SerdeContext ctx) { @AfterAll static void shutdown() { - if (db.exists()) + if (db.exists()) { db.drop(); + } + arangoDB.shutdown(); } static class Person { @@ -134,4 +139,22 @@ void getDocumentWithinTx() { 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/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java b/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java index 166852daf..8d220faab 100644 --- a/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java +++ b/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java @@ -22,7 +22,6 @@ import com.arangodb.entity.BaseDocument; import com.arangodb.example.ExampleBase; -import com.arangodb.serde.SerdeContext; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import com.fasterxml.jackson.databind.JsonNode; @@ -92,7 +91,7 @@ void getAsJson() { void getAsBytes() { final RawBytes doc = collection.getDocument(key, RawBytes.class); assertThat(doc.get()).isNotNull(); - Map mapDoc = collection.getSerde().deserializeUserData(doc.get(), Map.class, SerdeContext.EMPTY); + Map mapDoc = collection.getSerde().deserializeUserData(doc.get(), Map.class); assertThat(mapDoc).containsEntry("foo", "bar"); } diff --git a/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java b/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java index 7330c1cbf..cd649640c 100644 --- a/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java +++ b/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java @@ -112,7 +112,7 @@ void manualCustomPersonDeserializer() { person.name = "Joe"; InternalSerde serialization = arangoDB.getSerde(); byte[] serialized = serialization.serializeUserData(person); - Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class, SerdeContext.EMPTY); + Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class); assertThat(deserializedPerson.name).isEqualTo(PERSON_DESERIALIZER_ADDED_PREFIX + PERSON_SERIALIZER_ADDED_PREFIX + person.name); } @@ -208,8 +208,7 @@ void getDocument() throws ExecutionException, InterruptedException { @Test void parseNullString() { - final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), - String.class, SerdeContext.EMPTY); + final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class); assertThat(json).isNull(); } diff --git a/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java b/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java index 6106605f9..292795d3e 100644 --- a/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java +++ b/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java @@ -109,7 +109,7 @@ void manualCustomPersonDeserializer() { person.name = "Joe"; InternalSerde serialization = arangoDB.getSerde(); byte[] serialized = serialization.serializeUserData(person); - Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class, SerdeContext.EMPTY); + Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class); assertThat(deserializedPerson.name).isEqualTo(PERSON_DESERIALIZER_ADDED_PREFIX + PERSON_SERIALIZER_ADDED_PREFIX + person.name); } @@ -205,8 +205,7 @@ void getDocument() { @Test void parseNullString() { - final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), - String.class, SerdeContext.EMPTY); + final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class); assertThat(json).isNull(); } diff --git a/driver/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java b/driver/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java index 33ad0d9c0..1a0f82122 100644 --- a/driver/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java +++ b/driver/src/test/java/com/arangodb/serde/JacksonConfigurationTest.java @@ -25,7 +25,7 @@ void bigStringInternalSerde(ContentType type) { } String in = sb.toString(); byte[] bytes = s.serialize(in); - String out = s.deserialize(bytes, String.class, SerdeContext.EMPTY); + String out = s.deserialize(bytes, String.class); assertThat(out).isEqualTo(in); } diff --git a/driver/src/test/java/com/arangodb/serde/SerdeTest.java b/driver/src/test/java/com/arangodb/serde/SerdeTest.java index 968b99da8..7bc9009df 100644 --- a/driver/src/test/java/com/arangodb/serde/SerdeTest.java +++ b/driver/src/test/java/com/arangodb/serde/SerdeTest.java @@ -28,7 +28,7 @@ void rawJsonSerde(ContentType type) { ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); RawJson raw = RawJson.of(SerdeUtils.INSTANCE.writeJson(node)); byte[] serialized = s.serialize(raw); - RawJson deserialized = s.deserialize(serialized, RawJson.class, SerdeContext.EMPTY); + RawJson deserialized = s.deserialize(serialized, RawJson.class); assertThat(deserialized).isEqualTo(raw); } @@ -39,7 +39,7 @@ void rawBytesSerde(ContentType type) { ObjectNode node = JsonNodeFactory.instance.objectNode().put("foo", "bar"); RawBytes raw = RawBytes.of(s.serialize(node)); byte[] serialized = s.serialize(raw); - RawBytes deserialized = s.deserialize(serialized, RawBytes.class, SerdeContext.EMPTY); + RawBytes deserialized = s.deserialize(serialized, RawBytes.class); assertThat(deserialized).isEqualTo(raw); } @@ -48,7 +48,7 @@ void rawBytesSerde(ContentType type) { void deserializeBaseDocumentWithNestedProperties(ContentType type) { InternalSerde s = new InternalSerdeProvider(type).create(); RawJson json = RawJson.of("{\"foo\":\"aaa\",\"properties\":{\"foo\":\"bbb\"}}"); - BaseDocument deserialized = s.deserialize(s.serialize(json), BaseDocument.class, SerdeContext.EMPTY); + BaseDocument deserialized = s.deserialize(s.serialize(json), BaseDocument.class); assertThat(deserialized.getAttribute("foo")).isEqualTo("aaa"); assertThat(deserialized.getAttribute("properties")) .isInstanceOf(Map.class) @@ -64,7 +64,7 @@ void serializeBaseDocumentWithNestedProperties(ContentType type) { doc.addAttribute("foo", "aaa"); doc.addAttribute("properties", Collections.singletonMap("foo", "bbb")); byte[] ser = s.serialize(doc); - ObjectNode on = s.deserializeUserData(ser, ObjectNode.class, SerdeContext.EMPTY); + ObjectNode on = s.deserializeUserData(ser, ObjectNode.class); assertThat(on.get("foo").textValue()).isEqualTo("aaa"); assertThat(on.get("properties").get("foo").textValue()).isEqualTo("bbb"); } diff --git a/vst/src/main/java/com/arangodb/vst/internal/VstConnectionAsync.java b/vst/src/main/java/com/arangodb/vst/internal/VstConnectionAsync.java index a3eb90498..8b74cbd57 100644 --- a/vst/src/main/java/com/arangodb/vst/internal/VstConnectionAsync.java +++ b/vst/src/main/java/com/arangodb/vst/internal/VstConnectionAsync.java @@ -26,7 +26,6 @@ import com.arangodb.internal.InternalResponse; import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.serde.InternalSerde; -import com.arangodb.serde.SerdeContext; import com.arangodb.velocypack.VPackSlice; import com.arangodb.velocypack.exception.VPackParserException; import com.arangodb.vst.internal.utils.CompletableFutureUtils; @@ -152,7 +151,7 @@ private Collection buildChunks(final Message message) { } private InternalResponse createResponse(final Message message) throws VPackParserException { - InternalResponse response = serde.deserialize(message.getHead().toByteArray(), InternalResponse.class, SerdeContext.EMPTY); + InternalResponse response = serde.deserialize(message.getHead().toByteArray(), InternalResponse.class); if (message.getBody() != null) { response.setBody(message.getBody().toByteArray()); } From 70af09e0688a5a7f37044ee8d1ecb0c0069a6587 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 8 Apr 2024 18:28:24 +0200 Subject: [PATCH 4/9] renamed SerdeContext to RequestContext --- .../arangodb/internal/ArangoExecutorAsync.java | 12 ++++++------ .../arangodb/internal/ArangoExecutorSync.java | 4 ++-- .../internal/serde/InternalSerdeImpl.java | 2 +- .../internal/serde/RequestContextHolder.java | 17 +++++++++++++++++ ...ContextImpl.java => RequestContextImpl.java} | 6 +++--- .../internal/serde/SerdeContextHolder.java | 17 ----------------- .../com/arangodb/internal/serde/SerdeUtils.java | 8 ++++---- .../java/com/arangodb/serde/ArangoSerde.java | 2 +- .../{SerdeContext.java => RequestContext.java} | 6 +++--- ...Test.java => JacksonRequestContextTest.java} | 6 +++--- ...ContextTest.java => RequestContextTest.java} | 8 ++++---- .../META-INF/native-image/reflect-config.json | 2 +- integration-tests/pom.xml | 2 +- .../arangodb/serde/jackson/JacksonSerde.java | 10 +++++----- .../jackson/internal/JacksonSerdeImpl.java | 6 +++--- 15 files changed, 54 insertions(+), 54 deletions(-) create mode 100644 core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java rename core/src/main/java/com/arangodb/internal/serde/{SerdeContextImpl.java => RequestContextImpl.java} (65%) delete mode 100644 core/src/main/java/com/arangodb/internal/serde/SerdeContextHolder.java rename core/src/main/java/com/arangodb/serde/{SerdeContext.java => RequestContext.java} (66%) rename driver/src/test/java/com/arangodb/{JacksonSerdeContextTest.java => JacksonRequestContextTest.java} (95%) rename driver/src/test/java/com/arangodb/{SerdeContextTest.java => RequestContextTest.java} (96%) diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java index 446309257..cd86a2172 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java @@ -24,9 +24,9 @@ import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.net.CommunicationProtocol; import com.arangodb.internal.net.HostHandle; -import com.arangodb.internal.serde.SerdeContextHolder; +import com.arangodb.internal.serde.RequestContextHolder; import com.arangodb.internal.serde.SerdeUtils; -import com.arangodb.serde.SerdeContext; +import com.arangodb.serde.RequestContext; import java.lang.reflect.Type; import java.util.concurrent.CompletableFuture; @@ -67,14 +67,14 @@ public CompletableFuture execute( .thenApply(Supplier::get) .thenCompose(request -> protocol .executeAsync(interceptRequest(request), hostHandle) - .thenApply(resp -> new ResponseWithRequest(resp, SerdeUtils.createSerdeContext(request))) + .thenApply(resp -> new ResponseWithRequest(resp, SerdeUtils.createRequestContext(request))) ) .handle((r, e) -> { if (e != null) { throw ArangoDBException.of(e); } else { interceptResponse(r.response); - SerdeContextHolder.INSTANCE.setCtx(r.context); + RequestContextHolder.INSTANCE.setCtx(r.context); return responseDeserializer.deserialize(r.response); } }); @@ -88,9 +88,9 @@ public CompletableFuture execute( private static class ResponseWithRequest { final InternalResponse response; - final SerdeContext context; + final RequestContext context; - ResponseWithRequest(InternalResponse response, SerdeContext context) { + ResponseWithRequest(InternalResponse response, RequestContext context) { this.response = response; this.context = context; } diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java index 9023e7f82..9add4cf6f 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java @@ -23,7 +23,7 @@ import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.net.CommunicationProtocol; import com.arangodb.internal.net.HostHandle; -import com.arangodb.internal.serde.SerdeContextHolder; +import com.arangodb.internal.serde.RequestContextHolder; import com.arangodb.internal.serde.SerdeUtils; import java.lang.reflect.Type; @@ -56,7 +56,7 @@ public T execute( final InternalResponse response = protocol.execute(interceptRequest(request), hostHandle); interceptResponse(response); - SerdeContextHolder.INSTANCE.setCtx(SerdeUtils.createSerdeContext(request)); + RequestContextHolder.INSTANCE.setCtx(SerdeUtils.createRequestContext(request)); return responseDeserializer.deserialize(response); } 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 3c5c4f013..c144afb3c 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -124,7 +124,7 @@ public T deserializeUserData(byte[] content, Class clazz) { if (isManagedClass(clazz)) { return deserialize(content, clazz); } else { - return userSerde.deserialize(content, clazz, SerdeContextHolder.INSTANCE.getCtx()); + return userSerde.deserialize(content, clazz, RequestContextHolder.INSTANCE.getCtx()); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java b/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java new file mode 100644 index 000000000..c31cc850d --- /dev/null +++ b/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java @@ -0,0 +1,17 @@ +package com.arangodb.internal.serde; + +import com.arangodb.serde.RequestContext; + +public enum RequestContextHolder { + INSTANCE; + + private final ThreadLocal ctx = ThreadLocal.withInitial(() -> RequestContext.EMPTY); + + public RequestContext getCtx() { + return ctx.get(); + } + + public void setCtx(RequestContext ctx) { + this.ctx.set(ctx != null ? ctx : RequestContext.EMPTY); + } +} diff --git a/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java b/core/src/main/java/com/arangodb/internal/serde/RequestContextImpl.java similarity index 65% rename from core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java rename to core/src/main/java/com/arangodb/internal/serde/RequestContextImpl.java index 5c47fe90f..f4213dcd4 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeContextImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/RequestContextImpl.java @@ -1,13 +1,13 @@ package com.arangodb.internal.serde; -import com.arangodb.serde.SerdeContext; +import com.arangodb.serde.RequestContext; import java.util.Optional; -public class SerdeContextImpl implements SerdeContext { +public class RequestContextImpl implements RequestContext { private final String streamTransactionId; - public SerdeContextImpl(String streamTransactionId) { + public RequestContextImpl(String streamTransactionId) { this.streamTransactionId = streamTransactionId; } diff --git a/core/src/main/java/com/arangodb/internal/serde/SerdeContextHolder.java b/core/src/main/java/com/arangodb/internal/serde/SerdeContextHolder.java deleted file mode 100644 index 1a29e256b..000000000 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeContextHolder.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.arangodb.internal.serde; - -import com.arangodb.serde.SerdeContext; - -public enum SerdeContextHolder { - INSTANCE; - - private final ThreadLocal ctx = ThreadLocal.withInitial(() -> SerdeContext.EMPTY); - - public SerdeContext getCtx() { - return ctx.get(); - } - - public void setCtx(SerdeContext ctx) { - this.ctx.set(ctx != null ? ctx : SerdeContext.EMPTY); - } -} 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 38985a953..c470d838f 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java @@ -2,7 +2,7 @@ import com.arangodb.ArangoDBException; import com.arangodb.internal.InternalRequest; -import com.arangodb.serde.SerdeContext; +import com.arangodb.serde.RequestContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; @@ -19,7 +19,7 @@ public enum SerdeUtils { INSTANCE; - public static final String SERDE_CONTEXT_ATTRIBUTE_NAME = "arangoSerdeContext"; + public static final String SERDE_CONTEXT_ATTRIBUTE_NAME = "arangoRequestContext"; private static final Logger LOGGER = LoggerFactory.getLogger(SerdeUtils.class); private static final String TRANSACTION_ID = "x-arango-trx-id"; @@ -59,8 +59,8 @@ static void checkSupportedJacksonVersion() { }); } - public static SerdeContext createSerdeContext(InternalRequest request) { - return new SerdeContextImpl(request.getHeaderParam().get(TRANSACTION_ID)); + public static RequestContext createRequestContext(InternalRequest request) { + return new RequestContextImpl(request.getHeaderParam().get(TRANSACTION_ID)); } /** diff --git a/core/src/main/java/com/arangodb/serde/ArangoSerde.java b/core/src/main/java/com/arangodb/serde/ArangoSerde.java index bec68395a..405152c65 100644 --- a/core/src/main/java/com/arangodb/serde/ArangoSerde.java +++ b/core/src/main/java/com/arangodb/serde/ArangoSerde.java @@ -43,7 +43,7 @@ public interface ArangoSerde { * @param ctx serde context, cannot be null * @return deserialized object */ - default T deserialize(byte[] content, Class clazz, SerdeContext ctx) { + default T deserialize(byte[] content, Class clazz, RequestContext ctx) { Objects.requireNonNull(ctx); return deserialize(content, clazz); } diff --git a/core/src/main/java/com/arangodb/serde/SerdeContext.java b/core/src/main/java/com/arangodb/serde/RequestContext.java similarity index 66% rename from core/src/main/java/com/arangodb/serde/SerdeContext.java rename to core/src/main/java/com/arangodb/serde/RequestContext.java index 79af9a6b1..ac7deb661 100644 --- a/core/src/main/java/com/arangodb/serde/SerdeContext.java +++ b/core/src/main/java/com/arangodb/serde/RequestContext.java @@ -1,15 +1,15 @@ package com.arangodb.serde; -import com.arangodb.internal.serde.SerdeContextImpl; +import com.arangodb.internal.serde.RequestContextImpl; import java.util.Optional; /** * Context holding information about the current request and response. */ -public interface SerdeContext { +public interface RequestContext { - SerdeContext EMPTY = new SerdeContextImpl(null); + RequestContext EMPTY = new RequestContextImpl(null); /** * @return the stream transaction id of the request (if any) or {@code null} diff --git a/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java b/driver/src/test/java/com/arangodb/JacksonRequestContextTest.java similarity index 95% rename from driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java rename to driver/src/test/java/com/arangodb/JacksonRequestContextTest.java index 5cc5152f2..a1152c402 100644 --- a/driver/src/test/java/com/arangodb/JacksonSerdeContextTest.java +++ b/driver/src/test/java/com/arangodb/JacksonRequestContextTest.java @@ -46,9 +46,9 @@ /** * @author Michele Rastelli */ -class JacksonSerdeContextTest { +class JacksonRequestContextTest { - private static final String COLLECTION_NAME = "JacksonSerdeContextTest_collection"; + private static final String COLLECTION_NAME = "JacksonRequestContextTest_collection"; private static ArangoDB arangoDB; private static ArangoDatabase db; @@ -92,7 +92,7 @@ static class PersonDeserializer extends JsonDeserializer { 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.getSerdeContext(ctx).getStreamTransactionId().get(); + person.txId = JacksonSerde.getRequestContext(ctx).getStreamTransactionId().get(); return person; } } diff --git a/driver/src/test/java/com/arangodb/SerdeContextTest.java b/driver/src/test/java/com/arangodb/RequestContextTest.java similarity index 96% rename from driver/src/test/java/com/arangodb/SerdeContextTest.java rename to driver/src/test/java/com/arangodb/RequestContextTest.java index bbfd7399a..7f1df597a 100644 --- a/driver/src/test/java/com/arangodb/SerdeContextTest.java +++ b/driver/src/test/java/com/arangodb/RequestContextTest.java @@ -27,7 +27,7 @@ import com.arangodb.model.DocumentReadOptions; import com.arangodb.model.StreamTransactionOptions; import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.SerdeContext; +import com.arangodb.serde.RequestContext; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -46,9 +46,9 @@ /** * @author Michele Rastelli */ -class SerdeContextTest { +class RequestContextTest { - private static final String COLLECTION_NAME = "SerdeContextTest_collection"; + private static final String COLLECTION_NAME = "RequestContextTest_collection"; private static ArangoDB arangoDB; private static ArangoDatabase db; @@ -72,7 +72,7 @@ public T deserialize(byte[] content, Class clazz) { } @Override - public T deserialize(byte[] content, Class clazz, SerdeContext ctx) { + public T deserialize(byte[] content, Class clazz, RequestContext ctx) { Objects.requireNonNull(ctx); if (clazz != Person.class) { diff --git a/driver/src/test/resources/META-INF/native-image/reflect-config.json b/driver/src/test/resources/META-INF/native-image/reflect-config.json index dcd3b8e61..cc3e412db 100644 --- a/driver/src/test/resources/META-INF/native-image/reflect-config.json +++ b/driver/src/test/resources/META-INF/native-image/reflect-config.json @@ -306,7 +306,7 @@ "allDeclaredClasses": true }, { - "name": "com.arangodb.SerdeContextTest$Person", + "name": "com.arangodb.RequestContextTest$Person", "allDeclaredFields": true, "allDeclaredMethods": true, "allDeclaredConstructors": true diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 91e110fc2..e2d50b336 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -188,7 +188,7 @@ **/SerdeTest.**, **/SerializableTest.**, **/JacksonInterferenceTest.**, - **/JacksonSerdeContextTest.** + **/JacksonRequestContextTest.** 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 d954f11d7..a3e46560e 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,7 +3,7 @@ import com.arangodb.ContentType; import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.SerdeContext; +import com.arangodb.serde.RequestContext; import com.arangodb.serde.jackson.internal.JacksonSerdeImpl; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.ObjectMapper; @@ -36,13 +36,13 @@ static JacksonSerde create(final ObjectMapper mapper) { } /** - * Extracts the {@link SerdeContext} from the current {@link DeserializationContext}. + * Extracts the {@link RequestContext} from the current {@link DeserializationContext}. * * @param ctx current Jackson {@link DeserializationContext} - * @return current {@link SerdeContext} + * @return current {@link RequestContext} */ - static SerdeContext getSerdeContext(DeserializationContext ctx) { - return (SerdeContext) ctx.getAttribute(SerdeUtils.SERDE_CONTEXT_ATTRIBUTE_NAME); + static RequestContext getRequestContext(DeserializationContext ctx) { + return (RequestContext) ctx.getAttribute(SerdeUtils.SERDE_CONTEXT_ATTRIBUTE_NAME); } /** 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 7bdb30709..1b95fd433 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 @@ -1,6 +1,6 @@ package com.arangodb.serde.jackson.internal; -import com.arangodb.serde.SerdeContext; +import com.arangodb.serde.RequestContext; import com.arangodb.serde.jackson.JacksonSerde; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -37,11 +37,11 @@ public byte[] serialize(final Object value) { @Override public T deserialize(final byte[] content, final Class type) { - return deserialize(content, type, SerdeContext.EMPTY); + return deserialize(content, type, RequestContext.EMPTY); } @Override - public T deserialize(byte[] content, Class type, SerdeContext ctx) { + public T deserialize(byte[] content, Class type, RequestContext ctx) { Objects.requireNonNull(ctx); try { return mapper.readerFor(mapper.constructType(type)) From 5aec5d7403eac385190d095c70084f8f2fc3cd6b Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 8 Apr 2024 18:54:42 +0200 Subject: [PATCH 5/9] RequestContextHolder.runWithCtx --- .../arangodb/internal/ArangoExecutorAsync.java | 4 ++-- .../com/arangodb/internal/ArangoExecutorSync.java | 4 ++-- .../internal/serde/RequestContextHolder.java | 15 +++++++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java index cd86a2172..6adf86dc3 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java @@ -74,8 +74,8 @@ public CompletableFuture execute( throw ArangoDBException.of(e); } else { interceptResponse(r.response); - RequestContextHolder.INSTANCE.setCtx(r.context); - return responseDeserializer.deserialize(r.response); + return RequestContextHolder.INSTANCE.runWithCtx(r.context, () -> + responseDeserializer.deserialize(r.response)); } }); diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java index 9add4cf6f..89f8c91fa 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java @@ -56,8 +56,8 @@ public T execute( final InternalResponse response = protocol.execute(interceptRequest(request), hostHandle); interceptResponse(response); - RequestContextHolder.INSTANCE.setCtx(SerdeUtils.createRequestContext(request)); - return responseDeserializer.deserialize(response); + return RequestContextHolder.INSTANCE.runWithCtx(SerdeUtils.createRequestContext(request), () -> + responseDeserializer.deserialize(response)); } } diff --git a/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java b/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java index c31cc850d..f8ed84680 100644 --- a/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java +++ b/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java @@ -2,16 +2,23 @@ import com.arangodb.serde.RequestContext; +import java.util.function.Supplier; + public enum RequestContextHolder { INSTANCE; private final ThreadLocal ctx = ThreadLocal.withInitial(() -> RequestContext.EMPTY); - public RequestContext getCtx() { - return ctx.get(); + public T runWithCtx(RequestContext ctx, Supplier fun) { + this.ctx.set(ctx != null ? ctx : RequestContext.EMPTY); + try { + return fun.get(); + } finally { + this.ctx.remove(); + } } - public void setCtx(RequestContext ctx) { - this.ctx.set(ctx != null ? ctx : RequestContext.EMPTY); + public RequestContext getCtx() { + return ctx.get(); } } From 3e3065a795889c964c236f27507d6e3409c45506 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 8 Apr 2024 22:31:07 +0200 Subject: [PATCH 6/9] changed RequestContext package --- .../arangodb/{serde => }/RequestContext.java | 4 ++-- .../internal/ArangoExecutorAsync.java | 6 ++--- .../arangodb/internal/ArangoExecutorSync.java | 4 +--- .../{serde => }/RequestContextHolder.java | 4 ++-- .../arangodb/internal/RequestContextImpl.java | 24 +++++++++++++++++++ .../internal/serde/InternalSerdeImpl.java | 1 + .../internal/serde/RequestContextImpl.java | 18 -------------- .../arangodb/internal/serde/SerdeUtils.java | 8 ------- .../java/com/arangodb/serde/ArangoSerde.java | 1 + .../java/com/arangodb/RequestContextTest.java | 1 - .../arangodb/serde/jackson/JacksonSerde.java | 7 +++--- .../jackson/internal/JacksonSerdeImpl.java | 4 ++-- 12 files changed, 39 insertions(+), 43 deletions(-) rename core/src/main/java/com/arangodb/{serde => }/RequestContext.java (80%) rename core/src/main/java/com/arangodb/internal/{serde => }/RequestContextHolder.java (86%) create mode 100644 core/src/main/java/com/arangodb/internal/RequestContextImpl.java delete mode 100644 core/src/main/java/com/arangodb/internal/serde/RequestContextImpl.java diff --git a/core/src/main/java/com/arangodb/serde/RequestContext.java b/core/src/main/java/com/arangodb/RequestContext.java similarity index 80% rename from core/src/main/java/com/arangodb/serde/RequestContext.java rename to core/src/main/java/com/arangodb/RequestContext.java index ac7deb661..cbc3052ad 100644 --- a/core/src/main/java/com/arangodb/serde/RequestContext.java +++ b/core/src/main/java/com/arangodb/RequestContext.java @@ -1,6 +1,6 @@ -package com.arangodb.serde; +package com.arangodb; -import com.arangodb.internal.serde.RequestContextImpl; +import com.arangodb.internal.RequestContextImpl; import java.util.Optional; diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java index 6adf86dc3..cb1f1c2f3 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorAsync.java @@ -24,9 +24,7 @@ import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.net.CommunicationProtocol; import com.arangodb.internal.net.HostHandle; -import com.arangodb.internal.serde.RequestContextHolder; -import com.arangodb.internal.serde.SerdeUtils; -import com.arangodb.serde.RequestContext; +import com.arangodb.RequestContext; import java.lang.reflect.Type; import java.util.concurrent.CompletableFuture; @@ -67,7 +65,7 @@ public CompletableFuture execute( .thenApply(Supplier::get) .thenCompose(request -> protocol .executeAsync(interceptRequest(request), hostHandle) - .thenApply(resp -> new ResponseWithRequest(resp, SerdeUtils.createRequestContext(request))) + .thenApply(resp -> new ResponseWithRequest(resp, new RequestContextImpl(request))) ) .handle((r, e) -> { if (e != null) { diff --git a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java index 89f8c91fa..dfd9f986c 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java +++ b/core/src/main/java/com/arangodb/internal/ArangoExecutorSync.java @@ -23,8 +23,6 @@ import com.arangodb.internal.config.ArangoConfig; import com.arangodb.internal.net.CommunicationProtocol; import com.arangodb.internal.net.HostHandle; -import com.arangodb.internal.serde.RequestContextHolder; -import com.arangodb.internal.serde.SerdeUtils; import java.lang.reflect.Type; @@ -56,7 +54,7 @@ public T execute( final InternalResponse response = protocol.execute(interceptRequest(request), hostHandle); interceptResponse(response); - return RequestContextHolder.INSTANCE.runWithCtx(SerdeUtils.createRequestContext(request), () -> + return RequestContextHolder.INSTANCE.runWithCtx(new RequestContextImpl(request), () -> responseDeserializer.deserialize(response)); } diff --git a/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java b/core/src/main/java/com/arangodb/internal/RequestContextHolder.java similarity index 86% rename from core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java rename to core/src/main/java/com/arangodb/internal/RequestContextHolder.java index f8ed84680..736148935 100644 --- a/core/src/main/java/com/arangodb/internal/serde/RequestContextHolder.java +++ b/core/src/main/java/com/arangodb/internal/RequestContextHolder.java @@ -1,6 +1,6 @@ -package com.arangodb.internal.serde; +package com.arangodb.internal; -import com.arangodb.serde.RequestContext; +import com.arangodb.RequestContext; import java.util.function.Supplier; diff --git a/core/src/main/java/com/arangodb/internal/RequestContextImpl.java b/core/src/main/java/com/arangodb/internal/RequestContextImpl.java new file mode 100644 index 000000000..2394db568 --- /dev/null +++ b/core/src/main/java/com/arangodb/internal/RequestContextImpl.java @@ -0,0 +1,24 @@ +package com.arangodb.internal; + +import com.arangodb.RequestContext; + +import java.util.Optional; + +public class RequestContextImpl implements RequestContext { + private static final String TRANSACTION_ID = "x-arango-trx-id"; + + private final String streamTransactionId; + + public RequestContextImpl() { + this.streamTransactionId = null; + } + + public RequestContextImpl(InternalRequest request) { + this.streamTransactionId = request.getHeaderParam().get(TRANSACTION_ID); + } + + @Override + public Optional getStreamTransactionId() { + return Optional.ofNullable(streamTransactionId); + } +} 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 c144afb3c..2e14c89b4 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java @@ -3,6 +3,7 @@ import com.arangodb.ArangoDBException; import com.arangodb.entity.BaseDocument; import com.arangodb.entity.BaseEdgeDocument; +import com.arangodb.internal.RequestContextHolder; import com.arangodb.serde.ArangoSerde; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; diff --git a/core/src/main/java/com/arangodb/internal/serde/RequestContextImpl.java b/core/src/main/java/com/arangodb/internal/serde/RequestContextImpl.java deleted file mode 100644 index f4213dcd4..000000000 --- a/core/src/main/java/com/arangodb/internal/serde/RequestContextImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.arangodb.internal.serde; - -import com.arangodb.serde.RequestContext; - -import java.util.Optional; - -public class RequestContextImpl implements RequestContext { - private final String streamTransactionId; - - public RequestContextImpl(String streamTransactionId) { - this.streamTransactionId = streamTransactionId; - } - - @Override - public Optional getStreamTransactionId() { - return Optional.ofNullable(streamTransactionId); - } -} 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 c470d838f..94b0659a6 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java @@ -1,8 +1,6 @@ package com.arangodb.internal.serde; import com.arangodb.ArangoDBException; -import com.arangodb.internal.InternalRequest; -import com.arangodb.serde.RequestContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; @@ -19,9 +17,7 @@ public enum SerdeUtils { INSTANCE; - public static final String SERDE_CONTEXT_ATTRIBUTE_NAME = "arangoRequestContext"; private static final Logger LOGGER = LoggerFactory.getLogger(SerdeUtils.class); - private static final String TRANSACTION_ID = "x-arango-trx-id"; private final ObjectMapper jsonMapper = new ObjectMapper(); @@ -59,10 +55,6 @@ static void checkSupportedJacksonVersion() { }); } - public static RequestContext createRequestContext(InternalRequest request) { - return new RequestContextImpl(request.getHeaderParam().get(TRANSACTION_ID)); - } - /** * Parse a JSON string. * diff --git a/core/src/main/java/com/arangodb/serde/ArangoSerde.java b/core/src/main/java/com/arangodb/serde/ArangoSerde.java index 405152c65..d7a4ff8e7 100644 --- a/core/src/main/java/com/arangodb/serde/ArangoSerde.java +++ b/core/src/main/java/com/arangodb/serde/ArangoSerde.java @@ -1,6 +1,7 @@ package com.arangodb.serde; import com.arangodb.ContentType; +import com.arangodb.RequestContext; import java.util.Objects; diff --git a/driver/src/test/java/com/arangodb/RequestContextTest.java b/driver/src/test/java/com/arangodb/RequestContextTest.java index 7f1df597a..730dea14d 100644 --- a/driver/src/test/java/com/arangodb/RequestContextTest.java +++ b/driver/src/test/java/com/arangodb/RequestContextTest.java @@ -27,7 +27,6 @@ import com.arangodb.model.DocumentReadOptions; import com.arangodb.model.StreamTransactionOptions; import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.RequestContext; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; 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 a3e46560e..8a749121e 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 @@ -1,15 +1,16 @@ package com.arangodb.serde.jackson; import com.arangodb.ContentType; -import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.serde.ArangoSerde; -import com.arangodb.serde.RequestContext; +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 static com.arangodb.serde.jackson.internal.JacksonSerdeImpl.SERDE_CONTEXT_ATTRIBUTE_NAME; + /** * User data serde based on Jackson Databind. Not shaded in arangodb-java-driver-shaded. */ @@ -42,7 +43,7 @@ static JacksonSerde create(final ObjectMapper mapper) { * @return current {@link RequestContext} */ static RequestContext getRequestContext(DeserializationContext ctx) { - return (RequestContext) ctx.getAttribute(SerdeUtils.SERDE_CONTEXT_ATTRIBUTE_NAME); + return (RequestContext) ctx.getAttribute(SERDE_CONTEXT_ATTRIBUTE_NAME); } /** 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 1b95fd433..9af416749 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 @@ -1,6 +1,6 @@ package com.arangodb.serde.jackson.internal; -import com.arangodb.serde.RequestContext; +import com.arangodb.RequestContext; import com.arangodb.serde.jackson.JacksonSerde; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -11,12 +11,12 @@ import java.util.Objects; import java.util.function.Consumer; -import static com.arangodb.internal.serde.SerdeUtils.SERDE_CONTEXT_ATTRIBUTE_NAME; /** * 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; From b42e9c18fc003b4e27a9d5b414538e0578000d02 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Tue, 9 Apr 2024 09:54:58 +0200 Subject: [PATCH 7/9] fixed RequestContext.EMPTY --- core/src/main/java/com/arangodb/RequestContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/arangodb/RequestContext.java b/core/src/main/java/com/arangodb/RequestContext.java index cbc3052ad..0ef8b61dc 100644 --- a/core/src/main/java/com/arangodb/RequestContext.java +++ b/core/src/main/java/com/arangodb/RequestContext.java @@ -9,7 +9,7 @@ */ public interface RequestContext { - RequestContext EMPTY = new RequestContextImpl(null); + RequestContext EMPTY = new RequestContextImpl(); /** * @return the stream transaction id of the request (if any) or {@code null} From 5f33f1630b6bbbe1962db6b6a7e26fa10ae96cef Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Wed, 10 Apr 2024 10:20:54 +0200 Subject: [PATCH 8/9] added RequestContextHolder safety checks --- .../arangodb/arch/NoRawTypesInspection.java | 1 + .../internal/RequestContextHolder.java | 31 ++++++++++++++++--- .../arangodb/internal/RequestContextImpl.java | 7 +++++ .../arangodb/ArangoCollectionAsyncTest.java | 4 ++- .../com/arangodb/ArangoCollectionTest.java | 4 ++- .../document/GetDocumentExampleTest.java | 5 ++- .../arangodb/serde/CustomSerdeAsyncTest.java | 7 +++-- .../com/arangodb/serde/CustomSerdeTest.java | 7 +++-- 8 files changed, 55 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/arangodb/arch/NoRawTypesInspection.java b/core/src/main/java/com/arangodb/arch/NoRawTypesInspection.java index c30f5ddcd..1031ca1c4 100644 --- a/core/src/main/java/com/arangodb/arch/NoRawTypesInspection.java +++ b/core/src/main/java/com/arangodb/arch/NoRawTypesInspection.java @@ -8,6 +8,7 @@ /** * Skip invoking {@code JavaType#getAllInvolvedRawTypes()} on the target class during arch tests. * Prevents StackOverflowError caused by this. + * FIXME: remove this when this is fixed and released */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.TYPE) diff --git a/core/src/main/java/com/arangodb/internal/RequestContextHolder.java b/core/src/main/java/com/arangodb/internal/RequestContextHolder.java index 736148935..eb549c450 100644 --- a/core/src/main/java/com/arangodb/internal/RequestContextHolder.java +++ b/core/src/main/java/com/arangodb/internal/RequestContextHolder.java @@ -1,24 +1,47 @@ package com.arangodb.internal; import com.arangodb.RequestContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.function.Supplier; public enum RequestContextHolder { INSTANCE; + private final static Logger LOGGER = LoggerFactory.getLogger(RequestContextHolder.class); + private final ThreadLocal ctx = ThreadLocal.withInitial(() -> RequestContext.EMPTY); + private final ThreadLocal runningWithinCtx = ThreadLocal.withInitial(() -> false); - public T runWithCtx(RequestContext ctx, Supplier fun) { - this.ctx.set(ctx != null ? ctx : RequestContext.EMPTY); + public T runWithCtx(RequestContext requestContext, Supplier fun) { try { + if (runningWithinCtx.get()) { + throw new IllegalStateException("re-entrant invocation is not supported"); + } + + runningWithinCtx.set(true); + + if (requestContext != null) { + LOGGER.debug("setting RequestContext: {}", requestContext); + ctx.set(requestContext); + } + return fun.get(); } finally { - this.ctx.remove(); + LOGGER.debug("removing RequestContext"); + ctx.remove(); + runningWithinCtx.remove(); } } public RequestContext getCtx() { - return ctx.get(); + 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/RequestContextImpl.java b/core/src/main/java/com/arangodb/internal/RequestContextImpl.java index 2394db568..dfd7e3a3e 100644 --- a/core/src/main/java/com/arangodb/internal/RequestContextImpl.java +++ b/core/src/main/java/com/arangodb/internal/RequestContextImpl.java @@ -21,4 +21,11 @@ public RequestContextImpl(InternalRequest request) { public Optional getStreamTransactionId() { return Optional.ofNullable(streamTransactionId); } + + @Override + public String toString() { + return "RequestContextImpl{" + + "streamTransactionId='" + streamTransactionId + '\'' + + '}'; + } } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 645f8e01c..d8ccbe0ed 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -21,6 +21,7 @@ package com.arangodb; import com.arangodb.entity.*; +import com.arangodb.internal.RequestContextHolder; import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.model.*; import com.arangodb.model.DocumentImportOptions.OnDuplicate; @@ -556,7 +557,8 @@ 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().deserializeUserData(createEntity.getNew().get(), Map.class); + Map newDoc = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> + collection.getSerde().deserializeUserData(createEntity.getNew().get(), Map.class)); assertThat(newDoc).containsAllEntriesOf(doc); } diff --git a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java index d4fd36123..2c4c9e318 100644 --- a/driver/src/test/java/com/arangodb/ArangoCollectionTest.java +++ b/driver/src/test/java/com/arangodb/ArangoCollectionTest.java @@ -21,6 +21,7 @@ package com.arangodb; import com.arangodb.entity.*; +import com.arangodb.internal.RequestContextHolder; import com.arangodb.internal.serde.SerdeUtils; import com.arangodb.model.*; import com.arangodb.model.DocumentImportOptions.OnDuplicate; @@ -559,7 +560,8 @@ void insertDocumentAsBytes(ArangoCollection collection) { assertThat(createEntity.getKey()).isEqualTo(key); assertThat(createEntity.getRev()).isNotNull(); assertThat(createEntity.getNew()).isNotNull().isInstanceOf(RawBytes.class); - Map newDoc = collection.getSerde().deserializeUserData(createEntity.getNew().get(), Map.class); + Map newDoc = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> + collection.getSerde().deserializeUserData(createEntity.getNew().get(), Map.class)); assertThat(newDoc).containsAllEntriesOf(doc); } diff --git a/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java b/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java index 8d220faab..2c22de165 100644 --- a/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java +++ b/driver/src/test/java/com/arangodb/example/document/GetDocumentExampleTest.java @@ -20,8 +20,10 @@ package com.arangodb.example.document; +import com.arangodb.RequestContext; import com.arangodb.entity.BaseDocument; import com.arangodb.example.ExampleBase; +import com.arangodb.internal.RequestContextHolder; import com.arangodb.util.RawBytes; import com.arangodb.util.RawJson; import com.fasterxml.jackson.databind.JsonNode; @@ -91,7 +93,8 @@ void getAsJson() { void getAsBytes() { final RawBytes doc = collection.getDocument(key, RawBytes.class); assertThat(doc.get()).isNotNull(); - Map mapDoc = collection.getSerde().deserializeUserData(doc.get(), Map.class); + Map mapDoc = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> + collection.getSerde().deserializeUserData(doc.get(), Map.class)); assertThat(mapDoc).containsEntry("foo", "bar"); } diff --git a/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java b/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java index cd649640c..1b5fb9d54 100644 --- a/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java +++ b/driver/src/test/java/com/arangodb/serde/CustomSerdeAsyncTest.java @@ -23,6 +23,7 @@ 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; @@ -112,7 +113,8 @@ void manualCustomPersonDeserializer() { person.name = "Joe"; InternalSerde serialization = arangoDB.getSerde(); byte[] serialized = serialization.serializeUserData(person); - Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class); + Person deserializedPerson = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> + serialization.deserializeUserData(serialized, Person.class)); assertThat(deserializedPerson.name).isEqualTo(PERSON_DESERIALIZER_ADDED_PREFIX + PERSON_SERIALIZER_ADDED_PREFIX + person.name); } @@ -208,7 +210,8 @@ void getDocument() throws ExecutionException, InterruptedException { @Test void parseNullString() { - final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class); + final String json = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> + arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class)); assertThat(json).isNull(); } diff --git a/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java b/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java index 292795d3e..bfdc37bd5 100644 --- a/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java +++ b/driver/src/test/java/com/arangodb/serde/CustomSerdeTest.java @@ -23,6 +23,7 @@ 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; @@ -109,7 +110,8 @@ void manualCustomPersonDeserializer() { person.name = "Joe"; InternalSerde serialization = arangoDB.getSerde(); byte[] serialized = serialization.serializeUserData(person); - Person deserializedPerson = serialization.deserializeUserData(serialized, Person.class); + Person deserializedPerson = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> + serialization.deserializeUserData(serialized, Person.class)); assertThat(deserializedPerson.name).isEqualTo(PERSON_DESERIALIZER_ADDED_PREFIX + PERSON_SERIALIZER_ADDED_PREFIX + person.name); } @@ -205,7 +207,8 @@ void getDocument() { @Test void parseNullString() { - final String json = arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class); + final String json = RequestContextHolder.INSTANCE.runWithCtx(RequestContext.EMPTY, () -> + arangoDB.getSerde().deserializeUserData(arangoDB.getSerde().serializeUserData(null), String.class)); assertThat(json).isNull(); } From 5af59b13442f55068b6aa20252e9948eafa6b4e4 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Wed, 10 Apr 2024 14:41:03 +0200 Subject: [PATCH 9/9] RequestContextHolder: support re-entrant invocations --- .../internal/RequestContextHolder.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/arangodb/internal/RequestContextHolder.java b/core/src/main/java/com/arangodb/internal/RequestContextHolder.java index eb549c450..bde22f031 100644 --- a/core/src/main/java/com/arangodb/internal/RequestContextHolder.java +++ b/core/src/main/java/com/arangodb/internal/RequestContextHolder.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Objects; import java.util.function.Supplier; public enum RequestContextHolder { @@ -11,27 +12,31 @@ public enum RequestContextHolder { private final static Logger LOGGER = LoggerFactory.getLogger(RequestContextHolder.class); - private final ThreadLocal ctx = ThreadLocal.withInitial(() -> RequestContext.EMPTY); 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()) { - throw new IllegalStateException("re-entrant invocation is not supported"); + // 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); - - if (requestContext != null) { - LOGGER.debug("setting RequestContext: {}", requestContext); - ctx.set(requestContext); - } - return fun.get(); } finally { - LOGGER.debug("removing RequestContext"); - ctx.remove(); - runningWithinCtx.remove(); + 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); + } } }