Skip to content

Commit deb4526

Browse files
authored
[DE-535] configure Vertx instance (#558)
* reuse Vert.x instance * reuse Vert.x instance tests * fixed tests * fixed acrivefailover tests * fixed tests * reverted managed Vert.x instances to single thread event loop * changed log levels to debug * added HttpProtocolConfig to allow configuring the Vert.x instance to use
1 parent 8e13bda commit deb4526

File tree

15 files changed

+277
-32
lines changed

15 files changed

+277
-32
lines changed

Diff for: .github/workflows/test.yml

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ jobs:
3232
- docker.io/arangodb/arangodb:3.12
3333
- docker.io/arangodb/enterprise:3.11
3434
- docker.io/arangodb/enterprise:3.12
35+
starter-docker-img:
36+
# support activefailover
37+
- docker.io/arangodb/arangodb-starter:0.18.5
3538
topology:
3639
- single
3740
- cluster
@@ -60,6 +63,7 @@ jobs:
6063
ARANGO_LICENSE_KEY: ${{ secrets.ARANGO_LICENSE_KEY }}
6164
STARTER_MODE: ${{matrix.topology}}
6265
DOCKER_IMAGE: ${{matrix.docker-img}}
66+
STARTER_DOCKER_IMAGE: ${{matrix.starter-docker-img}}
6367
- name: Info
6468
run: mvn -version
6569
- name: Test
@@ -127,6 +131,9 @@ jobs:
127131
matrix:
128132
docker-img:
129133
- docker.io/arangodb/enterprise:3.11
134+
starter-docker-img:
135+
# support activefailover
136+
- docker.io/arangodb/arangodb-starter:0.18.5
130137
topology:
131138
- single
132139
- cluster
@@ -150,6 +157,7 @@ jobs:
150157
ARANGO_LICENSE_KEY: ${{ secrets.ARANGO_LICENSE_KEY }}
151158
STARTER_MODE: ${{matrix.topology}}
152159
DOCKER_IMAGE: ${{matrix.docker-img}}
160+
STARTER_DOCKER_IMAGE: ${{matrix.starter-docker-img}}
153161
- name: Set JWT
154162
run: |
155163
ENDPOINT=$(./docker/find_active_endpoint.sh)

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

+18-8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.arangodb.arch.UnstableApi;
2424
import com.arangodb.config.ArangoConfigProperties;
2525
import com.arangodb.config.HostDescription;
26+
import com.arangodb.config.ProtocolConfig;
2627
import com.arangodb.entity.*;
2728
import com.arangodb.internal.ArangoDBImpl;
2829
import com.arangodb.internal.ArangoExecutorSync;
@@ -264,9 +265,9 @@ public interface ArangoDB extends ArangoSerdeAccessor {
264265
*
265266
* @param user The name of the user
266267
* @param permissions The permissions the user grant
267-
* @since ArangoDB 3.2.0
268268
* @see <a href="https://docs.arangodb.com/stable/develop/http-api/users/#set-a-users-database-access-level">API
269269
* Documentation</a>
270+
* @since ArangoDB 3.2.0
270271
*/
271272
void grantDefaultDatabaseAccess(String user, Permissions permissions);
272273

@@ -276,9 +277,9 @@ public interface ArangoDB extends ArangoSerdeAccessor {
276277
*
277278
* @param user The name of the user
278279
* @param permissions The permissions the user grant
279-
* @since ArangoDB 3.2.0
280280
* @see <a href="https://docs.arangodb.com/stable/develop/http-api/users/#set-a-users-collection-access-level">API
281281
* Documentation</a>
282+
* @since ArangoDB 3.2.0
282283
*/
283284
void grantDefaultCollectionAccess(String user, Permissions permissions);
284285

@@ -313,19 +314,19 @@ public interface ArangoDB extends ArangoSerdeAccessor {
313314
* Returns the server's current loglevel settings.
314315
*
315316
* @return the server's current loglevel settings
316-
* @since ArangoDB 3.1.0
317317
* @see <a href="https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#get-the-server-log-levels">API
318318
* Documentation</a>
319+
* @since ArangoDB 3.1.0
319320
*/
320321
LogLevelEntity getLogLevel();
321322

322323
/**
323324
* Returns the server's current loglevel settings.
324325
*
325326
* @return the server's current loglevel settings
326-
* @since ArangoDB 3.10
327327
* @see <a href="https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#get-the-server-log-levels">API
328328
* Documentation</a>
329+
* @since ArangoDB 3.10
329330
*/
330331
LogLevelEntity getLogLevel(LogLevelOptions options);
331332

@@ -334,9 +335,9 @@ public interface ArangoDB extends ArangoSerdeAccessor {
334335
*
335336
* @param entity loglevel settings
336337
* @return the server's current loglevel settings
337-
* @since ArangoDB 3.1.0
338338
* @see <a href="https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#set-the-server-log-levels">API
339339
* Documentation</a>
340+
* @since ArangoDB 3.1.0
340341
*/
341342
LogLevelEntity setLogLevel(LogLevelEntity entity);
342343

@@ -345,17 +346,17 @@ public interface ArangoDB extends ArangoSerdeAccessor {
345346
*
346347
* @param entity loglevel settings
347348
* @return the server's current loglevel settings
348-
* @since ArangoDB 3.10
349349
* @see <a href="https://docs.arangodb.com/stable/develop/http-api/monitoring/logs/#set-the-server-log-levels">API
350350
* Documentation</a>
351+
* @since ArangoDB 3.10
351352
*/
352353
LogLevelEntity setLogLevel(LogLevelEntity entity, LogLevelOptions options);
353354

354355
/**
355356
* @return the list of available rules and their respective flags
356-
* @since ArangoDB 3.10
357357
* @see <a href="https://docs.arangodb.com/stable/develop/http-api/queries/aql-queries/#list-all-aql-optimizer-rules">API
358358
* Documentation</a>
359+
* @since ArangoDB 3.10
359360
*/
360361
Collection<QueryOptimizerRule> getQueryOptimizerRules();
361362

@@ -381,7 +382,7 @@ public ArangoDB build() {
381382
ProtocolProvider protocolProvider = protocolProvider(config.getProtocol());
382383
config.setProtocolModule(protocolProvider.protocolModule());
383384

384-
ConnectionFactory connectionFactory = protocolProvider.createConnectionFactory();
385+
ConnectionFactory connectionFactory = protocolProvider.createConnectionFactory(config.getProtocolConfig());
385386
Collection<Host> hostList = createHostList(connectionFactory);
386387
HostResolver hostResolver = createHostResolver(hostList, connectionFactory);
387388
HostHandler hostHandler = createHostHandler(hostResolver);
@@ -680,6 +681,15 @@ public Builder compressionLevel(Integer level) {
680681
return this;
681682
}
682683

684+
/**
685+
* Configuration specific for {@link com.arangodb.internal.net.ProtocolProvider}.
686+
* @return {@link ArangoDB.Builder}
687+
*/
688+
public Builder protocolConfig(ProtocolConfig protocolConfig) {
689+
config.setProtocolConfig(protocolConfig);
690+
return this;
691+
}
692+
683693
@UnstableApi
684694
protected ProtocolProvider protocolProvider(Protocol protocol) {
685695
ServiceLoader<ProtocolProvider> loader = ServiceLoader.load(ProtocolProvider.class);

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

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

113+
default Optional<Boolean> getReuseVertx() {
114+
return Optional.empty();
115+
}
116+
113117
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.arangodb.config;
2+
3+
/**
4+
* Configuration specific for {@link com.arangodb.internal.net.ProtocolProvider}.
5+
*/
6+
public interface ProtocolConfig {
7+
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.arangodb.arch.UsedInApi;
88
import com.arangodb.config.ArangoConfigProperties;
99
import com.arangodb.config.HostDescription;
10+
import com.arangodb.config.ProtocolConfig;
1011
import com.arangodb.entity.LoadBalancingStrategy;
1112
import com.arangodb.internal.ArangoDefaults;
1213
import com.arangodb.internal.serde.ContentTypeFactory;
@@ -49,6 +50,7 @@ public class ArangoConfig {
4950
private Compression compression;
5051
private Integer compressionThreshold;
5152
private Integer compressionLevel;
53+
private ProtocolConfig protocolConfig;
5254

5355
private static final Logger LOG = LoggerFactory.getLogger(ArangoConfig.class);
5456

@@ -329,4 +331,12 @@ public Integer getCompressionLevel() {
329331
public void setCompressionLevel(Integer compressionLevel) {
330332
this.compressionLevel = compressionLevel;
331333
}
334+
335+
public ProtocolConfig getProtocolConfig() {
336+
return protocolConfig;
337+
}
338+
339+
public void setProtocolConfig(ProtocolConfig protocolConfig) {
340+
this.protocolConfig = protocolConfig;
341+
}
332342
}

Diff for: core/src/main/java/com/arangodb/internal/net/ProtocolProvider.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import com.arangodb.Protocol;
55
import com.arangodb.arch.UsedInApi;
6+
import com.arangodb.config.ProtocolConfig;
67
import com.arangodb.internal.config.ArangoConfig;
78
import com.fasterxml.jackson.databind.Module;
89

@@ -11,7 +12,17 @@ public interface ProtocolProvider {
1112

1213
boolean supportsProtocol(Protocol protocol);
1314

14-
ConnectionFactory createConnectionFactory();
15+
/**
16+
* @deprecated use {@link #createConnectionFactory(ProtocolConfig)} instead
17+
*/
18+
@Deprecated
19+
default ConnectionFactory createConnectionFactory() {
20+
throw new UnsupportedOperationException();
21+
}
22+
23+
default ConnectionFactory createConnectionFactory(ProtocolConfig config) {
24+
return createConnectionFactory();
25+
}
1526

1627
CommunicationProtocol createProtocol(ArangoConfig config, HostHandler hostHandler);
1728

Diff for: docker/start_db.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Configuration environment variables:
44
# STARTER_MODE: (single|cluster|activefailover), default single
55
# DOCKER_IMAGE: ArangoDB docker image, default docker.io/arangodb/arangodb:latest
6+
# STARTER_DOCKER_IMAGE: ArangoDB Starter docker image, default docker.io/arangodb/arangodb-starter:latest
67
# SSL: (true|false), default false
78
# ARANGO_LICENSE_KEY: only required for ArangoDB Enterprise
89

@@ -11,10 +12,10 @@
1112

1213
STARTER_MODE=${STARTER_MODE:=single}
1314
DOCKER_IMAGE=${DOCKER_IMAGE:=docker.io/arangodb/arangodb:latest}
15+
STARTER_DOCKER_IMAGE=${STARTER_DOCKER_IMAGE:=docker.io/arangodb/arangodb-starter:latest}
1416
SSL=${SSL:=false}
1517
COMPRESSION=${COMPRESSION:=false}
1618

17-
STARTER_DOCKER_IMAGE=docker.io/arangodb/arangodb-starter:latest
1819
GW=172.28.0.1
1920
docker network create arangodb --subnet 172.28.0.0/16
2021

Diff for: driver/src/test/java/com/arangodb/ArangoConfigTest.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.arangodb;
22

3+
import com.arangodb.http.HttpProtocolConfig;
34
import com.arangodb.internal.ArangoDefaults;
45
import com.arangodb.internal.config.ArangoConfig;
56
import org.junit.jupiter.api.Test;
@@ -8,7 +9,7 @@
89

910
public class ArangoConfigTest {
1011
@Test
11-
void defaultValues() {
12+
void ArangoConfigDefaultValues() {
1213
ArangoConfig cfg = new ArangoConfig();
1314
assertThat(cfg.getHosts()).isEqualTo(ArangoDefaults.DEFAULT_HOSTS);
1415
assertThat(cfg.getProtocol()).isEqualTo(Protocol.HTTP2_JSON);
@@ -31,5 +32,13 @@ void defaultValues() {
3132
assertThat(cfg.getCompression()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION);
3233
assertThat(cfg.getCompressionThreshold()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION_THRESHOLD);
3334
assertThat(cfg.getCompressionLevel()).isEqualTo(ArangoDefaults.DEFAULT_COMPRESSION_LEVEL);
35+
assertThat(cfg.getProtocolConfig()).isNull();
3436
}
37+
38+
@Test
39+
void HttpProtocolConfigDefaultValues() {
40+
HttpProtocolConfig cfg = HttpProtocolConfig.builder().build();
41+
assertThat(cfg.getVertx()).isNull();
42+
}
43+
3544
}

Diff for: driver/src/test/java/com/arangodb/ArangoDBAsyncTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ void getAccessibleDatabasesFor(ArangoDBAsync arangoDB) throws ExecutionException
234234
@ParameterizedTest
235235
@MethodSource("asyncArangos")
236236
void createUser(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException {
237+
assumeTrue(isSingleServer());
237238
String username = "user-" + UUID.randomUUID();
238239
final UserEntity result = arangoDB.createUser(username, PW, null).get();
239240
assertThat(result.getUser()).isEqualTo(username);

Diff for: driver/src/test/java/perf/SimpleSyncPerfTest.java

+5
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@
2121
package perf;
2222

2323
import com.arangodb.ArangoDB;
24+
import com.arangodb.BaseJunit5;
2425
import com.arangodb.Protocol;
2526
import org.junit.jupiter.api.Disabled;
2627
import org.junit.jupiter.params.ParameterizedTest;
2728
import org.junit.jupiter.params.provider.EnumSource;
2829

2930
import java.util.Date;
3031

32+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
33+
3134
/**
3235
* @author Michele Rastelli
3336
*/
@@ -44,6 +47,8 @@ private void doGetVersion(ArangoDB arangoDB) {
4447
@ParameterizedTest
4548
@EnumSource(Protocol.class)
4649
void getVersion(Protocol protocol) throws InterruptedException {
50+
assumeTrue(!protocol.equals(Protocol.VST) || BaseJunit5.isLessThanVersion(3, 12));
51+
4752
ArangoDB arangoDB = new ArangoDB.Builder()
4853
.host("172.28.0.1", 8529)
4954
.password("test")

Diff for: http/src/main/java/com/arangodb/http/HttpConnection.java

+29-15
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,19 @@ public class HttpConnection implements Connection {
7575
private static final String CONTENT_TYPE_VPACK = "application/x-velocypack";
7676
private static final String USER_AGENT = getUserAgent();
7777
private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
78-
private String auth;
78+
private volatile String auth;
7979
private final int compressionThreshold;
8080
private final Encoder encoder;
8181
private final WebClient client;
8282
private final Integer timeout;
8383
private final MultiMap commonHeaders = MultiMap.caseInsensitiveMultiMap();
84-
private final Vertx vertx;
84+
private final Vertx vertxToClose;
8585

8686
private static String getUserAgent() {
8787
return "JavaDriver/" + PackageVersion.VERSION + " (JVM/" + System.getProperty("java.specification.version") + ")";
8888
}
8989

90-
HttpConnection(final ArangoConfig config, final HostDescription host) {
90+
HttpConnection(final ArangoConfig config, final HostDescription host, final Vertx existingVertx) {
9191
super();
9292
Protocol protocol = config.getProtocol();
9393
ContentType contentType = ContentTypeFactory.of(protocol);
@@ -108,14 +108,25 @@ private static String getUserAgent() {
108108
}
109109
commonHeaders.add("x-arango-driver", USER_AGENT);
110110
timeout = config.getTimeout();
111-
vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true).setEventLoopPoolSize(1));
112-
vertx.runOnContext(e -> {
113-
Thread.currentThread().setName("adb-http-" + THREAD_COUNT.getAndIncrement());
114-
auth = new UsernamePasswordCredentials(
115-
config.getUser(), Optional.ofNullable(config.getPassword()).orElse("")
116-
).toHttpAuthorization();
117-
LOGGER.debug("Created Vert.x context");
118-
});
111+
auth = new UsernamePasswordCredentials(
112+
config.getUser(), Optional.ofNullable(config.getPassword()).orElse("")
113+
).toHttpAuthorization();
114+
115+
Vertx vertxToUse;
116+
if (existingVertx != null) {
117+
// reuse existing Vert.x
118+
vertxToUse = existingVertx;
119+
// Vert.x will not be closed when connection is closed
120+
vertxToClose = null;
121+
LOGGER.debug("Reusing existing Vert.x instance");
122+
} else {
123+
// create a new Vert.x instance
124+
LOGGER.debug("Creating new Vert.x instance");
125+
vertxToUse = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true).setEventLoopPoolSize(1));
126+
vertxToUse.runOnContext(e -> Thread.currentThread().setName("adb-http-" + THREAD_COUNT.getAndIncrement()));
127+
// Vert.x be closed when connection is closed
128+
vertxToClose = vertxToUse;
129+
}
119130

120131
int intTtl = Optional.ofNullable(config.getConnectionTtl())
121132
.map(ttl -> Math.toIntExact(ttl / 1000))
@@ -193,7 +204,7 @@ public SslContextFactory sslContextFactory() {
193204
});
194205
}
195206

196-
client = WebClient.create(vertx, webClientOptions);
207+
client = WebClient.create(vertxToUse, webClientOptions);
197208
}
198209

199210
private static String buildUrl(final InternalRequest request) {
@@ -229,7 +240,10 @@ private static void addHeader(final InternalRequest request, final HttpRequest<?
229240
@Override
230241
public void close() {
231242
client.close();
232-
vertx.close();
243+
if (vertxToClose != null) {
244+
LOGGER.debug("Closing Vert.x instance");
245+
vertxToClose.close();
246+
}
233247
}
234248

235249
private HttpMethod requestTypeToHttpMethod(RequestType requestType) {
@@ -254,7 +268,7 @@ private HttpMethod requestTypeToHttpMethod(RequestType requestType) {
254268
@UnstableApi
255269
public CompletableFuture<InternalResponse> executeAsync(@UnstableApi final InternalRequest request) {
256270
CompletableFuture<InternalResponse> rfuture = new CompletableFuture<>();
257-
vertx.runOnContext(e -> doExecute(request, rfuture));
271+
doExecute(request, rfuture);
258272
return rfuture;
259273
}
260274

@@ -308,7 +322,7 @@ private InternalResponse buildResponse(final HttpResponse<Buffer> httpResponse)
308322
@Override
309323
public void setJwt(String jwt) {
310324
if (jwt != null) {
311-
vertx.runOnContext(e -> auth = new TokenCredentials(jwt).toHttpAuthorization());
325+
auth = new TokenCredentials(jwt).toHttpAuthorization();
312326
}
313327
}
314328

0 commit comments

Comments
 (0)