Skip to content

[DE-771] Refactoring serde context #555

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions core/src/main/java/com/arangodb/RequestContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.arangodb;

import com.arangodb.internal.RequestContextImpl;

import java.util.Optional;

/**
* Context holding information about the current request and response.
*/
public interface RequestContext {

RequestContext EMPTY = new RequestContextImpl();

/**
* @return the stream transaction id of the request (if any) or {@code null}
*/
Optional<String> getStreamTransactionId();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/**
* Skip invoking {@code JavaType#getAllInvolvedRawTypes()} on the target class during arch tests.
* Prevents StackOverflowError caused by <a href="https://github.com/TNG/ArchUnit/issues/1237">this</a>.
* FIXME: remove this when <a href="https://github.com/TNG/ArchUnit/issues/1237">this</a> is fixed and released
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
Expand Down
7 changes: 3 additions & 4 deletions core/src/main/java/com/arangodb/internal/ArangoExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -59,8 +58,8 @@ public void setJwt(String jwt) {
protocol.setJwt(jwt);
}

protected <T> T createResult(final Type type, final InternalResponse response, final SerdeContext ctx) {
return serde.deserialize(response.getBody(), type, ctx);
protected <T> T createResult(final Type type, final InternalResponse response) {
return serde.deserialize(response.getBody(), type);
}

protected final void interceptResponse(InternalResponse response) {
Expand All @@ -80,6 +79,6 @@ public QueueTimeMetrics getQueueTimeMetrics() {
}

public interface ResponseDeserializer<T> {
T deserialize(InternalResponse response, SerdeContext ctx);
T deserialize(InternalResponse response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +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.SerdeUtils;
import com.arangodb.serde.SerdeContext;
import com.arangodb.RequestContext;

import java.lang.reflect.Type;
import java.util.concurrent.CompletableFuture;
Expand All @@ -50,7 +49,7 @@ public <T> CompletableFuture<T> execute(final Supplier<InternalRequest> requestS
}

public <T> CompletableFuture<T> execute(final Supplier<InternalRequest> 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 <T> CompletableFuture<T> execute(final Supplier<InternalRequest> requestSupplier, final ResponseDeserializer<T> responseDeserializer) {
Expand All @@ -66,14 +65,15 @@ public <T> CompletableFuture<T> execute(
.thenApply(Supplier::get)
.thenCompose(request -> protocol
.executeAsync(interceptRequest(request), hostHandle)
.thenApply(resp -> new ResponseWithContext(resp, SerdeUtils.createSerdeContext(request)))
.thenApply(resp -> new ResponseWithRequest(resp, new RequestContextImpl(request)))
)
.handle((r, e) -> {
if (e != null) {
throw ArangoDBException.of(e);
} else {
interceptResponse(r.response);
return responseDeserializer.deserialize(r.response, r.context);
return RequestContextHolder.INSTANCE.runWithCtx(r.context, () ->
responseDeserializer.deserialize(r.response));
}
});

Expand All @@ -84,15 +84,14 @@ public <T> CompletableFuture<T> execute(
}
}

private static class ResponseWithContext {
private static class ResponseWithRequest {
final InternalResponse response;
final SerdeContext context;
final RequestContext context;

ResponseWithContext(InternalResponse response, SerdeContext context) {
ResponseWithRequest(InternalResponse response, RequestContext context) {
this.response = response;
this.context = context;
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +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.SerdeUtils;

import java.lang.reflect.Type;

Expand All @@ -41,7 +40,7 @@ public <T> T execute(final InternalRequest request, final Type type) {
}

public <T> 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> T execute(final InternalRequest request, final ResponseDeserializer<T> responseDeserializer) {
Expand All @@ -55,7 +54,8 @@ public <T> T execute(

final InternalResponse response = protocol.execute(interceptRequest(request), hostHandle);
interceptResponse(response);
return responseDeserializer.deserialize(response, SerdeUtils.createSerdeContext(request));
return RequestContextHolder.INSTANCE.runWithCtx(new RequestContextImpl(request), () ->
responseDeserializer.deserialize(response));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private InternalRequest createInsertDocumentRequest(final DocumentCreateOptions
}

protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentCreateEntity<T>>> insertDocumentsResponseDeserializer(Class<T> userDataClass) {
return (response, ctx) -> {
return (response) -> {
final MultiDocumentEntity<DocumentCreateEntity<T>> multiDocument = new MultiDocumentEntity<>();
final List<DocumentCreateEntity<T>> docs = new ArrayList<>();
final List<ErrorEntity> errors = new ArrayList<>();
Expand All @@ -119,12 +119,12 @@ protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentCreateEntity<T>>>
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<T> doc = getSerde().deserialize(next, type, ctx);
final DocumentCreateEntity<T> doc = getSerde().deserialize(next, type);
docs.add(doc);
documentsAndErrors.add(doc);
}
Expand Down Expand Up @@ -168,7 +168,7 @@ protected InternalRequest getDocumentRequest(final String key, final DocumentRea
}

protected <T> ResponseDeserializer<T> getDocumentResponseDeserializer(final Class<T> type) {
return (response, ctx) -> getSerde().deserializeUserData(response.getBody(), type, ctx);
return (response) -> getSerde().deserializeUserData(response.getBody(), type);
}

protected InternalRequest getDocumentsRequest(final Iterable<String> keys, final DocumentReadOptions options) {
Expand All @@ -186,7 +186,7 @@ protected InternalRequest getDocumentsRequest(final Iterable<String> keys, final

protected <T> ResponseDeserializer<MultiDocumentEntity<T>> getDocumentsResponseDeserializer(
final Class<T> type) {
return (response, ctx) -> {
return (response) -> {
final MultiDocumentEntity<T> multiDocument = new MultiDocumentEntity<>();
boolean potentialDirtyRead = Boolean.parseBoolean(response.getMeta("X-Arango-Potential-Dirty-Read"));
multiDocument.setPotentialDirtyRead(potentialDirtyRead);
Expand All @@ -197,11 +197,11 @@ protected <T> ResponseDeserializer<MultiDocumentEntity<T>> 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);
}
Expand Down Expand Up @@ -249,7 +249,7 @@ private InternalRequest createReplaceDocumentRequest(final DocumentReplaceOption

protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentUpdateEntity<T>>> replaceDocumentsResponseDeserializer(
final Class<T> returnType) {
return (response, ctx) -> {
return (response) -> {
final MultiDocumentEntity<DocumentUpdateEntity<T>> multiDocument = new MultiDocumentEntity<>();
final List<DocumentUpdateEntity<T>> docs = new ArrayList<>();
final List<ErrorEntity> errors = new ArrayList<>();
Expand All @@ -258,12 +258,12 @@ protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentUpdateEntity<T>>>
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<T> doc = getSerde().deserialize(next, type, ctx);
final DocumentUpdateEntity<T> doc = getSerde().deserialize(next, type);
docs.add(doc);
documentsAndErrors.add(doc);
}
Expand Down Expand Up @@ -312,7 +312,7 @@ private InternalRequest createUpdateDocumentRequest(final DocumentUpdateOptions

protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentUpdateEntity<T>>> updateDocumentsResponseDeserializer(
final Class<T> returnType) {
return (response, ctx) -> {
return (response) -> {
final MultiDocumentEntity<DocumentUpdateEntity<T>> multiDocument = new MultiDocumentEntity<>();
final List<DocumentUpdateEntity<T>> docs = new ArrayList<>();
final List<ErrorEntity> errors = new ArrayList<>();
Expand All @@ -321,12 +321,12 @@ protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentUpdateEntity<T>>>
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<T> doc = getSerde().deserialize(next, type, ctx);
final DocumentUpdateEntity<T> doc = getSerde().deserialize(next, type);
docs.add(doc);
documentsAndErrors.add(doc);
}
Expand Down Expand Up @@ -368,7 +368,7 @@ private InternalRequest createDeleteDocumentRequest(final DocumentDeleteOptions

protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentDeleteEntity<T>>> deleteDocumentsResponseDeserializer(
final Class<T> userDataClass) {
return (response, ctx) -> {
return (response) -> {
final MultiDocumentEntity<DocumentDeleteEntity<T>> multiDocument = new MultiDocumentEntity<>();
final List<DocumentDeleteEntity<T>> docs = new ArrayList<>();
final List<ErrorEntity> errors = new ArrayList<>();
Expand All @@ -377,12 +377,12 @@ protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentDeleteEntity<T>>>
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<T> doc = getSerde().deserialize(next, type, ctx);
final DocumentDeleteEntity<T> doc = getSerde().deserialize(next, type);
docs.add(doc);
documentsAndErrors.add(doc);
}
Expand Down Expand Up @@ -413,7 +413,7 @@ protected InternalRequest deleteIndexRequest(final String id) {
}

protected ResponseDeserializer<String> 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) {
Expand Down Expand Up @@ -495,23 +495,23 @@ protected InternalRequest getIndexesRequest() {
}

protected ResponseDeserializer<Collection<IndexEntity>> getIndexesResponseDeserializer() {
return (response, ctx) -> {
return (response) -> {
Collection<IndexEntity> 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;
};
}

protected ResponseDeserializer<Collection<InvertedIndexEntity>> getInvertedIndexesResponseDeserializer() {
return (response, ctx) -> {
return (response) -> {
Collection<InvertedIndexEntity> 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;
Expand Down Expand Up @@ -583,8 +583,8 @@ protected InternalRequest getPermissionsRequest(final String user) {
}

protected ResponseDeserializer<Permissions> 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);
}

}
22 changes: 11 additions & 11 deletions core/src/main/java/com/arangodb/internal/InternalArangoDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ protected InternalRequest getServerIdRequest() {
}

protected ResponseDeserializer<ServerRole> getRoleResponseDeserializer() {
return (response, ctx) -> getSerde().deserialize(response.getBody(), "/role", ServerRole.class, ctx);
return (response) -> getSerde().deserialize(response.getBody(), "/role", ServerRole.class);
}

protected ResponseDeserializer<String> 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) {
Expand All @@ -81,25 +81,25 @@ protected InternalRequest createDatabaseRequest(final DBCreateOptions options) {
}

protected ResponseDeserializer<Boolean> 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) {
return request(dbName, RequestType.GET, InternalArangoDatabase.PATH_API_DATABASE);
}

protected ResponseDeserializer<Collection<String>> 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) {
return request(dbName, RequestType.GET, PATH_API_USER, user, ArangoRequestParam.DATABASE);
}

protected ResponseDeserializer<Collection<String>> getAccessibleDatabasesForResponseDeserializer() {
return (response, ctx) -> {
return (response) -> {
Iterator<String> names =
getSerde().parse(response.getBody(), ArangoResponseField.RESULT_JSON_POINTER).fieldNames();
final Collection<String> dbs = new ArrayList<>();
Expand Down Expand Up @@ -136,8 +136,8 @@ protected InternalRequest getUserRequest(final String dbName, final String user)
}

protected ResponseDeserializer<Collection<UserEntity>> 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) {
Expand Down Expand Up @@ -173,10 +173,10 @@ protected InternalRequest executeRequest(final Request<?> request) {
}

protected <T> ResponseDeserializer<Response<T>> responseDeserializer(Class<T> 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)
);
}

Expand Down
Loading
Loading