Skip to content

Commit

Permalink
added configuration parameter serdeProviderClass
Browse files Browse the repository at this point in the history
  • Loading branch information
rashtao committed Sep 5, 2024
1 parent 05c2358 commit 7a7ca8e
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 26 deletions.
13 changes: 13 additions & 0 deletions core/src/main/java/com/arangodb/ArangoDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.arangodb.internal.util.HostUtils;
import com.arangodb.model.*;
import com.arangodb.serde.ArangoSerde;
import com.arangodb.serde.ArangoSerdeProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -636,6 +637,18 @@ public Builder serde(final ArangoSerde serde) {
return this;
}

/**
* Sets the serde provider to be used to instantiate the user data serde.
* Ignored if {@link Builder#serde(ArangoSerde)} is used.
*
* @param serdeProviderClass class of the serde provider, it must have a public no-args constructor
* @return {@link ArangoDB.Builder}
*/
public Builder serdeProviderClass(final Class<? extends ArangoSerdeProvider> serdeProviderClass) {
config.setUserDataSerdeProvider(serdeProviderClass);
return this;
}

/**
* Sets the downstream async executor that will be used to consume the responses of the async API, that are returned
* as {@link java.util.concurrent.CompletableFuture}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ default Optional<Integer> getCompressionLevel() {
return Optional.empty();
}

default Optional<Boolean> getReuseVertx() {
default Optional<String> getSerdeProviderClass() {
return Optional.empty();
}

Expand Down
32 changes: 29 additions & 3 deletions core/src/main/java/com/arangodb/internal/config/ArangoConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.fasterxml.jackson.databind.Module;

import javax.net.ssl.SSLContext;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
Expand All @@ -40,6 +41,7 @@ public class ArangoConfig {
private LoadBalancingStrategy loadBalancingStrategy;
private InternalSerde internalSerde;
private ArangoSerde userDataSerde;
private Class<? extends ArangoSerdeProvider> serdeProviderClass;
private Integer responseQueueTimeSamples;
private Module protocolModule;
private Executor asyncExecutor;
Expand Down Expand Up @@ -81,6 +83,14 @@ public void loadProperties(final ArangoConfigProperties properties) {
compression = properties.getCompression().orElse(ArangoDefaults.DEFAULT_COMPRESSION);
compressionThreshold = properties.getCompressionThreshold().orElse(ArangoDefaults.DEFAULT_COMPRESSION_THRESHOLD);
compressionLevel = properties.getCompressionLevel().orElse(ArangoDefaults.DEFAULT_COMPRESSION_LEVEL);
serdeProviderClass = properties.getSerdeProviderClass().map((String className) -> {
try {
//noinspection unchecked
return (Class<? extends ArangoSerdeProvider>) Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}).orElse(null);
}

public List<HostDescription> getHosts() {
Expand Down Expand Up @@ -237,11 +247,23 @@ public void setLoadBalancingStrategy(LoadBalancingStrategy loadBalancingStrategy
this.loadBalancingStrategy = loadBalancingStrategy;
}

public Class<? extends ArangoSerdeProvider> getSerdeProviderClass() {
return serdeProviderClass;
}

public ArangoSerde getUserDataSerde() {
if (userDataSerde == null) {
userDataSerde = ArangoSerdeProvider.of(ContentTypeFactory.of(getProtocol())).create();
if (userDataSerde != null) {
return userDataSerde;
} else if (serdeProviderClass != null) {
try {
return serdeProviderClass.getDeclaredConstructor().newInstance().create();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
} else {
return ArangoSerdeProvider.of(ContentTypeFactory.of(getProtocol())).create();
}
return userDataSerde;
}

public InternalSerde getInternalSerde() {
Expand All @@ -255,6 +277,10 @@ public void setUserDataSerde(ArangoSerde userDataSerde) {
this.userDataSerde = userDataSerde;
}

public void setUserDataSerdeProvider(Class<? extends ArangoSerdeProvider> serdeProviderClass) {
this.serdeProviderClass = serdeProviderClass;
}

public Integer getResponseQueueTimeSamples() {
return responseQueueTimeSamples;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,9 @@ public Optional<Integer> getCompressionLevel() {
return Optional.ofNullable(getProperty("compressionLevel")).map(Integer::valueOf);
}

@Override
public Optional<String> getSerdeProviderClass() {
return Optional.ofNullable(getProperty("serdeProviderClass"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void ArangoConfigDefaultValues() {
assertThat(cfg.getCompressionThreshold()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION_THRESHOLD);
assertThat(cfg.getCompressionLevel()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION_LEVEL);
assertThat(cfg.getProtocolConfig()).isNull();
assertThat(cfg.getSerdeProviderClass()).isNull();
}

@Test
Expand Down
19 changes: 0 additions & 19 deletions test-functional/src/test/resources/arangodb-config-test.properties

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public final class ArangoConfigPropertiesMPImpl implements ArangoConfigPropertie
private Optional<Compression> compression;
private Optional<Integer> compressionThreshold;
private Optional<Integer> compressionLevel;
private Optional<String> serdeProviderClass;

@Override
public Optional<List<HostDescription>> getHosts() {
Expand Down Expand Up @@ -129,22 +130,27 @@ public Optional<Integer> getCompressionLevel() {
return compressionLevel;
}

@Override
public Optional<String> getSerdeProviderClass() {
return serdeProviderClass;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ArangoConfigPropertiesMPImpl that = (ArangoConfigPropertiesMPImpl) o;
return Objects.equals(hosts, that.hosts) && Objects.equals(protocol, that.protocol) && Objects.equals(user, that.user) && Objects.equals(password, that.password) && Objects.equals(jwt, that.jwt) && Objects.equals(timeout, that.timeout) && Objects.equals(useSsl, that.useSsl) && Objects.equals(verifyHost, that.verifyHost) && Objects.equals(chunkSize, that.chunkSize) && Objects.equals(maxConnections, that.maxConnections) && Objects.equals(connectionTtl, that.connectionTtl) && Objects.equals(keepAliveInterval, that.keepAliveInterval) && Objects.equals(acquireHostList, that.acquireHostList) && Objects.equals(acquireHostListInterval, that.acquireHostListInterval) && Objects.equals(loadBalancingStrategy, that.loadBalancingStrategy) && Objects.equals(responseQueueTimeSamples, that.responseQueueTimeSamples) && Objects.equals(compression, that.compression) && Objects.equals(compressionThreshold, that.compressionThreshold) && Objects.equals(compressionLevel, that.compressionLevel);
return Objects.equals(hosts, that.hosts) && Objects.equals(protocol, that.protocol) && Objects.equals(user, that.user) && Objects.equals(password, that.password) && Objects.equals(jwt, that.jwt) && Objects.equals(timeout, that.timeout) && Objects.equals(useSsl, that.useSsl) && Objects.equals(verifyHost, that.verifyHost) && Objects.equals(chunkSize, that.chunkSize) && Objects.equals(maxConnections, that.maxConnections) && Objects.equals(connectionTtl, that.connectionTtl) && Objects.equals(keepAliveInterval, that.keepAliveInterval) && Objects.equals(acquireHostList, that.acquireHostList) && Objects.equals(acquireHostListInterval, that.acquireHostListInterval) && Objects.equals(loadBalancingStrategy, that.loadBalancingStrategy) && Objects.equals(responseQueueTimeSamples, that.responseQueueTimeSamples) && Objects.equals(compression, that.compression) && Objects.equals(compressionThreshold, that.compressionThreshold) && Objects.equals(compressionLevel, that.compressionLevel) && Objects.equals(serdeProviderClass, that.serdeProviderClass);
}

@Override
public int hashCode() {
return Objects.hash(hosts, protocol, user, password, jwt, timeout, useSsl, verifyHost, chunkSize, maxConnections, connectionTtl, keepAliveInterval, acquireHostList, acquireHostListInterval, loadBalancingStrategy, responseQueueTimeSamples, compression, compressionThreshold, compressionLevel);
return Objects.hash(hosts, protocol, user, password, jwt, timeout, useSsl, verifyHost, chunkSize, maxConnections, connectionTtl, keepAliveInterval, acquireHostList, acquireHostListInterval, loadBalancingStrategy, responseQueueTimeSamples, compression, compressionThreshold, compressionLevel, serdeProviderClass);
}

@Override
public String toString() {
return "ArangoConfigPropertiesImpl{" +
return "ArangoConfigPropertiesMPImpl{" +
"hosts=" + hosts +
", protocol=" + protocol +
", user=" + user +
Expand All @@ -164,6 +170,7 @@ public String toString() {
", compression=" + compression +
", compressionThreshold=" + compressionThreshold +
", compressionLevel=" + compressionLevel +
", serdeProviderClass=" + serdeProviderClass +
'}';
}
}
2 changes: 2 additions & 0 deletions test-non-functional/src/test/java/mp/ConfigMPTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ConfigMPTest {
private final Compression compression = Compression.GZIP;
private final Integer compressionThreshold = 123456789;
private final Integer compressionLevel = 9;
private final String serdeProviderClass = "com.arangodb.serde.jsonb.JsonbSerdeProvider";

@Test
void readConfig() {
Expand Down Expand Up @@ -73,5 +74,6 @@ private void checkResult(ArangoConfigProperties config) {
assertThat(config.getCompression()).hasValue(compression);
assertThat(config.getCompressionThreshold()).hasValue(compressionThreshold);
assertThat(config.getCompressionLevel()).hasValue(compressionLevel);
assertThat(config.getSerdeProviderClass()).isPresent().hasValue(serdeProviderClass);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package serde;

import com.arangodb.ArangoDB;
import com.arangodb.config.ArangoConfigProperties;
import com.arangodb.serde.ArangoSerde;
import com.arangodb.serde.jackson.internal.JacksonSerdeImpl;
import com.arangodb.serde.jackson.json.JacksonJsonSerdeProvider;
import com.arangodb.serde.jackson.vpack.JacksonVPackSerdeProvider;
import com.arangodb.serde.jsonb.JsonbSerde;
import com.arangodb.serde.jsonb.JsonbSerdeProvider;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;

import static org.assertj.core.api.Assertions.assertThat;

public class SerdeConfigurationTest {
private final VarHandle JACKSON_SERDE_IMPL_MAPPER;
{
try {
JACKSON_SERDE_IMPL_MAPPER = MethodHandles
.privateLookupIn(JacksonSerdeImpl.class, MethodHandles.lookup())
.findVarHandle(JacksonSerdeImpl.class, "mapper", ObjectMapper.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}

@Test
void vpackSerdeProvider() {
ArangoDB adb = new ArangoDB.Builder()
.host("foo", 1111)
.serdeProviderClass(JacksonVPackSerdeProvider.class)
.build();

ArangoSerde serde = adb.getSerde().getUserSerde();
assertThat(serde).isInstanceOf(JacksonSerdeImpl.class);

ObjectMapper mapper = (ObjectMapper) JACKSON_SERDE_IMPL_MAPPER.get(serde);
assertThat(mapper.getFactory().getFormatName()).isEqualTo("Velocypack");
}

@Test
void jsonSerdeProvider() {
ArangoDB adb = new ArangoDB.Builder()
.host("foo", 1111)
.serdeProviderClass(JacksonJsonSerdeProvider.class)
.build();

ArangoSerde serde = adb.getSerde().getUserSerde();
assertThat(serde).isInstanceOf(JacksonSerdeImpl.class);

ObjectMapper mapper = (ObjectMapper) JACKSON_SERDE_IMPL_MAPPER.get(serde);
assertThat(mapper.getFactory().getFormatName()).isEqualTo("JSON");
}


@Test
void jsonBSerdeProvider() {
ArangoDB adb = new ArangoDB.Builder()
.host("foo", 1111)
.serdeProviderClass(JsonbSerdeProvider.class)
.build();

ArangoSerde serde = adb.getSerde().getUserSerde();
assertThat(serde).isInstanceOf(JsonbSerde.class);
}

@Test
void jsonBSerdeProviderFromConfigFile() {
ArangoDB adb = new ArangoDB.Builder()
.loadProperties(ArangoConfigProperties.fromFile("arangodb-serde-provider.properties"))
.build();

ArangoSerde serde = adb.getSerde().getUserSerde();
assertThat(serde).isInstanceOf(JsonbSerde.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ adb.responseQueueTimeSamples=12345678
adb.compression=GZIP
adb.compressionThreshold=123456789
adb.compressionLevel=9
adb.serdeProviderClass=com.arangodb.serde.jsonb.JsonbSerdeProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
arangodb.hosts=172.28.0.1:8529
arangodb.password=test
arangodb.serdeProviderClass=com.arangodb.serde.jsonb.JsonbSerdeProvider

0 comments on commit 7a7ca8e

Please sign in to comment.