Skip to content

Commit f01c53b

Browse files
authored
added serdeProviderClass configuration property (#575)
1 parent 05c2358 commit f01c53b

File tree

11 files changed

+146
-26
lines changed

11 files changed

+146
-26
lines changed

Diff for: core/src/main/java/com/arangodb/ArangoDB.java

+13
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.arangodb.internal.util.HostUtils;
3333
import com.arangodb.model.*;
3434
import com.arangodb.serde.ArangoSerde;
35+
import com.arangodb.serde.ArangoSerdeProvider;
3536
import org.slf4j.Logger;
3637
import org.slf4j.LoggerFactory;
3738

@@ -636,6 +637,18 @@ public Builder serde(final ArangoSerde serde) {
636637
return this;
637638
}
638639

640+
/**
641+
* Sets the serde provider to be used to instantiate the user data serde.
642+
* Ignored if {@link Builder#serde(ArangoSerde)} is used.
643+
*
644+
* @param serdeProviderClass class of the serde provider, it must have a public no-args constructor
645+
* @return {@link ArangoDB.Builder}
646+
*/
647+
public Builder serdeProviderClass(final Class<? extends ArangoSerdeProvider> serdeProviderClass) {
648+
config.setUserDataSerdeProvider(serdeProviderClass);
649+
return this;
650+
}
651+
639652
/**
640653
* Sets the downstream async executor that will be used to consume the responses of the async API, that are returned
641654
* as {@link java.util.concurrent.CompletableFuture}

Diff for: core/src/main/java/com/arangodb/config/ArangoConfigProperties.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ default Optional<Integer> getCompressionLevel() {
110110
return Optional.empty();
111111
}
112112

113-
default Optional<Boolean> getReuseVertx() {
113+
default Optional<String> getSerdeProviderClass() {
114114
return Optional.empty();
115115
}
116116

Diff for: core/src/main/java/com/arangodb/internal/config/ArangoConfig.java

+29-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.fasterxml.jackson.databind.Module;
1717

1818
import javax.net.ssl.SSLContext;
19+
import java.lang.reflect.InvocationTargetException;
1920
import java.util.*;
2021
import java.util.concurrent.Executor;
2122
import java.util.stream.Collectors;
@@ -40,6 +41,7 @@ public class ArangoConfig {
4041
private LoadBalancingStrategy loadBalancingStrategy;
4142
private InternalSerde internalSerde;
4243
private ArangoSerde userDataSerde;
44+
private Class<? extends ArangoSerdeProvider> serdeProviderClass;
4345
private Integer responseQueueTimeSamples;
4446
private Module protocolModule;
4547
private Executor asyncExecutor;
@@ -81,6 +83,14 @@ public void loadProperties(final ArangoConfigProperties properties) {
8183
compression = properties.getCompression().orElse(ArangoDefaults.DEFAULT_COMPRESSION);
8284
compressionThreshold = properties.getCompressionThreshold().orElse(ArangoDefaults.DEFAULT_COMPRESSION_THRESHOLD);
8385
compressionLevel = properties.getCompressionLevel().orElse(ArangoDefaults.DEFAULT_COMPRESSION_LEVEL);
86+
serdeProviderClass = properties.getSerdeProviderClass().map((String className) -> {
87+
try {
88+
//noinspection unchecked
89+
return (Class<? extends ArangoSerdeProvider>) Class.forName(className);
90+
} catch (ClassNotFoundException e) {
91+
throw new RuntimeException(e);
92+
}
93+
}).orElse(null);
8494
}
8595

8696
public List<HostDescription> getHosts() {
@@ -237,11 +247,23 @@ public void setLoadBalancingStrategy(LoadBalancingStrategy loadBalancingStrategy
237247
this.loadBalancingStrategy = loadBalancingStrategy;
238248
}
239249

250+
public Class<? extends ArangoSerdeProvider> getSerdeProviderClass() {
251+
return serdeProviderClass;
252+
}
253+
240254
public ArangoSerde getUserDataSerde() {
241-
if (userDataSerde == null) {
242-
userDataSerde = ArangoSerdeProvider.of(ContentTypeFactory.of(getProtocol())).create();
255+
if (userDataSerde != null) {
256+
return userDataSerde;
257+
} else if (serdeProviderClass != null) {
258+
try {
259+
return serdeProviderClass.getDeclaredConstructor().newInstance().create();
260+
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
261+
NoSuchMethodException e) {
262+
throw new RuntimeException(e);
263+
}
264+
} else {
265+
return ArangoSerdeProvider.of(ContentTypeFactory.of(getProtocol())).create();
243266
}
244-
return userDataSerde;
245267
}
246268

247269
public InternalSerde getInternalSerde() {
@@ -255,6 +277,10 @@ public void setUserDataSerde(ArangoSerde userDataSerde) {
255277
this.userDataSerde = userDataSerde;
256278
}
257279

280+
public void setUserDataSerdeProvider(Class<? extends ArangoSerdeProvider> serdeProviderClass) {
281+
this.serdeProviderClass = serdeProviderClass;
282+
}
283+
258284
public Integer getResponseQueueTimeSamples() {
259285
return responseQueueTimeSamples;
260286
}

Diff for: core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java

+5
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,9 @@ public Optional<Integer> getCompressionLevel() {
161161
return Optional.ofNullable(getProperty("compressionLevel")).map(Integer::valueOf);
162162
}
163163

164+
@Override
165+
public Optional<String> getSerdeProviderClass() {
166+
return Optional.ofNullable(getProperty("serdeProviderClass"));
167+
}
168+
164169
}

Diff for: test-functional/src/test/java/com/arangodb/ArangoConfigTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void ArangoConfigDefaultValues() {
3333
assertThat(cfg.getCompressionThreshold()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION_THRESHOLD);
3434
assertThat(cfg.getCompressionLevel()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION_LEVEL);
3535
assertThat(cfg.getProtocolConfig()).isNull();
36+
assertThat(cfg.getSerdeProviderClass()).isNull();
3637
}
3738

3839
@Test

Diff for: test-functional/src/test/resources/arangodb-config-test.properties

-19
This file was deleted.

Diff for: test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public final class ArangoConfigPropertiesMPImpl implements ArangoConfigPropertie
3333
private Optional<Compression> compression;
3434
private Optional<Integer> compressionThreshold;
3535
private Optional<Integer> compressionLevel;
36+
private Optional<String> serdeProviderClass;
3637

3738
@Override
3839
public Optional<List<HostDescription>> getHosts() {
@@ -129,22 +130,27 @@ public Optional<Integer> getCompressionLevel() {
129130
return compressionLevel;
130131
}
131132

133+
@Override
134+
public Optional<String> getSerdeProviderClass() {
135+
return serdeProviderClass;
136+
}
137+
132138
@Override
133139
public boolean equals(Object o) {
134140
if (this == o) return true;
135141
if (o == null || getClass() != o.getClass()) return false;
136142
ArangoConfigPropertiesMPImpl that = (ArangoConfigPropertiesMPImpl) o;
137-
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);
143+
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);
138144
}
139145

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

145151
@Override
146152
public String toString() {
147-
return "ArangoConfigPropertiesImpl{" +
153+
return "ArangoConfigPropertiesMPImpl{" +
148154
"hosts=" + hosts +
149155
", protocol=" + protocol +
150156
", user=" + user +
@@ -164,6 +170,7 @@ public String toString() {
164170
", compression=" + compression +
165171
", compressionThreshold=" + compressionThreshold +
166172
", compressionLevel=" + compressionLevel +
173+
", serdeProviderClass=" + serdeProviderClass +
167174
'}';
168175
}
169176
}

Diff for: test-non-functional/src/test/java/mp/ConfigMPTest.java

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class ConfigMPTest {
3333
private final Compression compression = Compression.GZIP;
3434
private final Integer compressionThreshold = 123456789;
3535
private final Integer compressionLevel = 9;
36+
private final String serdeProviderClass = "com.arangodb.serde.jsonb.JsonbSerdeProvider";
3637

3738
@Test
3839
void readConfig() {
@@ -73,5 +74,6 @@ private void checkResult(ArangoConfigProperties config) {
7374
assertThat(config.getCompression()).hasValue(compression);
7475
assertThat(config.getCompressionThreshold()).hasValue(compressionThreshold);
7576
assertThat(config.getCompressionLevel()).hasValue(compressionLevel);
77+
assertThat(config.getSerdeProviderClass()).isPresent().hasValue(serdeProviderClass);
7678
}
7779
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package serde;
2+
3+
import com.arangodb.ArangoDB;
4+
import com.arangodb.config.ArangoConfigProperties;
5+
import com.arangodb.serde.ArangoSerde;
6+
import com.arangodb.serde.jackson.internal.JacksonSerdeImpl;
7+
import com.arangodb.serde.jackson.json.JacksonJsonSerdeProvider;
8+
import com.arangodb.serde.jackson.vpack.JacksonVPackSerdeProvider;
9+
import com.arangodb.serde.jsonb.JsonbSerde;
10+
import com.arangodb.serde.jsonb.JsonbSerdeProvider;
11+
import com.fasterxml.jackson.databind.ObjectMapper;
12+
import org.junit.jupiter.api.Test;
13+
14+
import java.lang.invoke.MethodHandles;
15+
import java.lang.invoke.VarHandle;
16+
17+
import static org.assertj.core.api.Assertions.assertThat;
18+
19+
public class SerdeConfigurationTest {
20+
private final VarHandle JACKSON_SERDE_IMPL_MAPPER;
21+
{
22+
try {
23+
JACKSON_SERDE_IMPL_MAPPER = MethodHandles
24+
.privateLookupIn(JacksonSerdeImpl.class, MethodHandles.lookup())
25+
.findVarHandle(JacksonSerdeImpl.class, "mapper", ObjectMapper.class);
26+
} catch (NoSuchFieldException | IllegalAccessException e) {
27+
throw new RuntimeException(e);
28+
}
29+
}
30+
31+
@Test
32+
void vpackSerdeProvider() {
33+
ArangoDB adb = new ArangoDB.Builder()
34+
.host("foo", 1111)
35+
.serdeProviderClass(JacksonVPackSerdeProvider.class)
36+
.build();
37+
38+
ArangoSerde serde = adb.getSerde().getUserSerde();
39+
assertThat(serde).isInstanceOf(JacksonSerdeImpl.class);
40+
41+
ObjectMapper mapper = (ObjectMapper) JACKSON_SERDE_IMPL_MAPPER.get(serde);
42+
assertThat(mapper.getFactory().getFormatName()).isEqualTo("Velocypack");
43+
}
44+
45+
@Test
46+
void jsonSerdeProvider() {
47+
ArangoDB adb = new ArangoDB.Builder()
48+
.host("foo", 1111)
49+
.serdeProviderClass(JacksonJsonSerdeProvider.class)
50+
.build();
51+
52+
ArangoSerde serde = adb.getSerde().getUserSerde();
53+
assertThat(serde).isInstanceOf(JacksonSerdeImpl.class);
54+
55+
ObjectMapper mapper = (ObjectMapper) JACKSON_SERDE_IMPL_MAPPER.get(serde);
56+
assertThat(mapper.getFactory().getFormatName()).isEqualTo("JSON");
57+
}
58+
59+
60+
@Test
61+
void jsonBSerdeProvider() {
62+
ArangoDB adb = new ArangoDB.Builder()
63+
.host("foo", 1111)
64+
.serdeProviderClass(JsonbSerdeProvider.class)
65+
.build();
66+
67+
ArangoSerde serde = adb.getSerde().getUserSerde();
68+
assertThat(serde).isInstanceOf(JsonbSerde.class);
69+
}
70+
71+
@Test
72+
void jsonBSerdeProviderFromConfigFile() {
73+
ArangoDB adb = new ArangoDB.Builder()
74+
.loadProperties(ArangoConfigProperties.fromFile("arangodb-serde-provider.properties"))
75+
.build();
76+
77+
ArangoSerde serde = adb.getSerde().getUserSerde();
78+
assertThat(serde).isInstanceOf(JsonbSerde.class);
79+
}
80+
81+
}

Diff for: test-non-functional/src/test/resources/arangodb-config-test.properties

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ adb.responseQueueTimeSamples=12345678
1717
adb.compression=GZIP
1818
adb.compressionThreshold=123456789
1919
adb.compressionLevel=9
20+
adb.serdeProviderClass=com.arangodb.serde.jsonb.JsonbSerdeProvider
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
arangodb.hosts=172.28.0.1:8529
2+
arangodb.password=test
3+
arangodb.serdeProviderClass=com.arangodb.serde.jsonb.JsonbSerdeProvider

0 commit comments

Comments
 (0)