diff --git a/.circleci/config.yml b/.circleci/config.yml index 33bc358ab..dd397e8ad 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,7 @@ commands: parameters: docker-img: type: 'string' - default: 'docker.io/arangodb/arangodb:latest' + default: 'docker.io/arangodb/enterprise:latest' topology: type: 'string' default: 'single' @@ -109,13 +109,6 @@ commands: - run: name: Deploy to Apache Maven Central command: mvn -s .circleci/maven-release-settings.xml -Dmaven.test.skip deploy - release: - steps: - - run: - name: Release to Apache Maven Central - command: mvn -s .circleci/maven-release-settings.xml -Dmaven.test.skip nexus-staging:release - environment: - MAVEN_OPTS: "--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED" executors: j17: @@ -124,6 +117,9 @@ executors: j21: docker: - image: 'cimg/openjdk:21.0' + j25: + docker: + - image: 'cimg/openjdk:25.0' jobs: @@ -131,13 +127,13 @@ jobs: parameters: docker-img: type: 'string' - default: 'docker.io/arangodb/arangodb:latest' + default: 'docker.io/arangodb/enterprise:latest' topology: type: 'string' default: 'single' jdk: type: 'string' - default: 'j21' + default: 'j25' args: type: 'string' default: '' @@ -149,7 +145,7 @@ jobs: default: 'false' graalvm-version: type: 'string' - default: '21.0.2-graalce' + default: '25-graalce' resource_class: type: 'string' default: 'medium' @@ -199,13 +195,13 @@ jobs: parameters: docker-img: type: 'string' - default: 'docker.io/arangodb/arangodb:latest' + default: 'docker.io/arangodb/enterprise:latest' topology: type: 'string' default: 'single' jdk: type: 'string' - default: 'j21' + default: 'j25' args: type: 'string' default: '' @@ -217,7 +213,7 @@ jobs: default: 'false' graalvm-version: type: 'string' - default: '21.0.2-graalce' + default: '25-graalce' resource_class: type: 'string' default: 'medium' @@ -266,14 +262,14 @@ jobs: - store_cache test-non-func: - executor: 'j21' + executor: 'j25' steps: - timeout - checkout - setup_remote_docker - install-sdk: sdk: 'java' - version: '21.0.2-graalce' + version: '25-graalce' - start-db - load_cache - run: @@ -290,14 +286,14 @@ jobs: # https://issues.apache.org/jira/browse/MSHADE-206 # https://issues.apache.org/jira/browse/MNG-5899 test-non-func-shaded: - executor: 'j21' + executor: 'j25' steps: - timeout - checkout - setup_remote_docker - install-sdk: sdk: 'java' - version: '21.0.2-graalce' + version: '25-graalce' - start-db - load_cache - install @@ -360,7 +356,7 @@ jobs: - store_cache resilience-test: - executor: 'j21' + executor: 'j25' resource_class: 'large' steps: - timeout @@ -391,7 +387,7 @@ jobs: # https://issues.apache.org/jira/browse/MSHADE-206 # https://issues.apache.org/jira/browse/MNG-5899 resilience-test-shaded: - executor: 'j21' + executor: 'j25' resource_class: 'large' steps: - timeout @@ -432,18 +428,6 @@ jobs: - deploy - store_cache - release: - executor: 'j17' - steps: - - timeout: - duration: '30m' - - checkout - - load_cache - - config_gpg - - deploy - - release - - store_cache - workflows: test-adb-version: when: @@ -454,9 +438,6 @@ workflows: matrix: parameters: docker-img: - - 'docker.io/arangodb/arangodb:3.11' - - 'docker.io/arangodb/arangodb:3.12' - - 'docker.io/arangodb/enterprise:3.11' - 'docker.io/arangodb/enterprise:3.12' topology: - 'single' @@ -467,9 +448,6 @@ workflows: matrix: parameters: docker-img: - - 'docker.io/arangodb/arangodb:3.11' - - 'docker.io/arangodb/arangodb:3.12' - - 'docker.io/arangodb/enterprise:3.11' - 'docker.io/arangodb/enterprise:3.12' topology: - 'cluster' @@ -524,32 +502,35 @@ workflows: jdk: - 'j17' - 'j21' + - 'j25' filters: tags: only: /^v.*/ branches: only: - main + - next - test: name: test-jackson-<> matrix: parameters: args: - - '-Dadb.jackson.version=2.18.2' + - '-Dadb.jackson.version=2.20.0' + - '-Dadb.jackson.version=2.19.2' + - '-Dadb.jackson.version=2.18.4' - '-Dadb.jackson.version=2.17.3' - '-Dadb.jackson.version=2.16.2' - '-Dadb.jackson.version=2.15.4' - '-Dadb.jackson.version=2.14.3' - '-Dadb.jackson.version=2.13.5' - '-Dadb.jackson.version=2.12.7' - - '-Dadb.jackson.version=2.11.4' - - '-Dadb.jackson.version=2.10.5' filters: tags: only: /^v.*/ branches: only: - main + - next - test: name: test-native-ssl=<>-<> matrix: @@ -562,7 +543,7 @@ workflows: - 'true' - 'false' graalvm-version: - - '22.0.1-graalce' + - '25-graalce' - '21.0.2-graalce' filters: tags: @@ -570,6 +551,7 @@ workflows: branches: only: - main + - next - test-shaded: name: test-native-shaded-ssl=<>-<> matrix: @@ -582,7 +564,7 @@ workflows: - 'true' - 'false' graalvm-version: - - '22.0.1-graalce' + - '25-graalce' - '21.0.2-graalce' filters: tags: @@ -590,21 +572,7 @@ workflows: branches: only: - main - - test: - name: test-activefailover-<> - matrix: - parameters: - docker-img: - - 'docker.io/arangodb/arangodb:3.11' - - 'docker.io/arangodb/enterprise:3.11' - topology: - - 'activefailover' - filters: - tags: - only: /^v.*/ - branches: - only: - - main + - next test-non-func: when: @@ -646,13 +614,3 @@ workflows: only: /^deploy.*/ branches: ignore: /.*/ - - release: - jobs: - - release: - context: java-release - filters: - tags: - only: /^release.*/ - branches: - ignore: /.*/ diff --git a/.circleci/maven-release-settings.xml b/.circleci/maven-release-settings.xml index be5b9aef8..d8e10fc5d 100644 --- a/.circleci/maven-release-settings.xml +++ b/.circleci/maven-release-settings.xml @@ -3,7 +3,7 @@ - ossrh + central true @@ -16,9 +16,9 @@ - ossrh - ${env.OSSRH_USERNAME} - ${env.OSSRH_PASSWORD} + central + ${env.CENTRAL_USERNAME} + ${env.CENTRAL_PASSWORD} diff --git a/ChangeLog.md b/ChangeLog.md index eca1024b4..6c615750c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,6 +6,27 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] +## [7.22.1] - 2025-10-09 + +- added Java 25 to test matrix (#614) +- fixed native image in GraalVM 25 (#614) +- update Vert.x to version 4.5.21 (#614) +- updated Jackson to version `2.20.0` (#613) + +## [7.22.0] - 2025-08-06 + +- wildcard generic AQL bind vars (#612, DE-991) + +## [7.21.0] - 2025-07-23 + +- added SSL configuration properties (DE-1010, #611) +- fixed support to Jackson `2.19` + +## [7.20.0] - 2025-06-17 + +- added option `usePlanCache` to `AqlQueryOptions` (DE-973, #609) +- updated Jackson version to `2.19` (DE-1012, #607) + ## [7.19.0] - 2025-05-28 - fixed connection pool load-balancing (DE-1016, #602), now the connection pool: diff --git a/core/pom.xml b/core/pom.xml index 59ec6734e..293c3ab47 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,10 +5,9 @@ 4.0.0 - ../release-parent com.arangodb - release-parent - 7.19.0 + arangodb-java-driver-parent + 7.22.1 core @@ -17,7 +16,6 @@ com.arangodb.core - false diff --git a/core/src/main/java/com/arangodb/ArangoDB.java b/core/src/main/java/com/arangodb/ArangoDB.java index 7ebdb2e7e..56efa4758 100644 --- a/core/src/main/java/com/arangodb/ArangoDB.java +++ b/core/src/main/java/com/arangodb/ArangoDB.java @@ -356,6 +356,7 @@ public interface ArangoDB extends ArangoSerdeAccessor { /** * Reset the server log levels * Revert the server's log level settings to the values they had at startup, as determined by the startup options specified on the command-line, a configuration file, and the factory defaults. + * * @since ArangoDB 3.12 */ LogLevelEntity resetLogLevels(LogLevelOptions options); @@ -484,6 +485,39 @@ public Builder useSsl(final Boolean useSsl) { return this; } + /** + * Sets the SSL certificate value as Base64 encoded String + * + * @param sslCertValue the SSL certificate value as Base64 encoded String + * @return {@link ArangoDB.Builder} + */ + public Builder sslCertValue(final String sslCertValue) { + config.setSslCertValue(sslCertValue); + return this; + } + + /** + * Sets the SSL Trust manager algorithm + * + * @param sslAlgorithm the name of the SSL Trust manager algorithm + * @return {@link ArangoDB.Builder} + */ + public Builder sslAlgorithm(final String sslAlgorithm) { + config.setSslAlgorithm(sslAlgorithm); + return this; + } + + /** + * Sets the SSLContext protocol, default: {@code TLS} + * + * @param sslProtocol the name of the SSLContext protocol + * @return {@link ArangoDB.Builder} + */ + public Builder sslProtocol(final String sslProtocol) { + config.setSslProtocol(sslProtocol); + return this; + } + /** * Sets the SSL context to be used when {@code true} is passed through {@link #useSsl(Boolean)}. * @@ -716,6 +750,7 @@ public Builder compressionLevel(Integer level) { /** * Configuration specific for {@link com.arangodb.internal.net.ProtocolProvider}. + * * @return {@link ArangoDB.Builder} */ public Builder protocolConfig(ProtocolConfig protocolConfig) { diff --git a/core/src/main/java/com/arangodb/ArangoDatabase.java b/core/src/main/java/com/arangodb/ArangoDatabase.java index 8bef480f7..4af6cee38 100644 --- a/core/src/main/java/com/arangodb/ArangoDatabase.java +++ b/core/src/main/java/com/arangodb/ArangoDatabase.java @@ -254,7 +254,7 @@ public interface ArangoDatabase extends ArangoSerdeAccessor { * @see API * Documentation */ - ArangoCursor query(String query, Class type, Map bindVars, AqlQueryOptions options); + ArangoCursor query(String query, Class type, Map bindVars, AqlQueryOptions options); /** * Performs a database query using the given {@code query}, then returns a new {@code ArangoCursor} instance for the @@ -280,7 +280,7 @@ public interface ArangoDatabase extends ArangoSerdeAccessor { * @see API * Documentation */ - ArangoCursor query(String query, Class type, Map bindVars); + ArangoCursor query(String query, Class type, Map bindVars); /** * Performs a database query using the given {@code query}, then returns a new {@code ArangoCursor} instance for the @@ -355,11 +355,10 @@ public interface ArangoDatabase extends ArangoSerdeAccessor { * @return information about the query * @see API * Documentation - * * @deprecated for removal, use {@link ArangoDatabase#explainAqlQuery(String, Map, AqlQueryExplainOptions)} instead */ @Deprecated - AqlExecutionExplainEntity explainQuery(String query, Map bindVars, AqlQueryExplainOptions options); + AqlExecutionExplainEntity explainQuery(String query, Map bindVars, AqlQueryExplainOptions options); /** * Explain an AQL query and return information about it @@ -370,11 +369,10 @@ public interface ArangoDatabase extends ArangoSerdeAccessor { * @return information about the query * @see API * Documentation - * * @deprecated for removal, use {@link ArangoDatabase#explainAqlQuery(String, Map, ExplainAqlQueryOptions)} instead */ @Deprecated - AqlQueryExplainEntity explainAqlQuery(String query, Map bindVars, AqlQueryExplainOptions options); + AqlQueryExplainEntity explainAqlQuery(String query, Map bindVars, AqlQueryExplainOptions options); /** @@ -387,7 +385,7 @@ public interface ArangoDatabase extends ArangoSerdeAccessor { * @see API * Documentation */ - AqlQueryExplainEntity explainAqlQuery(String query, Map bindVars, ExplainAqlQueryOptions options); + AqlQueryExplainEntity explainAqlQuery(String query, Map bindVars, ExplainAqlQueryOptions options); /** * Parse an AQL query and return information about it This method is for query validation only. To actually query diff --git a/core/src/main/java/com/arangodb/ArangoDatabaseAsync.java b/core/src/main/java/com/arangodb/ArangoDatabaseAsync.java index d7a56d79a..41b2e34d6 100644 --- a/core/src/main/java/com/arangodb/ArangoDatabaseAsync.java +++ b/core/src/main/java/com/arangodb/ArangoDatabaseAsync.java @@ -146,11 +146,11 @@ public interface ArangoDatabaseAsync extends ArangoSerdeAccessor { */ CompletableFuture getPermissions(String user); - CompletableFuture> query(String query, Class type, Map bindVars, AqlQueryOptions options); + CompletableFuture> query(String query, Class type, Map bindVars, AqlQueryOptions options); CompletableFuture> query(String query, Class type, AqlQueryOptions options); - CompletableFuture> query(String query, Class type, Map bindVars); + CompletableFuture> query(String query, Class type, Map bindVars); CompletableFuture> query(String query, Class type); @@ -168,7 +168,7 @@ public interface ArangoDatabaseAsync extends ArangoSerdeAccessor { * @deprecated for removal, use {@link ArangoDatabaseAsync#explainAqlQuery(String, Map, AqlQueryExplainOptions)} instead */ @Deprecated - CompletableFuture explainQuery(String query, Map bindVars, AqlQueryExplainOptions options); + CompletableFuture explainQuery(String query, Map bindVars, AqlQueryExplainOptions options); /** * Asynchronous version of {@link ArangoDatabase#explainAqlQuery(String, Map, AqlQueryExplainOptions)} @@ -176,12 +176,12 @@ public interface ArangoDatabaseAsync extends ArangoSerdeAccessor { * @deprecated for removal, use {@link ArangoDatabaseAsync#explainAqlQuery(String, Map, ExplainAqlQueryOptions)} instead */ @Deprecated - CompletableFuture explainAqlQuery(String query, Map bindVars, AqlQueryExplainOptions options); + CompletableFuture explainAqlQuery(String query, Map bindVars, AqlQueryExplainOptions options); /** * Asynchronous version of {@link ArangoDatabase#explainAqlQuery(String, Map, ExplainAqlQueryOptions)} */ - CompletableFuture explainAqlQuery(String query, Map bindVars, ExplainAqlQueryOptions options); + CompletableFuture explainAqlQuery(String query, Map bindVars, ExplainAqlQueryOptions options); /** * Asynchronous version of {@link ArangoDatabase#parseQuery(String)} diff --git a/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java b/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java index 832c8862d..ee961acf1 100644 --- a/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java +++ b/core/src/main/java/com/arangodb/config/ArangoConfigProperties.java @@ -19,6 +19,9 @@ public interface ArangoConfigProperties { String KEY_JWT = "jwt"; String KEY_TIMEOUT = "timeout"; String KEY_USE_SSL = "useSsl"; + String KEY_SSL_CERT_VALUE = "sslCertValue"; + String KEY_SSL_ALGORITHM = "sslAlgorithm"; + String KEY_SSL_PROTOCOL = "sslProtocol"; String KEY_VERIFY_HOST = "verifyHost"; String KEY_CHUNK_SIZE = "chunkSize"; String KEY_PIPELINING = "pipelining"; @@ -103,6 +106,18 @@ default Optional getUseSsl() { return Optional.empty(); } + default Optional getSslCertValue() { + return Optional.empty(); + } + + default Optional getSslAlgorithm() { + return Optional.empty(); + } + + default Optional getSslProtocol() { + return Optional.empty(); + } + default Optional getVerifyHost() { return Optional.empty(); } diff --git a/core/src/main/java/com/arangodb/internal/ArangoDatabaseAsyncImpl.java b/core/src/main/java/com/arangodb/internal/ArangoDatabaseAsyncImpl.java index 698335094..7c7dda594 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoDatabaseAsyncImpl.java +++ b/core/src/main/java/com/arangodb/internal/ArangoDatabaseAsyncImpl.java @@ -169,7 +169,7 @@ public CompletableFuture getPermissions(final String user) { @Override public CompletableFuture> query( - final String query, final Class type, final Map bindVars, final AqlQueryOptions options) { + final String query, final Class type, final Map bindVars, final AqlQueryOptions options) { final InternalRequest request = queryRequest(query, bindVars, options); final HostHandle hostHandle = new HostHandle(); return executorAsync().execute(() -> request, cursorEntityDeserializer(type), hostHandle) @@ -182,7 +182,7 @@ public CompletableFuture> query(String query, Class } @Override - public CompletableFuture> query(String query, Class type, Map bindVars) { + public CompletableFuture> query(String query, Class type, Map bindVars) { return query(query, type, bindVars, new AqlQueryOptions()); } @@ -219,18 +219,18 @@ public CompletableFuture> cursor(String cursorId, Class @Override public CompletableFuture explainQuery( - final String query, final Map bindVars, final AqlQueryExplainOptions options) { + final String query, final Map bindVars, final AqlQueryExplainOptions options) { return executorAsync().execute(() -> explainQueryRequest(query, bindVars, options), AqlExecutionExplainEntity.class); } @Override public CompletableFuture explainAqlQuery( - String query, Map bindVars, AqlQueryExplainOptions options) { + String query, Map bindVars, AqlQueryExplainOptions options) { return executorAsync().execute(() -> explainQueryRequest(query, bindVars, options), AqlQueryExplainEntity.class); } @Override - public CompletableFuture explainAqlQuery(String query, Map bindVars, ExplainAqlQueryOptions options) { + public CompletableFuture explainAqlQuery(String query, Map bindVars, ExplainAqlQueryOptions options) { return executorAsync().execute(() -> explainQueryRequest(query, bindVars, options), AqlQueryExplainEntity.class); } diff --git a/core/src/main/java/com/arangodb/internal/ArangoDatabaseImpl.java b/core/src/main/java/com/arangodb/internal/ArangoDatabaseImpl.java index 5a652467d..26649883e 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoDatabaseImpl.java +++ b/core/src/main/java/com/arangodb/internal/ArangoDatabaseImpl.java @@ -162,7 +162,7 @@ public Permissions getPermissions(final String user) { @Override public ArangoCursor query( - final String query, final Class type, final Map bindVars, final AqlQueryOptions options) { + final String query, final Class type, final Map bindVars, final AqlQueryOptions options) { final InternalRequest request = queryRequest(query, bindVars, options); final HostHandle hostHandle = new HostHandle(); final CursorEntity result = executorSync().execute(request, cursorEntityDeserializer(type), hostHandle); @@ -170,7 +170,7 @@ public ArangoCursor query( } @Override - public ArangoCursor query(final String query, final Class type, final Map bindVars) { + public ArangoCursor query(final String query, final Class type, final Map bindVars) { return query(query, type, bindVars, new AqlQueryOptions()); } @@ -240,17 +240,17 @@ public void close(final String id) { @Override public AqlExecutionExplainEntity explainQuery( - final String query, final Map bindVars, final AqlQueryExplainOptions options) { + final String query, final Map bindVars, final AqlQueryExplainOptions options) { return executorSync().execute(explainQueryRequest(query, bindVars, options), AqlExecutionExplainEntity.class); } @Override - public AqlQueryExplainEntity explainAqlQuery(String query, Map bindVars, AqlQueryExplainOptions options) { + public AqlQueryExplainEntity explainAqlQuery(String query, Map bindVars, AqlQueryExplainOptions options) { return executorSync().execute(explainQueryRequest(query, bindVars, options), AqlQueryExplainEntity.class); } @Override - public AqlQueryExplainEntity explainAqlQuery(String query, Map bindVars, ExplainAqlQueryOptions options) { + public AqlQueryExplainEntity explainAqlQuery(String query, Map bindVars, ExplainAqlQueryOptions options) { return executorSync().execute(explainQueryRequest(query, bindVars, options), AqlQueryExplainEntity.class); } diff --git a/core/src/main/java/com/arangodb/internal/ArangoDefaults.java b/core/src/main/java/com/arangodb/internal/ArangoDefaults.java index 25448187c..2f68fd53e 100644 --- a/core/src/main/java/com/arangodb/internal/ArangoDefaults.java +++ b/core/src/main/java/com/arangodb/internal/ArangoDefaults.java @@ -48,6 +48,7 @@ public final class ArangoDefaults { public static final Integer DEFAULT_TIMEOUT = 0; public static final Long DEFAULT_CONNECTION_TTL_HTTP = 30_000L; public static final Boolean DEFAULT_USE_SSL = false; + public static final String DEFAULT_SSL_PROTOCOL = "TLS"; public static final Boolean DEFAULT_VERIFY_HOST = true; public static final Integer DEFAULT_CHUNK_SIZE = 30_000; public static final Boolean DEFAULT_PIPELINING = false; diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java b/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java index 3fe3911aa..135f4d825 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoDatabase.java @@ -140,7 +140,7 @@ protected ResponseDeserializer getPermissionsResponseDeserialzer() Permissions.class); } - protected InternalRequest queryRequest(final String query, final Map bindVars, + protected InternalRequest queryRequest(final String query, final Map bindVars, final AqlQueryOptions options) { final AqlQueryOptions opt = options != null ? options : new AqlQueryOptions(); final InternalRequest request = request(name, RequestType.POST, PATH_API_CURSOR) @@ -172,14 +172,14 @@ protected InternalRequest queryCloseRequest(final String id, final AqlQueryOptio return request; } - protected InternalRequest explainQueryRequest(final String query, final Map bindVars, + protected InternalRequest explainQueryRequest(final String query, final Map bindVars, final AqlQueryExplainOptions options) { final AqlQueryExplainOptions opt = options != null ? options : new AqlQueryExplainOptions(); return request(name, RequestType.POST, PATH_API_EXPLAIN) .setBody(getSerde().serialize(OptionsBuilder.build(opt, query, bindVars))); } - protected InternalRequest explainQueryRequest(final String query, final Map bindVars, + protected InternalRequest explainQueryRequest(final String query, final Map bindVars, final ExplainAqlQueryOptions options) { final ExplainAqlQueryOptions opt = options != null ? options : new ExplainAqlQueryOptions(); return request(name, RequestType.POST, PATH_API_EXPLAIN) diff --git a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java index f95e0a4e2..a13d41cdb 100644 --- a/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java +++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfig.java @@ -16,7 +16,12 @@ import com.fasterxml.jackson.databind.Module; import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.ByteArrayInputStream; import java.lang.reflect.InvocationTargetException; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; import java.util.*; import java.util.concurrent.Executor; import java.util.stream.Collectors; @@ -30,6 +35,9 @@ public class ArangoConfig { private String password; private String jwt; private Boolean useSsl; + private Optional sslCertValue; + private Optional sslAlgorithm; + private String sslProtocol; private SSLContext sslContext; private Boolean verifyHost; private Integer chunkSize; @@ -69,6 +77,9 @@ public void loadProperties(final ArangoConfigProperties properties) { // FIXME: make jwt field Optional jwt = properties.getJwt().orElse(null); useSsl = properties.getUseSsl().orElse(ArangoDefaults.DEFAULT_USE_SSL); + sslCertValue = properties.getSslCertValue(); + sslAlgorithm = properties.getSslAlgorithm(); + sslProtocol = properties.getSslProtocol().orElse(ArangoDefaults.DEFAULT_SSL_PROTOCOL); verifyHost = properties.getVerifyHost().orElse(ArangoDefaults.DEFAULT_VERIFY_HOST); chunkSize = properties.getChunkSize().orElse(ArangoDefaults.DEFAULT_CHUNK_SIZE); pipelining = properties.getPipelining().orElse(ArangoDefaults.DEFAULT_PIPELINING); @@ -151,7 +162,22 @@ public void setUseSsl(Boolean useSsl) { this.useSsl = useSsl; } + public void setSslCertValue(String sslCertValue) { + this.sslCertValue = Optional.ofNullable(sslCertValue); + } + + public void setSslAlgorithm(String sslAlgorithm) { + this.sslAlgorithm = Optional.ofNullable(sslAlgorithm); + } + + public void setSslProtocol(String sslProtocol) { + this.sslProtocol = sslProtocol; + } + public SSLContext getSslContext() { + if (sslContext == null) { + sslContext = createSslContext(); + } return sslContext; } @@ -342,4 +368,26 @@ public ProtocolConfig getProtocolConfig() { public void setProtocolConfig(ProtocolConfig protocolConfig) { this.protocolConfig = protocolConfig; } + + private SSLContext createSslContext() { + try { + if (sslCertValue.isPresent()) { + ByteArrayInputStream is = new ByteArrayInputStream(Base64.getDecoder().decode(sslCertValue.get())); + Certificate cert = CertificateFactory.getInstance("X.509").generateCertificate(is); + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + ks.load(null); + ks.setCertificateEntry("arangodb", cert); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(sslAlgorithm.orElseGet(TrustManagerFactory::getDefaultAlgorithm)); + tmf.init(ks); + SSLContext sc = SSLContext.getInstance(sslProtocol); + sc.init(null, tmf.getTrustManagers(), null); + return sc; + } else { + return SSLContext.getDefault(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } diff --git a/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java b/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java index f7d865f81..c1eadb402 100644 --- a/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java +++ b/core/src/main/java/com/arangodb/internal/config/ArangoConfigPropertiesImpl.java @@ -109,6 +109,21 @@ public Optional getUseSsl() { return Optional.ofNullable(getProperty(KEY_USE_SSL)).map(Boolean::valueOf); } + @Override + public Optional getSslCertValue() { + return Optional.ofNullable(getProperty(KEY_SSL_CERT_VALUE)); + } + + @Override + public Optional getSslAlgorithm() { + return Optional.ofNullable(getProperty(KEY_SSL_ALGORITHM)); + } + + @Override + public Optional getSslProtocol() { + return Optional.ofNullable(getProperty(KEY_SSL_PROTOCOL)); + } + @Override public Optional getVerifyHost() { return Optional.ofNullable(getProperty(KEY_VERIFY_HOST)).map(Boolean::valueOf); 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 acbbcbaaf..2d7ad5935 100644 --- a/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java +++ b/core/src/main/java/com/arangodb/internal/serde/SerdeUtils.java @@ -58,7 +58,7 @@ static void checkSupportedJacksonVersion() { ).forEach(version -> { int major = version.getMajorVersion(); int minor = version.getMinorVersion(); - if (major != 2 || minor < 10 || minor > 18) { + if (major != 2 || minor < 10 || minor > 20) { LOGGER.warn("Unsupported Jackson version: {}", version); } }); diff --git a/core/src/main/java/com/arangodb/model/AqlQueryExplainOptions.java b/core/src/main/java/com/arangodb/model/AqlQueryExplainOptions.java index 80862ae4f..ac4d1d161 100644 --- a/core/src/main/java/com/arangodb/model/AqlQueryExplainOptions.java +++ b/core/src/main/java/com/arangodb/model/AqlQueryExplainOptions.java @@ -35,7 +35,7 @@ @Deprecated public final class AqlQueryExplainOptions { - private Map bindVars; + private Map bindVars; private String query; private Options options; @@ -44,7 +44,7 @@ public AqlQueryExplainOptions() { } @UserDataInside - public Map getBindVars() { + public Map getBindVars() { return bindVars; } @@ -52,7 +52,7 @@ public Map getBindVars() { * @param bindVars key/value pairs representing the bind parameters * @return options */ - AqlQueryExplainOptions bindVars(final Map bindVars) { + AqlQueryExplainOptions bindVars(final Map bindVars) { this.bindVars = bindVars; return this; } diff --git a/core/src/main/java/com/arangodb/model/AqlQueryOptions.java b/core/src/main/java/com/arangodb/model/AqlQueryOptions.java index f51f419b2..ccf217a16 100644 --- a/core/src/main/java/com/arangodb/model/AqlQueryOptions.java +++ b/core/src/main/java/com/arangodb/model/AqlQueryOptions.java @@ -36,7 +36,7 @@ public final class AqlQueryOptions extends TransactionalOptions private Boolean allowDirtyRead; private Integer batchSize; - private Map bindVars; + private Map bindVars; private Boolean cache; private Boolean count; private Long memoryLimit; @@ -87,7 +87,7 @@ public AqlQueryOptions batchSize(final Integer batchSize) { } @UserDataInside - public Map getBindVars() { + public Map getBindVars() { return bindVars; } @@ -97,7 +97,7 @@ public Map getBindVars() { * variable {@code @@coll}, use {@code @coll} as the attribute name. * @return this */ - AqlQueryOptions bindVars(final Map bindVars) { + AqlQueryOptions bindVars(final Map bindVars) { this.bindVars = bindVars; return this; } @@ -236,6 +236,7 @@ public static final class Options implements Cloneable { private Long spillOverThresholdMemoryUsage; private Long spillOverThresholdNumRows; private Boolean stream; + private Boolean usePlanCache; @JsonInclude @JsonAnyGetter @@ -354,6 +355,10 @@ public Boolean getStream() { return stream; } + public Boolean getUsePlanCache() { + return usePlanCache; + } + public void setAllPlans(Boolean allPlans) { this.allPlans = allPlans; } @@ -446,6 +451,10 @@ public void setStream(Boolean stream) { this.stream = stream; } + public void setUsePlanCache(Boolean usePlanCache) { + this.usePlanCache = usePlanCache; + } + @Override public Options clone() { try { @@ -961,6 +970,11 @@ public Boolean getStream() { return getOptions().getStream(); } + @JsonIgnore + public Boolean getUsePlanCache() { + return getOptions().getUsePlanCache(); + } + /** * @param stream Specify true and the query will be executed in a streaming fashion. The query result is not * stored on @@ -983,6 +997,20 @@ public AqlQueryOptions stream(final Boolean stream) { return this; } + /** + * @param usePlanCache Set this option to true to utilize a cached query plan or add the execution plan of this + * query to the cache if it’s not in the cache yet. Otherwise, the plan cache is bypassed + * (introduced in v3.12.4). + * Query plan caching can reduce the total time for processing queries by avoiding to parse, + * plan, and optimize queries over and over again that effectively have the same execution plan + * with at most some changes to bind parameter values. + * @return this + */ + public AqlQueryOptions usePlanCache(final Boolean usePlanCache) { + getOptions().setUsePlanCache(usePlanCache); + return this; + } + @JsonIgnore public Collection getRules() { return getOptions().getOptimizer().getRules(); diff --git a/core/src/main/java/com/arangodb/model/ExplainAqlQueryOptions.java b/core/src/main/java/com/arangodb/model/ExplainAqlQueryOptions.java index 4d4d2f511..827670cf5 100644 --- a/core/src/main/java/com/arangodb/model/ExplainAqlQueryOptions.java +++ b/core/src/main/java/com/arangodb/model/ExplainAqlQueryOptions.java @@ -32,7 +32,7 @@ */ public final class ExplainAqlQueryOptions { - private Map bindVars; + private Map bindVars; private String query; private AqlQueryOptions.Options options; @@ -41,7 +41,7 @@ public ExplainAqlQueryOptions() { } @UserDataInside - public Map getBindVars() { + public Map getBindVars() { return bindVars; } @@ -49,7 +49,7 @@ public Map getBindVars() { * @param bindVars key/value pairs representing the bind parameters * @return options */ - ExplainAqlQueryOptions bindVars(final Map bindVars) { + ExplainAqlQueryOptions bindVars(final Map bindVars) { this.bindVars = bindVars; return this; } @@ -554,6 +554,11 @@ public Boolean getStream() { return getOptions().getStream(); } + @JsonIgnore + public Boolean getUsePlanCache() { + return getOptions().getUsePlanCache(); + } + /** * @param stream Specify true and the query will be executed in a streaming fashion. The query result is not * stored on @@ -576,6 +581,20 @@ public ExplainAqlQueryOptions stream(final Boolean stream) { return this; } + /** + * @param usePlanCache Set this option to true to utilize a cached query plan or add the execution plan of this + * query to the cache if it’s not in the cache yet. Otherwise, the plan cache is bypassed + * (introduced in v3.12.4). + * Query plan caching can reduce the total time for processing queries by avoiding to parse, + * plan, and optimize queries over and over again that effectively have the same execution plan + * with at most some changes to bind parameter values. + * @return this + */ + public ExplainAqlQueryOptions usePlanCache(final Boolean usePlanCache) { + getOptions().setUsePlanCache(usePlanCache); + return this; + } + @JsonIgnore public Collection getRules() { return getOptions().getOptimizer().getRules(); diff --git a/core/src/main/java/com/arangodb/model/OptionsBuilder.java b/core/src/main/java/com/arangodb/model/OptionsBuilder.java index 050c0d98f..1c6d4dfc6 100644 --- a/core/src/main/java/com/arangodb/model/OptionsBuilder.java +++ b/core/src/main/java/com/arangodb/model/OptionsBuilder.java @@ -71,21 +71,21 @@ public static CollectionCreateOptions build(final CollectionCreateOptions option } public static AqlQueryOptions build(final AqlQueryOptions options, final String query, - final Map bindVars) { + final Map bindVars) { return options.query(query).bindVars(bindVars); } public static AqlQueryExplainOptions build( final AqlQueryExplainOptions options, final String query, - final Map bindVars) { + final Map bindVars) { return options.query(query).bindVars(bindVars); } public static ExplainAqlQueryOptions build( final ExplainAqlQueryOptions options, final String query, - final Map bindVars) { + final Map bindVars) { return options.query(query).bindVars(bindVars); } diff --git a/docker/start_db.sh b/docker/start_db.sh index e8c58ebcd..0ef51fa5b 100755 --- a/docker/start_db.sh +++ b/docker/start_db.sh @@ -2,7 +2,7 @@ # Configuration environment variables: # STARTER_MODE: (single|cluster|activefailover), default single -# DOCKER_IMAGE: ArangoDB docker image, default docker.io/arangodb/arangodb:latest +# DOCKER_IMAGE: ArangoDB docker image, default docker.io/arangodb/enterprise:latest # STARTER_DOCKER_IMAGE: ArangoDB Starter docker image, default docker.io/arangodb/arangodb-starter:latest # SSL: (true|false), default false # ARANGO_LICENSE_KEY: only required for ArangoDB Enterprise @@ -11,7 +11,7 @@ # STARTER_MODE=cluster SSL=true ./start_db.sh STARTER_MODE=${STARTER_MODE:=single} -DOCKER_IMAGE=${DOCKER_IMAGE:=docker.io/arangodb/arangodb:latest} +DOCKER_IMAGE=${DOCKER_IMAGE:=docker.io/arangodb/enterprise:latest} STARTER_DOCKER_IMAGE=${STARTER_DOCKER_IMAGE:=docker.io/arangodb/arangodb-starter:latest} SSL=${SSL:=false} COMPRESSION=${COMPRESSION:=false} diff --git a/driver/pom.xml b/driver/pom.xml index f7a2c181c..59451e3c0 100644 --- a/driver/pom.xml +++ b/driver/pom.xml @@ -5,10 +5,9 @@ 4.0.0 - ../release-parent com.arangodb - release-parent - 7.19.0 + arangodb-java-driver-parent + 7.22.1 arangodb-java-driver @@ -16,7 +15,6 @@ ArangoDB Java Driver - false com.arangodb.driver src/test/**/* diff --git a/http-protocol/pom.xml b/http-protocol/pom.xml index 76d0b5ba8..599017176 100644 --- a/http-protocol/pom.xml +++ b/http-protocol/pom.xml @@ -5,10 +5,9 @@ 4.0.0 - ../release-parent com.arangodb - release-parent - 7.19.0 + arangodb-java-driver-parent + 7.22.1 http-protocol @@ -17,7 +16,6 @@ com.arangodb.http - false diff --git a/http-protocol/src/main/java/com/arangodb/http/HttpConnection.java b/http-protocol/src/main/java/com/arangodb/http/HttpConnection.java index d777f0e3f..f75c3639b 100644 --- a/http-protocol/src/main/java/com/arangodb/http/HttpConnection.java +++ b/http-protocol/src/main/java/com/arangodb/http/HttpConnection.java @@ -55,7 +55,6 @@ import org.slf4j.LoggerFactory; import javax.net.ssl.SSLContext; -import java.security.NoSuchAlgorithmException; import java.util.Collections; import java.util.Iterator; import java.util.Map.Entry; @@ -169,17 +168,7 @@ private static String getUserAgent() { } if (Boolean.TRUE.equals(config.getUseSsl())) { - SSLContext ctx; - if (config.getSslContext() != null) { - ctx = config.getSslContext(); - } else { - try { - ctx = SSLContext.getDefault(); - } catch (NoSuchAlgorithmException e) { - throw ArangoDBException.of(e); - } - } - + SSLContext ctx = config.getSslContext(); webClientOptions .setSsl(true) .setUseAlpn(true) diff --git a/jackson-serde-json/pom.xml b/jackson-serde-json/pom.xml index a435674c2..c86303b86 100644 --- a/jackson-serde-json/pom.xml +++ b/jackson-serde-json/pom.xml @@ -5,10 +5,9 @@ 4.0.0 - ../release-parent com.arangodb - release-parent - 7.19.0 + arangodb-java-driver-parent + 7.22.1 jackson-serde-json @@ -17,7 +16,6 @@ com.arangodb.serde.jackson.json - false diff --git a/jackson-serde-vpack/pom.xml b/jackson-serde-vpack/pom.xml index 6e077be36..0ce27c63a 100644 --- a/jackson-serde-vpack/pom.xml +++ b/jackson-serde-vpack/pom.xml @@ -5,10 +5,9 @@ 4.0.0 - ../release-parent com.arangodb - release-parent - 7.19.0 + arangodb-java-driver-parent + 7.22.1 jackson-serde-vpack @@ -17,7 +16,6 @@ com.arangodb.serde.jackson.vpack - false diff --git a/jsonb-serde/pom.xml b/jsonb-serde/pom.xml index 9923dbcf3..79de22e05 100644 --- a/jsonb-serde/pom.xml +++ b/jsonb-serde/pom.xml @@ -5,10 +5,9 @@ 4.0.0 - ../release-parent com.arangodb - release-parent - 7.19.0 + arangodb-java-driver-parent + 7.22.1 jsonb-serde @@ -17,7 +16,6 @@ com.arangodb.serde.jsonb - false diff --git a/pom.xml b/pom.xml index 0aa0fff95..2cddb0d87 100644 --- a/pom.xml +++ b/pom.xml @@ -5,10 +5,9 @@ com.arangodb arangodb-java-driver-parent - 7.19.0 + 7.22.1 2016 - release-parent core driver shaded @@ -37,12 +36,12 @@ 8 8 UTF-8 - true https://sonarcloud.io arangodb-1 target/spotbugsXml.xml site/jacoco/jacoco.xml - 23.1.1 + 25.0.0 + @@ -79,24 +78,200 @@ test-perf + + static-code-analysis + + + + com.github.spotbugs + spotbugs-maven-plugin + 4.9.6.0 + + spotbugs/spotbugs-exclude.xml + + + + compile + + check + + + + + + com.github.spotbugs + spotbugs + 4.7.3 + + + + + org.jacoco + jacoco-maven-plugin + + + + report + + + + + ../test-functional/target/jacoco.exec + + XML + + + + + + + + release + + + maven.test.skip + true + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.3.1 + + + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + jar + + + + com.arangodb.internal, + com.arangodb.internal.*, + com.arangodb.serde.jackson.internal, + javax.* + + none + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.2.8 + + + --pinentry-mode + loopback + + + + + sign-artifacts + verify + + sign + + + + + + org.codehaus.mojo + flatten-maven-plugin + + oss + + + + + flatten + package + + flatten + + + + + flatten.clean + clean + + clean + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + ${project.name} + ${project.version} + ${moduleName} + + + true + + + + org.apache.maven.plugins + maven-clean-plugin + + + + ${project.basedir} + + **/dependency-reduced-pom.xml + + + + + + + org.sonatype.central + central-publishing-maven-plugin + 0.9.0 + true + + central + true + published + + + + + - - io.vertx - vertx-stack-depchain - 4.5.7 - pom - import - com.fasterxml.jackson jackson-bom - 2.18.2 + 2.20.0 import pom + + io.vertx + vertx-stack-depchain + 4.5.21 + pom + import + com.google.code.findbugs jsr305 @@ -105,7 +280,7 @@ org.slf4j slf4j-api - 2.0.9 + 2.0.17 jakarta.json @@ -145,7 +320,7 @@ com.arangodb jackson-dataformat-velocypack - 4.6.0 + 4.6.2 com.arangodb @@ -178,7 +353,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.3.0 + 3.6.2 enforce @@ -199,7 +374,7 @@ - 3.6 + 3.6.3 @@ -209,39 +384,72 @@ org.codehaus.mojo extra-enforcer-rules - 1.8.0 + 1.11.0 - org.apache.maven.plugins - maven-deploy-plugin - 3.1.1 + org.codehaus.mojo + versions-maven-plugin + 2.19.1 - 10 - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.13 - true - - ossrh - https://oss.sonatype.org/ - 84aff6e87e214c - false - ${maven.deploy.skip} + + + + + + regex + (?i).*(alpha|beta|m|rc).*(\d+)? + + + + + io.vertx + + + regex + 5..* + + + + + io.netty + + + regex + .* + + + + + org.junit.jupiter + + + regex + 6..* + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 3.1.4 + + true + + org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.14.1 -Xlint:unchecked @@ -261,22 +469,22 @@ org.apache.maven.plugins maven-clean-plugin - 3.4.0 + 3.5.0 org.apache.maven.plugins maven-install-plugin - 3.1.2 + 3.1.4 org.apache.maven.plugins maven-site-plugin - 3.12.1 + 3.21.0 org.apache.maven.plugins maven-surefire-plugin - 3.0.0 + 3.5.4 true @@ -284,12 +492,12 @@ org.codehaus.mojo build-helper-maven-plugin - 3.3.0 + 3.6.1 org.jacoco jacoco-maven-plugin - 0.8.12 + 0.8.13 org.apache.maven.plugins @@ -299,12 +507,12 @@ org.sonarsource.scanner.maven sonar-maven-plugin - 4.0.0.4121 + 5.2.0.4988 org.apache.maven.plugins maven-shade-plugin - 3.4.1 + 3.6.1 com.google.code.maven-replacer-plugin @@ -314,23 +522,22 @@ org.apache.maven.plugins maven-surefire-report-plugin - 3.4.0 + 3.5.4 + + + org.codehaus.mojo + flatten-maven-plugin + 1.7.3 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.12.0 - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - oss.sonatype.org-snapshot diff --git a/release-parent/pom.xml b/release-parent/pom.xml deleted file mode 100644 index 0bb861fa0..000000000 --- a/release-parent/pom.xml +++ /dev/null @@ -1,184 +0,0 @@ - - - 4.0.0 - - com.arangodb - arangodb-java-driver-parent - 7.19.0 - - pom - - release-parent - release-parent - Parent for releasable modules - - - - true - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.2.1 - - - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.8.0 - - - - jar - - - - com.arangodb.internal, - com.arangodb.internal.*, - com.arangodb.serde.jackson.internal, - javax.* - - none - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 3.0.1 - - - --pinentry-mode - loopback - - - - - sign-artifacts - verify - - sign - - - - - - org.codehaus.mojo - flatten-maven-plugin - 1.4.1 - - oss - - - - - flatten - package - - flatten - - - - - flatten.clean - clean - - clean - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - ${project.name} - ${project.version} - ${moduleName} - - - true - - - - org.apache.maven.plugins - maven-clean-plugin - - - - ${project.basedir} - - **/dependency-reduced-pom.xml - - - - - - - - - - - static-code-analysis - - - - com.github.spotbugs - spotbugs-maven-plugin - 4.7.3.4 - - spotbugs/spotbugs-exclude.xml - - - - compile - - check - - - - - - com.github.spotbugs - spotbugs - 4.7.3 - - - - - org.jacoco - jacoco-maven-plugin - - - - report - - - - - ../test-functional/target/jacoco.exec - - XML - - - - - - - - - \ No newline at end of file diff --git a/shaded/pom.xml b/shaded/pom.xml index 7af61af37..4d108c4e6 100644 --- a/shaded/pom.xml +++ b/shaded/pom.xml @@ -5,10 +5,9 @@ 4.0.0 - ../release-parent com.arangodb - release-parent - 7.19.0 + arangodb-java-driver-parent + 7.22.1 arangodb-java-driver-shaded @@ -17,7 +16,6 @@ com.arangodb.driver - false src/main/java/graal/**/* @@ -207,7 +205,7 @@ - ${project.parent.parent.basedir}/driver/target/arangodb-java-driver-${project.version}-javadoc.jar + ${project.parent.basedir}/driver/target/arangodb-java-driver-${project.version}-javadoc.jar jar javadoc diff --git a/shaded/src/main/java/graal/netty/graal/NettySubstitutions.java b/shaded/src/main/java/graal/netty/graal/NettySubstitutions.java index fb9b8b1bb..d910cf1e7 100644 --- a/shaded/src/main/java/graal/netty/graal/NettySubstitutions.java +++ b/shaded/src/main/java/graal/netty/graal/NettySubstitutions.java @@ -1,45 +1,71 @@ package graal.netty.graal; +import static io.netty.handler.codec.http.HttpHeaderValues.BR; +import static io.netty.handler.codec.http.HttpHeaderValues.DEFLATE; +import static io.netty.handler.codec.http.HttpHeaderValues.GZIP; +import static io.netty.handler.codec.http.HttpHeaderValues.X_DEFLATE; +import static io.netty.handler.codec.http.HttpHeaderValues.X_GZIP; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.function.BooleanSupplier; + +import javax.crypto.NoSuchPaddingException; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; + import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; + import graal.netty.EmptyByteBufStub; import io.netty.bootstrap.AbstractBootstrapConfig; import io.netty.bootstrap.ChannelFactory; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; -import io.netty.channel.*; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.DefaultChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.handler.codec.compression.Brotli; +import io.netty.handler.codec.compression.BrotliDecoder; import io.netty.handler.codec.compression.ZlibCodecFactory; import io.netty.handler.codec.compression.ZlibWrapper; -import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http2.Http2Exception; -import io.netty.handler.ssl.*; +import io.netty.handler.ssl.ApplicationProtocolConfig; import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; +import io.netty.handler.ssl.CipherSuiteFilter; +import io.netty.handler.ssl.ClientAuth; +import io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator; +import io.netty.handler.ssl.JdkApplicationProtocolNegotiator; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextOption; +import io.netty.handler.ssl.SslProvider; import io.netty.util.concurrent.GlobalEventExecutor; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.JdkLoggerFactory; -import javax.crypto.NoSuchPaddingException; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLException; -import javax.net.ssl.TrustManagerFactory; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.security.*; -import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; -import java.util.*; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.function.BooleanSupplier; - -import static io.netty.handler.codec.http.HttpHeaderValues.*; - /** * This substitution avoid having loggers added to the build */ @@ -140,15 +166,14 @@ public static boolean isCipherSuiteAvailable(String cipherSuite) { @TargetClass(className = "io.netty.handler.ssl.JdkSslServerContext") final class Target_io_netty_handler_ssl_JdkSslServerContext { - @Alias Target_io_netty_handler_ssl_JdkSslServerContext(Provider provider, - X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, - X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, - KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, - ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, - ClientAuth clientAuth, String[] protocols, boolean startTls, - String keyStore) + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, + KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, + ClientAuth clientAuth, String[] protocols, boolean startTls, + SecureRandom secureRandom, String keyStore, Target_io_netty_handler_ssl_ResumptionController resumptionController) throws SSLException { } } @@ -157,13 +182,13 @@ final class Target_io_netty_handler_ssl_JdkSslServerContext { final class Target_io_netty_handler_ssl_JdkSslClientContext { @Alias - Target_io_netty_handler_ssl_JdkSslClientContext(Provider sslContextProvider, X509Certificate[] trustCertCollection, - TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, - String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, - CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, - long sessionCacheSize, long sessionTimeout, String keyStoreType) - throws SSLException { - + Target_io_netty_handler_ssl_JdkSslClientContext(Provider sslContextProvider, + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, + KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout, + SecureRandom secureRandom, String keyStoreType, String endpointIdentificationAlgorithm, + Target_io_netty_handler_ssl_ResumptionController resumptionController) throws SSLException { } } @@ -183,7 +208,7 @@ final class Target_io_netty_handler_ssl_SslHandler$SslEngineType { final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapper { @Substitute public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, - JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { + JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { return (SSLEngine) (Object) new Target_io_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator, isServer); } @@ -194,7 +219,16 @@ public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, final class Target_io_netty_handler_ssl_JdkAlpnSslEngine { @Alias Target_io_netty_handler_ssl_JdkAlpnSslEngine(final SSLEngine engine, - final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) { + final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) { + + } +} + +@TargetClass(className = "io.netty.handler.ssl.ResumptionController") +final class Target_io_netty_handler_ssl_ResumptionController { + + @Alias + Target_io_netty_handler_ssl_ResumptionController() { } } @@ -203,37 +237,42 @@ final class Target_io_netty_handler_ssl_JdkAlpnSslEngine { final class Target_io_netty_handler_ssl_SslContext { @Substitute - static SslContext newServerContextInternal(SslProvider provider, Provider sslContextProvider, - X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, - X509Certificate[] keyCertChain, - PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, - CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, - ClientAuth clientAuth, String[] protocols, boolean startTls, boolean enableOcsp, String keyStoreType, - Map.Entry, Object>... ctxOptions) throws SSLException { + static SslContext newServerContextInternal(SslProvider provider, + Provider sslContextProvider, + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, + Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, + long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls, + boolean enableOcsp, SecureRandom secureRandom, String keyStoreType, + Map.Entry, Object>... ctxOptions) throws SSLException { if (enableOcsp) { throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); } + Target_io_netty_handler_ssl_ResumptionController resumptionController = new Target_io_netty_handler_ssl_ResumptionController(); return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslServerContext(sslContextProvider, trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, - clientAuth, protocols, startTls, keyStoreType); + clientAuth, protocols, startTls, secureRandom, keyStoreType, resumptionController); } @Substitute - static SslContext newClientContextInternal(SslProvider provider, Provider sslContextProvider, - X509Certificate[] trustCert, - TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, - KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, - ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout, - boolean enableOcsp, - String keyStoreType, Map.Entry, Object>... options) throws SSLException { + static SslContext newClientContextInternal(SslProvider provider, + Provider sslContextProvider, + X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, + Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, + long sessionCacheSize, long sessionTimeout, boolean enableOcsp, + SecureRandom secureRandom, String keyStoreType, String endpointIdentificationAlgorithm, + Map.Entry, Object>... options) throws SSLException { if (enableOcsp) { throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); } + Target_io_netty_handler_ssl_ResumptionController resumptionController = new Target_io_netty_handler_ssl_ResumptionController(); return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslClientContext(sslContextProvider, trustCert, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, - sessionTimeout, keyStoreType); + sessionTimeout, secureRandom, keyStoreType, endpointIdentificationAlgorithm, + resumptionController); } } @@ -368,22 +407,6 @@ private static Queue newTaskQueue0(int maxPendingTasks) { } } -@TargetClass(className = "io.netty.buffer.AbstractReferenceCountedByteBuf") -final class Target_io_netty_buffer_AbstractReferenceCountedByteBuf { - - @Alias - @RecomputeFieldValue(kind = Kind.FieldOffset, name = "refCnt") - private static long REFCNT_FIELD_OFFSET; -} - -@TargetClass(className = "io.netty.util.AbstractReferenceCounted") -final class Target_io_netty_util_AbstractReferenceCounted { - - @Alias - @RecomputeFieldValue(kind = Kind.FieldOffset, name = "refCnt") - private static long REFCNT_FIELD_OFFSET; -} - // This class is runtime-initialized by NettyProcessor final class Holder_io_netty_util_concurrent_ScheduledFutureTask { static final long START_TIME = System.nanoTime(); @@ -433,11 +456,11 @@ static Class tryToLoadClass(final ClassLoader loader, final Class helper) final class Target_io_netty_buffer_EmptyByteBuf { @Alias - @RecomputeFieldValue(kind = Kind.Reset) + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) private static ByteBuffer EMPTY_BYTE_BUFFER; @Alias - @RecomputeFieldValue(kind = Kind.Reset) + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) private static long EMPTY_BYTE_BUFFER_ADDRESS; @Substitute @@ -494,6 +517,10 @@ protected EmbeddedChannel newContentDecoder(String contentEncoding) throws Excep return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(wrapper)); } + if (Brotli.isAvailable() && BR.contentEqualsIgnoreCase(contentEncoding)) { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), new BrotliDecoder()); + } // 'identity' or unsupported return null; @@ -509,20 +536,23 @@ final class Target_io_netty_handler_codec_http2_DelegatingDecompressorFrameListe @Substitute protected EmbeddedChannel newContentDecompressor(ChannelHandlerContext ctx, CharSequence contentEncoding) throws Http2Exception { - if (!HttpHeaderValues.GZIP.contentEqualsIgnoreCase(contentEncoding) - && !HttpHeaderValues.X_GZIP.contentEqualsIgnoreCase(contentEncoding)) { - if (!HttpHeaderValues.DEFLATE.contentEqualsIgnoreCase(contentEncoding) - && !HttpHeaderValues.X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) { - return null; - } else { - ZlibWrapper wrapper = this.strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE; - return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), - new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(wrapper) }); - } - } else { - return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), - new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP) }); + if (GZIP.contentEqualsIgnoreCase(contentEncoding) || X_GZIP.contentEqualsIgnoreCase(contentEncoding)) { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP)); } + if (DEFLATE.contentEqualsIgnoreCase(contentEncoding) || X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) { + final ZlibWrapper wrapper = strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE; + // To be strict, 'deflate' means ZLIB, but some servers were not implemented correctly. + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(wrapper)); + } + if (Brotli.isAvailable() && BR.contentEqualsIgnoreCase(contentEncoding)) { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), new BrotliDecoder()); + } + + // 'identity' or unsupported + return null; } } @@ -588,6 +618,14 @@ private static PrivateKey getPrivateKeyFromByteBuffer(ByteBuf encodedKeyBuf, Str } } +@TargetClass(className = "io.netty.util.internal.shaded.org.jctools.util.UnsafeLongArrayAccess") +final class Target_io_netty_util_internal_shaded_org_jctools_util_UnsafeRefArrayAccess { + + @Alias + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.ArrayIndexShift, declClass = Object[].class) + public static int LONG_ELEMENT_SHIFT; +} + class IsBouncyNotThere implements BooleanSupplier { @Override diff --git a/test-functional/pom.xml b/test-functional/pom.xml index c138499d9..ec180cbab 100644 --- a/test-functional/pom.xml +++ b/test-functional/pom.xml @@ -8,15 +8,11 @@ ../test-parent com.arangodb test-parent - 7.19.0 + 7.22.1 test-functional - - true - - org.eclipse.parsson @@ -151,7 +147,7 @@ org.graalvm.buildtools native-maven-plugin - 0.10.2 + 0.11.1 true @@ -175,6 +171,23 @@ + + no-native + + + native + !true + + + + + io.qameta.allure + allure-junit5 + 2.29.1 + test + + + static-code-analysis diff --git a/test-functional/src/test-default/java/graal/netty/graal/NettySubstitutions.java b/test-functional/src/test-default/java/graal/netty/graal/NettySubstitutions.java index fb9b8b1bb..d910cf1e7 100644 --- a/test-functional/src/test-default/java/graal/netty/graal/NettySubstitutions.java +++ b/test-functional/src/test-default/java/graal/netty/graal/NettySubstitutions.java @@ -1,45 +1,71 @@ package graal.netty.graal; +import static io.netty.handler.codec.http.HttpHeaderValues.BR; +import static io.netty.handler.codec.http.HttpHeaderValues.DEFLATE; +import static io.netty.handler.codec.http.HttpHeaderValues.GZIP; +import static io.netty.handler.codec.http.HttpHeaderValues.X_DEFLATE; +import static io.netty.handler.codec.http.HttpHeaderValues.X_GZIP; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.function.BooleanSupplier; + +import javax.crypto.NoSuchPaddingException; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; + import com.oracle.svm.core.annotate.Alias; import com.oracle.svm.core.annotate.RecomputeFieldValue; import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; + import graal.netty.EmptyByteBufStub; import io.netty.bootstrap.AbstractBootstrapConfig; import io.netty.bootstrap.ChannelFactory; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; -import io.netty.channel.*; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.DefaultChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.handler.codec.compression.Brotli; +import io.netty.handler.codec.compression.BrotliDecoder; import io.netty.handler.codec.compression.ZlibCodecFactory; import io.netty.handler.codec.compression.ZlibWrapper; -import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http2.Http2Exception; -import io.netty.handler.ssl.*; +import io.netty.handler.ssl.ApplicationProtocolConfig; import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; +import io.netty.handler.ssl.CipherSuiteFilter; +import io.netty.handler.ssl.ClientAuth; +import io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator; +import io.netty.handler.ssl.JdkApplicationProtocolNegotiator; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextOption; +import io.netty.handler.ssl.SslProvider; import io.netty.util.concurrent.GlobalEventExecutor; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.JdkLoggerFactory; -import javax.crypto.NoSuchPaddingException; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLException; -import javax.net.ssl.TrustManagerFactory; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.security.*; -import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; -import java.util.*; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.function.BooleanSupplier; - -import static io.netty.handler.codec.http.HttpHeaderValues.*; - /** * This substitution avoid having loggers added to the build */ @@ -140,15 +166,14 @@ public static boolean isCipherSuiteAvailable(String cipherSuite) { @TargetClass(className = "io.netty.handler.ssl.JdkSslServerContext") final class Target_io_netty_handler_ssl_JdkSslServerContext { - @Alias Target_io_netty_handler_ssl_JdkSslServerContext(Provider provider, - X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, - X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, - KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, - ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, - ClientAuth clientAuth, String[] protocols, boolean startTls, - String keyStore) + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, + KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, + ClientAuth clientAuth, String[] protocols, boolean startTls, + SecureRandom secureRandom, String keyStore, Target_io_netty_handler_ssl_ResumptionController resumptionController) throws SSLException { } } @@ -157,13 +182,13 @@ final class Target_io_netty_handler_ssl_JdkSslServerContext { final class Target_io_netty_handler_ssl_JdkSslClientContext { @Alias - Target_io_netty_handler_ssl_JdkSslClientContext(Provider sslContextProvider, X509Certificate[] trustCertCollection, - TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, - String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, - CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, - long sessionCacheSize, long sessionTimeout, String keyStoreType) - throws SSLException { - + Target_io_netty_handler_ssl_JdkSslClientContext(Provider sslContextProvider, + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, + KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout, + SecureRandom secureRandom, String keyStoreType, String endpointIdentificationAlgorithm, + Target_io_netty_handler_ssl_ResumptionController resumptionController) throws SSLException { } } @@ -183,7 +208,7 @@ final class Target_io_netty_handler_ssl_SslHandler$SslEngineType { final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapper { @Substitute public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, - JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { + JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { return (SSLEngine) (Object) new Target_io_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator, isServer); } @@ -194,7 +219,16 @@ public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, final class Target_io_netty_handler_ssl_JdkAlpnSslEngine { @Alias Target_io_netty_handler_ssl_JdkAlpnSslEngine(final SSLEngine engine, - final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) { + final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) { + + } +} + +@TargetClass(className = "io.netty.handler.ssl.ResumptionController") +final class Target_io_netty_handler_ssl_ResumptionController { + + @Alias + Target_io_netty_handler_ssl_ResumptionController() { } } @@ -203,37 +237,42 @@ final class Target_io_netty_handler_ssl_JdkAlpnSslEngine { final class Target_io_netty_handler_ssl_SslContext { @Substitute - static SslContext newServerContextInternal(SslProvider provider, Provider sslContextProvider, - X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, - X509Certificate[] keyCertChain, - PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, - CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, - ClientAuth clientAuth, String[] protocols, boolean startTls, boolean enableOcsp, String keyStoreType, - Map.Entry, Object>... ctxOptions) throws SSLException { + static SslContext newServerContextInternal(SslProvider provider, + Provider sslContextProvider, + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, + Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, + long sessionCacheSize, long sessionTimeout, ClientAuth clientAuth, String[] protocols, boolean startTls, + boolean enableOcsp, SecureRandom secureRandom, String keyStoreType, + Map.Entry, Object>... ctxOptions) throws SSLException { if (enableOcsp) { throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); } + Target_io_netty_handler_ssl_ResumptionController resumptionController = new Target_io_netty_handler_ssl_ResumptionController(); return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslServerContext(sslContextProvider, trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, - clientAuth, protocols, startTls, keyStoreType); + clientAuth, protocols, startTls, secureRandom, keyStoreType, resumptionController); } @Substitute - static SslContext newClientContextInternal(SslProvider provider, Provider sslContextProvider, - X509Certificate[] trustCert, - TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, - KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, - ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout, - boolean enableOcsp, - String keyStoreType, Map.Entry, Object>... options) throws SSLException { + static SslContext newClientContextInternal(SslProvider provider, + Provider sslContextProvider, + X509Certificate[] trustCert, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, + Iterable ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, + long sessionCacheSize, long sessionTimeout, boolean enableOcsp, + SecureRandom secureRandom, String keyStoreType, String endpointIdentificationAlgorithm, + Map.Entry, Object>... options) throws SSLException { if (enableOcsp) { throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); } + Target_io_netty_handler_ssl_ResumptionController resumptionController = new Target_io_netty_handler_ssl_ResumptionController(); return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslClientContext(sslContextProvider, trustCert, trustManagerFactory, keyCertChain, key, keyPassword, keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, - sessionTimeout, keyStoreType); + sessionTimeout, secureRandom, keyStoreType, endpointIdentificationAlgorithm, + resumptionController); } } @@ -368,22 +407,6 @@ private static Queue newTaskQueue0(int maxPendingTasks) { } } -@TargetClass(className = "io.netty.buffer.AbstractReferenceCountedByteBuf") -final class Target_io_netty_buffer_AbstractReferenceCountedByteBuf { - - @Alias - @RecomputeFieldValue(kind = Kind.FieldOffset, name = "refCnt") - private static long REFCNT_FIELD_OFFSET; -} - -@TargetClass(className = "io.netty.util.AbstractReferenceCounted") -final class Target_io_netty_util_AbstractReferenceCounted { - - @Alias - @RecomputeFieldValue(kind = Kind.FieldOffset, name = "refCnt") - private static long REFCNT_FIELD_OFFSET; -} - // This class is runtime-initialized by NettyProcessor final class Holder_io_netty_util_concurrent_ScheduledFutureTask { static final long START_TIME = System.nanoTime(); @@ -433,11 +456,11 @@ static Class tryToLoadClass(final ClassLoader loader, final Class helper) final class Target_io_netty_buffer_EmptyByteBuf { @Alias - @RecomputeFieldValue(kind = Kind.Reset) + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) private static ByteBuffer EMPTY_BYTE_BUFFER; @Alias - @RecomputeFieldValue(kind = Kind.Reset) + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) private static long EMPTY_BYTE_BUFFER_ADDRESS; @Substitute @@ -494,6 +517,10 @@ protected EmbeddedChannel newContentDecoder(String contentEncoding) throws Excep return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(wrapper)); } + if (Brotli.isAvailable() && BR.contentEqualsIgnoreCase(contentEncoding)) { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), new BrotliDecoder()); + } // 'identity' or unsupported return null; @@ -509,20 +536,23 @@ final class Target_io_netty_handler_codec_http2_DelegatingDecompressorFrameListe @Substitute protected EmbeddedChannel newContentDecompressor(ChannelHandlerContext ctx, CharSequence contentEncoding) throws Http2Exception { - if (!HttpHeaderValues.GZIP.contentEqualsIgnoreCase(contentEncoding) - && !HttpHeaderValues.X_GZIP.contentEqualsIgnoreCase(contentEncoding)) { - if (!HttpHeaderValues.DEFLATE.contentEqualsIgnoreCase(contentEncoding) - && !HttpHeaderValues.X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) { - return null; - } else { - ZlibWrapper wrapper = this.strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE; - return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), - new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(wrapper) }); - } - } else { - return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), - new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP) }); + if (GZIP.contentEqualsIgnoreCase(contentEncoding) || X_GZIP.contentEqualsIgnoreCase(contentEncoding)) { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP)); } + if (DEFLATE.contentEqualsIgnoreCase(contentEncoding) || X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) { + final ZlibWrapper wrapper = strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE; + // To be strict, 'deflate' means ZLIB, but some servers were not implemented correctly. + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(wrapper)); + } + if (Brotli.isAvailable() && BR.contentEqualsIgnoreCase(contentEncoding)) { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), new BrotliDecoder()); + } + + // 'identity' or unsupported + return null; } } @@ -588,6 +618,14 @@ private static PrivateKey getPrivateKeyFromByteBuffer(ByteBuf encodedKeyBuf, Str } } +@TargetClass(className = "io.netty.util.internal.shaded.org.jctools.util.UnsafeLongArrayAccess") +final class Target_io_netty_util_internal_shaded_org_jctools_util_UnsafeRefArrayAccess { + + @Alias + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.ArrayIndexShift, declClass = Object[].class) + public static int LONG_ELEMENT_SHIFT; +} + class IsBouncyNotThere implements BooleanSupplier { @Override diff --git a/test-functional/src/test-ssl/java/com/arangodb/ArangoSslTest.java b/test-functional/src/test-ssl/java/com/arangodb/ArangoSslTest.java index 092276a81..b454c6111 100644 --- a/test-functional/src/test-ssl/java/com/arangodb/ArangoSslTest.java +++ b/test-functional/src/test-ssl/java/com/arangodb/ArangoSslTest.java @@ -20,6 +20,7 @@ package com.arangodb; +import com.arangodb.config.ArangoConfigProperties; import com.arangodb.entity.ArangoDBVersion; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -55,6 +56,36 @@ void connect(Protocol protocol) { assertThat(version).isNotNull(); } + @ParameterizedTest + @EnumSource(Protocol.class) + void connectWithCertConf(Protocol protocol) { + assumeTrue(protocol != Protocol.VST); + + final ArangoDB arangoDB = new ArangoDB.Builder() + .protocol(protocol) + .host("172.28.0.1", 8529) + .password("test") + .useSsl(true) + .sslCertValue("MIIDezCCAmOgAwIBAgIEeDCzXzANBgkqhkiG9w0BAQsFADBuMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMjAxMTAxMTg1MTE5WhcNMzAxMDMwMTg1MTE5WjBuMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1WiDnd4+uCmMG539ZNZB8NwI0RZF3sUSQGPx3lkqaFTZVEzMZL76HYvdc9Qg7difyKyQ09RLSpMALX9euSseD7bZGnfQH52BnKcT09eQ3wh7aVQ5sN2omygdHLC7X9usntxAfv7NzmvdogNXoJQyY/hSZff7RIqWH8NnAUKkjqOe6Bf5LDbxHKESmrFBxOCOnhcpvZWetwpiRdJVPwUn5P82CAZzfiBfmBZnB7D0l+/6Cv4jMuH26uAIcixnVekBQzl1RgwczuiZf2MGO64vDMMJJWE9ClZF1uQuQrwXF6qwhuP1Hnkii6wNbTtPWlGSkqeutr004+Hzbf8KnRY4PAgMBAAGjITAfMB0GA1UdDgQWBBTBrv9Awynt3C5IbaCNyOW5v4DNkTANBgkqhkiG9w0BAQsFAAOCAQEAIm9rPvDkYpmzpSIhR3VXG9Y71gxRDrqkEeLsMoEyqGnw/zx1bDCNeGg2PncLlW6zTIipEBooixIE9U7KxHgZxBy0Et6EEWvIUmnr6F4F+dbTD050GHlcZ7eOeqYTPYeQC502G1Fo4tdNi4lDP9L9XZpf7Q1QimRH2qaLS03ZFZa2tY7ah/RQqZL8Dkxx8/zc25sgTHVpxoK853glBVBs/ENMiyGJWmAXQayewY3EPt/9wGwV4KmU3dPDleQeXSUGPUISeQxFjy+jCw21pYviWVJTNBA9l5ny3GhEmcnOT/gQHCvVRLyGLMbaMZ4JrPwb+aAtBgrgeiK4xeSMMvrbhw==") + .verifyHost(false) + .build(); + final ArangoDBVersion version = arangoDB.getVersion(); + assertThat(version).isNotNull(); + } + + @ParameterizedTest + @EnumSource(Protocol.class) + void connectWithFileProperties(Protocol protocol) { + assumeTrue(protocol != Protocol.VST); + + final ArangoDB arangoDB = new ArangoDB.Builder() + .loadProperties(ArangoConfigProperties.fromFile("arangodb-ssl.properties")) + .protocol(protocol) + .build(); + final ArangoDBVersion version = arangoDB.getVersion(); + assertThat(version).isNotNull(); + } + @ParameterizedTest @EnumSource(Protocol.class) void connectWithoutValidSslContext(Protocol protocol) { diff --git a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java index 866dfe5e4..77737ceef 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoCollectionAsyncTest.java @@ -3057,7 +3057,7 @@ void deleteDocumentsByDocumentOne(ArangoCollectionAsync collection) throws Execu @MethodSource("asyncCols") void deleteDocumentsEmpty(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { final Collection values = new ArrayList<>(); - collection.insertDocuments(values); + collection.insertDocuments(values).get(); final Collection keys = new ArrayList<>(); final MultiDocumentEntity deleteResult = collection.deleteDocuments(keys).get(); assertThat(deleteResult).isNotNull(); @@ -3069,7 +3069,7 @@ void deleteDocumentsEmpty(ArangoCollectionAsync collection) throws ExecutionExce @MethodSource("asyncCols") void deleteDocumentsByKeyNotExisting(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { final Collection values = new ArrayList<>(); - collection.insertDocuments(values); + collection.insertDocuments(values).get(); final Collection keys = Arrays.asList(rnd(), rnd()); final MultiDocumentEntity deleteResult = collection.deleteDocuments(keys).get(); @@ -3170,7 +3170,7 @@ void updateDocumentsWithoutKey(ArangoCollectionAsync collection) throws Executio { values.add(new BaseDocument("1")); } - collection.insertDocuments(values); + collection.insertDocuments(values).get(); final Collection updatedValues = new ArrayList<>(); for (final BaseDocument i : values) { i.addAttribute("a", "test"); @@ -3188,7 +3188,7 @@ void updateDocumentsJson(ArangoCollectionAsync collection) throws ExecutionExcep final Collection values = new ArrayList<>(); values.add(RawJson.of("{\"_key\":\"1\"}")); values.add(RawJson.of("{\"_key\":\"2\"}")); - collection.insertDocuments(values); + collection.insertDocuments(values).get(); final Collection updatedValues = new ArrayList<>(); updatedValues.add(RawJson.of("{\"_key\":\"1\", \"foo\":\"bar\"}")); @@ -3263,7 +3263,7 @@ void replaceDocumentsOne(ArangoCollectionAsync collection) throws ExecutionExcep e.setKey("1"); values.add(e); } - collection.insertDocuments(values); + collection.insertDocuments(values).get(); final Collection updatedValues = new ArrayList<>(); final BaseDocument first = values.iterator().next(); first.addAttribute("a", "test"); @@ -3321,7 +3321,7 @@ void replaceDocumentsJson(ArangoCollectionAsync collection) throws ExecutionExce @MethodSource("asyncCols") void replaceDocumentsRawData(ArangoCollectionAsync collection) throws ExecutionException, InterruptedException { final RawData values = RawJson.of("[{\"_key\":\"1\"}, {\"_key\":\"2\"}]"); - collection.insertDocuments(values); + collection.insertDocuments(values).get(); final RawData updatedValues = RawJson.of("[{\"_key\":\"1\", \"foo\":\"bar\"}, {\"_key\":\"2\", " + "\"foo\":\"bar\"}]"); diff --git a/test-functional/src/test/java/com/arangodb/ArangoConfigTest.java b/test-functional/src/test/java/com/arangodb/ArangoConfigTest.java index 2e00339a0..c017ef718 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoConfigTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoConfigTest.java @@ -5,11 +5,15 @@ import com.arangodb.internal.config.ArangoConfig; import org.junit.jupiter.api.Test; +import javax.net.ssl.SSLContext; + +import java.security.NoSuchAlgorithmException; + import static org.assertj.core.api.Assertions.assertThat; public class ArangoConfigTest { @Test - void ArangoConfigDefaultValues() { + void ArangoConfigDefaultValues() throws NoSuchAlgorithmException { ArangoConfig cfg = new ArangoConfig(); assertThat(cfg.getHosts()).isEqualTo(ArangoDefaults.DEFAULT_HOSTS); assertThat(cfg.getProtocol()).isEqualTo(Protocol.HTTP2_JSON); @@ -18,7 +22,7 @@ void ArangoConfigDefaultValues() { assertThat(cfg.getPassword()).isNull(); assertThat(cfg.getJwt()).isNull(); assertThat(cfg.getUseSsl()).isEqualTo(ArangoDefaults.DEFAULT_USE_SSL); - assertThat(cfg.getSslContext()).isNull(); + assertThat(cfg.getSslContext()).isEqualTo(SSLContext.getDefault()); assertThat(cfg.getVerifyHost()).isEqualTo(ArangoDefaults.DEFAULT_VERIFY_HOST); assertThat(cfg.getChunkSize()).isEqualTo(ArangoDefaults.DEFAULT_CHUNK_SIZE); assertThat(cfg.getMaxConnections()).isEqualTo(ArangoDefaults.MAX_CONNECTIONS_HTTP2_DEFAULT); diff --git a/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java index 1598a7ca1..47ac152e8 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDBAsyncTest.java @@ -20,7 +20,6 @@ package com.arangodb; -import com.arangodb.config.ConfigUtils; import com.arangodb.entity.*; import com.arangodb.internal.ArangoRequestParam; import com.arangodb.internal.serde.SerdeUtils; @@ -237,15 +236,19 @@ void createUser(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedEx assumeTrue(isSingleServer()); String username = "user-" + UUID.randomUUID(); final UserEntity result = arangoDB.createUser(username, PW, null).get(); - assertThat(result.getUser()).isEqualTo(username); + try { + assertThat(result.getUser()).isEqualTo(username); + } finally { + arangoDB.deleteUser(username).get(); + } } @ParameterizedTest @MethodSource("asyncArangos") - void deleteUser(ArangoDBAsync arangoDB) { + void deleteUser(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String username = "user-" + UUID.randomUUID(); - arangoDB.createUser(username, PW, null); - arangoDB.deleteUser(username); + arangoDB.createUser(username, PW, null).get(); + arangoDB.deleteUser(username).get(); } @ParameterizedTest @@ -261,7 +264,11 @@ void getUser(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedExcep String username = "user-" + UUID.randomUUID(); arangoDB.createUser(username, PW, null).get(); final UserEntity user = arangoDB.getUser(username).get(); - assertThat(user.getUser()).isEqualTo(username); + try { + assertThat(user.getUser()).isEqualTo(username); + } finally { + arangoDB.deleteUser(username).get(); + } } @ParameterizedTest @@ -279,28 +286,36 @@ void getUsers(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedExce final Collection initialUsers = arangoDB.getUsers().get(); arangoDB.createUser(username, PW, null).get(); - final Collection users = arangoDB.getUsers().get(); - assertThat(users).hasSize(initialUsers.size() + 1); + try { + final Collection users = arangoDB.getUsers().get(); + assertThat(users).hasSize(initialUsers.size() + 1); - final List expected = new ArrayList<>(users.size()); - // Add initial users, including root: - for (final UserEntity userEntity : initialUsers) { - expected.add(userEntity.getUser()); - } - // Add username: - expected.add(username); + final List expected = new ArrayList<>(users.size()); + // Add initial users, including root: + for (final UserEntity userEntity : initialUsers) { + expected.add(userEntity.getUser()); + } + // Add username: + expected.add(username); - for (final UserEntity user : users) { - assertThat(user.getUser()).isIn(expected); + for (final UserEntity user : users) { + assertThat(user.getUser()).isIn(expected); + } + } finally { + arangoDB.deleteUser(username).get(); } } @ParameterizedTest @MethodSource("asyncArangos") - void updateUserNoOptions(ArangoDBAsync arangoDB) { + void updateUserNoOptions(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String username = "user-" + UUID.randomUUID(); - arangoDB.createUser(username, PW, null); - arangoDB.updateUser(username, null); + arangoDB.createUser(username, PW, null).get(); + try { + arangoDB.updateUser(username, null).get(); + } finally { + arangoDB.deleteUser(username).get(); + } } @ParameterizedTest @@ -310,16 +325,20 @@ void updateUser(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedEx final Map extra = new HashMap<>(); extra.put("hund", false); arangoDB.createUser(username, PW, new UserCreateOptions().extra(extra)).get(); - extra.put("hund", true); - extra.put("mund", true); - final UserEntity user = arangoDB.updateUser(username, new UserUpdateOptions().extra(extra)).get(); - assertThat(user.getExtra()).hasSize(2); - assertThat(user.getExtra()).containsKey("hund"); - assertThat(Boolean.valueOf(String.valueOf(user.getExtra().get("hund")))).isTrue(); - final UserEntity user2 = arangoDB.getUser(username).get(); - assertThat(user2.getExtra()).hasSize(2); - assertThat(user2.getExtra()).containsKey("hund"); - assertThat(Boolean.valueOf(String.valueOf(user2.getExtra().get("hund")))).isTrue(); + try { + extra.put("hund", true); + extra.put("mund", true); + final UserEntity user = arangoDB.updateUser(username, new UserUpdateOptions().extra(extra)).get(); + assertThat(user.getExtra()).hasSize(2); + assertThat(user.getExtra()).containsKey("hund"); + assertThat(Boolean.valueOf(String.valueOf(user.getExtra().get("hund")))).isTrue(); + final UserEntity user2 = arangoDB.getUser(username).get(); + assertThat(user2.getExtra()).hasSize(2); + assertThat(user2.getExtra()).containsKey("hund"); + assertThat(Boolean.valueOf(String.valueOf(user2.getExtra().get("hund")))).isTrue(); + } finally { + arangoDB.deleteUser(username).get(); + } } @ParameterizedTest @@ -329,32 +348,44 @@ void replaceUser(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedE final Map extra = new HashMap<>(); extra.put("hund", false); arangoDB.createUser(username, PW, new UserCreateOptions().extra(extra)).get(); - extra.remove("hund"); - extra.put("mund", true); - final UserEntity user = arangoDB.replaceUser(username, new UserUpdateOptions().extra(extra)).get(); - assertThat(user.getExtra()).hasSize(1); - assertThat(user.getExtra()).containsKey("mund"); - assertThat(Boolean.valueOf(String.valueOf(user.getExtra().get("mund")))).isTrue(); - final UserEntity user2 = arangoDB.getUser(username).get(); - assertThat(user2.getExtra()).hasSize(1); - assertThat(user2.getExtra()).containsKey("mund"); - assertThat(Boolean.valueOf(String.valueOf(user2.getExtra().get("mund")))).isTrue(); + try { + extra.remove("hund"); + extra.put("mund", true); + final UserEntity user = arangoDB.replaceUser(username, new UserUpdateOptions().extra(extra)).get(); + assertThat(user.getExtra()).hasSize(1); + assertThat(user.getExtra()).containsKey("mund"); + assertThat(Boolean.valueOf(String.valueOf(user.getExtra().get("mund")))).isTrue(); + final UserEntity user2 = arangoDB.getUser(username).get(); + assertThat(user2.getExtra()).hasSize(1); + assertThat(user2.getExtra()).containsKey("mund"); + assertThat(Boolean.valueOf(String.valueOf(user2.getExtra().get("mund")))).isTrue(); + } finally { + arangoDB.deleteUser(username).get(); + } } @ParameterizedTest @MethodSource("asyncArangos") - void updateUserDefaultDatabaseAccess(ArangoDBAsync arangoDB) { + void updateUserDefaultDatabaseAccess(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String username = "user-" + UUID.randomUUID(); - arangoDB.createUser(username, PW); - arangoDB.grantDefaultDatabaseAccess(username, Permissions.RW); + arangoDB.createUser(username, PW).get(); + try { + arangoDB.grantDefaultDatabaseAccess(username, Permissions.RW).get(); + } finally { + arangoDB.deleteUser(username).get(); + } } @ParameterizedTest @MethodSource("asyncArangos") - void updateUserDefaultCollectionAccess(ArangoDBAsync arangoDB) { + void updateUserDefaultCollectionAccess(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String username = "user-" + UUID.randomUUID(); - arangoDB.createUser(username, PW); - arangoDB.grantDefaultCollectionAccess(username, Permissions.RW); + arangoDB.createUser(username, PW).get(); + try { + arangoDB.grantDefaultCollectionAccess(username, Permissions.RW).get(); + } finally { + arangoDB.deleteUser(username).get(); + } } @ParameterizedTest @@ -637,29 +668,6 @@ void arangoDBException(ArangoDBAsync arangoDB) { assertThat(e.getErrorNum()).isEqualTo(1228); } - @ParameterizedTest - @MethodSource("asyncArangos") - void fallbackHost() throws ExecutionException, InterruptedException { - final ArangoDBAsync arangoDB = new ArangoDB.Builder() - .loadProperties(config) - .host("not-accessible", 8529).host("172.28.0.1", 8529) - .build() - .async(); - final ArangoDBVersion version = arangoDB.getVersion().get(); - assertThat(version).isNotNull(); - } - - @ParameterizedTest - @MethodSource("asyncArangos") - void loadpropertiesWithPrefix() throws ExecutionException, InterruptedException { - ArangoDBAsync adb = new ArangoDB.Builder() - .loadProperties(ConfigUtils.loadConfig("arangodb-with-prefix.properties", "adb")) - .build() - .async(); - adb.getVersion().get(); - adb.shutdown(); - } - @ParameterizedTest @MethodSource("asyncArangos") void accessMultipleDatabases(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { diff --git a/test-functional/src/test/java/com/arangodb/ArangoDBTest.java b/test-functional/src/test/java/com/arangodb/ArangoDBTest.java index 7085c7ae7..030d3d6a7 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDBTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDBTest.java @@ -239,7 +239,11 @@ void getAccessibleDatabasesFor(ArangoDB arangoDB) { void createUser(ArangoDB arangoDB) { String username = "user-" + UUID.randomUUID(); final UserEntity result = arangoDB.createUser(username, PW, null); - assertThat(result.getUser()).isEqualTo(username); + try { + assertThat(result.getUser()).isEqualTo(username); + } finally { + arangoDB.deleteUser(username); + } } @ParameterizedTest @@ -281,19 +285,23 @@ void getUsers(ArangoDB arangoDB) { final Collection initialUsers = arangoDB.getUsers(); arangoDB.createUser(username, PW, null); - final Collection users = arangoDB.getUsers(); - assertThat(users).hasSize(initialUsers.size() + 1); + try { + final Collection users = arangoDB.getUsers(); + assertThat(users).hasSize(initialUsers.size() + 1); - final List expected = new ArrayList<>(users.size()); - // Add initial users, including root: - for (final UserEntity userEntity : initialUsers) { - expected.add(userEntity.getUser()); - } - // Add username: - expected.add(username); + final List expected = new ArrayList<>(users.size()); + // Add initial users, including root: + for (final UserEntity userEntity : initialUsers) { + expected.add(userEntity.getUser()); + } + // Add username: + expected.add(username); - for (final UserEntity user : users) { - assertThat(user.getUser()).isIn(expected); + for (final UserEntity user : users) { + assertThat(user.getUser()).isIn(expected); + } + } finally { + arangoDB.deleteUser(username); } } @@ -302,7 +310,11 @@ void getUsers(ArangoDB arangoDB) { void updateUserNoOptions(ArangoDB arangoDB) { String username = "user-" + UUID.randomUUID(); arangoDB.createUser(username, PW, null); - arangoDB.updateUser(username, null); + try { + arangoDB.updateUser(username, null); + } finally { + arangoDB.deleteUser(username); + } } @ParameterizedTest @@ -312,16 +324,20 @@ void updateUser(ArangoDB arangoDB) { final Map extra = new HashMap<>(); extra.put("hund", false); arangoDB.createUser(username, PW, new UserCreateOptions().extra(extra)); - extra.put("hund", true); - extra.put("mund", true); - final UserEntity user = arangoDB.updateUser(username, new UserUpdateOptions().extra(extra)); - assertThat(user.getExtra()).hasSize(2); - assertThat(user.getExtra()).containsKey("hund"); - assertThat(Boolean.valueOf(String.valueOf(user.getExtra().get("hund")))).isTrue(); - final UserEntity user2 = arangoDB.getUser(username); - assertThat(user2.getExtra()).hasSize(2); - assertThat(user2.getExtra()).containsKey("hund"); - assertThat(Boolean.valueOf(String.valueOf(user2.getExtra().get("hund")))).isTrue(); + try { + extra.put("hund", true); + extra.put("mund", true); + final UserEntity user = arangoDB.updateUser(username, new UserUpdateOptions().extra(extra)); + assertThat(user.getExtra()).hasSize(2); + assertThat(user.getExtra()).containsKey("hund"); + assertThat(Boolean.valueOf(String.valueOf(user.getExtra().get("hund")))).isTrue(); + final UserEntity user2 = arangoDB.getUser(username); + assertThat(user2.getExtra()).hasSize(2); + assertThat(user2.getExtra()).containsKey("hund"); + assertThat(Boolean.valueOf(String.valueOf(user2.getExtra().get("hund")))).isTrue(); + } finally { + arangoDB.deleteUser(username); + } } @ParameterizedTest @@ -331,16 +347,20 @@ void replaceUser(ArangoDB arangoDB) { final Map extra = new HashMap<>(); extra.put("hund", false); arangoDB.createUser(username, PW, new UserCreateOptions().extra(extra)); - extra.remove("hund"); - extra.put("mund", true); - final UserEntity user = arangoDB.replaceUser(username, new UserUpdateOptions().extra(extra)); - assertThat(user.getExtra()).hasSize(1); - assertThat(user.getExtra()).containsKey("mund"); - assertThat(Boolean.valueOf(String.valueOf(user.getExtra().get("mund")))).isTrue(); - final UserEntity user2 = arangoDB.getUser(username); - assertThat(user2.getExtra()).hasSize(1); - assertThat(user2.getExtra()).containsKey("mund"); - assertThat(Boolean.valueOf(String.valueOf(user2.getExtra().get("mund")))).isTrue(); + try { + extra.remove("hund"); + extra.put("mund", true); + final UserEntity user = arangoDB.replaceUser(username, new UserUpdateOptions().extra(extra)); + assertThat(user.getExtra()).hasSize(1); + assertThat(user.getExtra()).containsKey("mund"); + assertThat(Boolean.valueOf(String.valueOf(user.getExtra().get("mund")))).isTrue(); + final UserEntity user2 = arangoDB.getUser(username); + assertThat(user2.getExtra()).hasSize(1); + assertThat(user2.getExtra()).containsKey("mund"); + assertThat(Boolean.valueOf(String.valueOf(user2.getExtra().get("mund")))).isTrue(); + } finally { + arangoDB.deleteUser(username); + } } @ParameterizedTest @@ -348,7 +368,11 @@ void replaceUser(ArangoDB arangoDB) { void updateUserDefaultDatabaseAccess(ArangoDB arangoDB) { String username = "user-" + UUID.randomUUID(); arangoDB.createUser(username, PW); - arangoDB.grantDefaultDatabaseAccess(username, Permissions.RW); + try { + arangoDB.grantDefaultDatabaseAccess(username, Permissions.RW); + } finally { + arangoDB.deleteUser(username); + } } @ParameterizedTest @@ -356,7 +380,11 @@ void updateUserDefaultDatabaseAccess(ArangoDB arangoDB) { void updateUserDefaultCollectionAccess(ArangoDB arangoDB) { String username = "user-" + UUID.randomUUID(); arangoDB.createUser(username, PW); - arangoDB.grantDefaultCollectionAccess(username, Permissions.RW); + try { + arangoDB.grantDefaultCollectionAccess(username, Permissions.RW); + } finally { + arangoDB.deleteUser(username); + } } @ParameterizedTest @@ -651,16 +679,6 @@ void arangoDBException(ArangoDB arangoDB) { assertThat(e.getErrorNum()).isEqualTo(1228); } - @ParameterizedTest - @MethodSource("arangos") - void fallbackHost() { - final ArangoDB arangoDB = new ArangoDB.Builder() - .loadProperties(config) - .host("not-accessible", 8529).host("172.28.0.1", 8529).build(); - final ArangoDBVersion version = arangoDB.getVersion(); - assertThat(version).isNotNull(); - } - @ParameterizedTest @MethodSource("arangos") void loadproperties() { @@ -670,29 +688,6 @@ void loadproperties() { assertThat(thrown).isInstanceOf(IllegalArgumentException.class); } - @ParameterizedTest - @MethodSource("arangos") - void loadPropertiesWithPrefix() { - ArangoDB adb = new ArangoDB.Builder() - .loadProperties(ConfigUtils.loadConfig("arangodb-with-prefix.properties", "adb")) - .build(); - adb.getVersion(); - adb.shutdown(); - } - - @ParameterizedTest - @MethodSource("arangos") - void loadConfigFromPropertiesWithPrefix() { - Properties props = new Properties(); - props.setProperty("adb.hosts", "172.28.0.1:8529"); - props.setProperty("adb.password", "test"); - ArangoDB adb = new ArangoDB.Builder() - .loadProperties(ConfigUtils.loadConfig(props, "adb")) - .build(); - adb.getVersion(); - adb.shutdown(); - } - @ParameterizedTest @MethodSource("arangos") void accessMultipleDatabases(ArangoDB arangoDB) { diff --git a/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java index bd6f45a2b..67af254ea 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDatabaseAsyncTest.java @@ -24,10 +24,7 @@ import com.arangodb.entity.QueryCachePropertiesEntity.CacheMode; import com.arangodb.internal.serde.InternalSerde; import com.arangodb.model.*; -import com.arangodb.util.MapBuilder; -import com.arangodb.util.RawBytes; -import com.arangodb.util.RawJson; -import com.arangodb.util.SlowTest; +import com.arangodb.util.*; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; @@ -478,31 +475,47 @@ void getCollectionsExcludeSystem(ArangoDatabaseAsync db) throws ExecutionExcepti void grantAccess(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String user = "user-" + rnd(); arangoDB.createUser(user, "1234", null).get(); - arangoDB.db(getTestDb()).grantAccess(user).get(); + try { + arangoDB.db(getTestDb()).grantAccess(user).get(); + } finally { + arangoDB.deleteUser(user).get(); + } } @ParameterizedTest @MethodSource("asyncArangos") - void grantAccessRW(ArangoDBAsync arangoDB) { + void grantAccessRW(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String user = "user-" + rnd(); - arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).grantAccess(user, Permissions.RW); + arangoDB.createUser(user, "1234", null).get(); + try { + arangoDB.db(getTestDb()).grantAccess(user, Permissions.RW).get(); + } finally { + arangoDB.deleteUser(user).get(); + } } @ParameterizedTest @MethodSource("asyncArangos") - void grantAccessRO(ArangoDBAsync arangoDB) { + void grantAccessRO(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String user = "user-" + rnd(); - arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).grantAccess(user, Permissions.RO); + arangoDB.createUser(user, "1234", null).get(); + try { + arangoDB.db(getTestDb()).grantAccess(user, Permissions.RO).get(); + } finally { + arangoDB.deleteUser(user).get(); + } } @ParameterizedTest @MethodSource("asyncArangos") - void grantAccessNONE(ArangoDBAsync arangoDB) { + void grantAccessNONE(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String user = "user-" + rnd(); - arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).grantAccess(user, Permissions.NONE); + arangoDB.createUser(user, "1234", null).get(); + try { + arangoDB.db(getTestDb()).grantAccess(user, Permissions.NONE).get(); + } finally { + arangoDB.deleteUser(user).get(); + } } @ParameterizedTest @@ -515,10 +528,14 @@ void grantAccessUserNotFound(ArangoDatabaseAsync db) { @ParameterizedTest @MethodSource("asyncArangos") - void revokeAccess(ArangoDBAsync arangoDB) { + void revokeAccess(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String user = "user-" + rnd(); - arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).revokeAccess(user); + arangoDB.createUser(user, "1234", null).get(); + try { + arangoDB.db(getTestDb()).revokeAccess(user).get(); + } finally { + arangoDB.deleteUser(user).get(); + } } @ParameterizedTest @@ -531,10 +548,14 @@ void revokeAccessUserNotFound(ArangoDatabaseAsync db) { @ParameterizedTest @MethodSource("asyncArangos") - void resetAccess(ArangoDBAsync arangoDB) { + void resetAccess(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String user = "user-" + rnd(); - arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).resetAccess(user); + arangoDB.createUser(user, "1234", null).get(); + try { + arangoDB.db(getTestDb()).resetAccess(user).get(); + } finally { + arangoDB.deleteUser(user).get(); + } } @ParameterizedTest @@ -547,10 +568,14 @@ void resetAccessUserNotFound(ArangoDatabaseAsync db) { @ParameterizedTest @MethodSource("asyncArangos") - void grantDefaultCollectionAccess(ArangoDBAsync arangoDB) { + void grantDefaultCollectionAccess(ArangoDBAsync arangoDB) throws ExecutionException, InterruptedException { String user = "user-" + rnd(); - arangoDB.createUser(user, "1234"); - arangoDB.db(getTestDb()).grantDefaultCollectionAccess(user, Permissions.RW); + arangoDB.createUser(user, "1234").get(); + try { + arangoDB.db(getTestDb()).grantDefaultCollectionAccess(user, Permissions.RW).get(); + } finally { + arangoDB.deleteUser(user).get(); + } } @ParameterizedTest @@ -904,7 +929,7 @@ void queryWithBindVars(ArangoDatabaseAsync db) throws ExecutionException, Interr @ParameterizedTest @MethodSource("asyncDbs") void queryWithRawBindVars(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { - final Map bindVars = new HashMap<>(); + final Map bindVars = new HashMap<>(); bindVars.put("foo", RawJson.of("\"fooValue\"")); bindVars.put("bar", RawBytes.of(db.getSerde().serializeUserData(11))); diff --git a/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java b/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java index ea487e07c..3763aacbf 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoDatabaseTest.java @@ -490,7 +490,11 @@ void getCollectionsExcludeSystem(ArangoDatabase db) { void grantAccess(ArangoDB arangoDB) { String user = "user-" + rnd(); arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).grantAccess(user); + try { + arangoDB.db(getTestDb()).grantAccess(user); + } finally { + arangoDB.deleteUser(user); + } } @ParameterizedTest @@ -498,7 +502,11 @@ void grantAccess(ArangoDB arangoDB) { void grantAccessRW(ArangoDB arangoDB) { String user = "user-" + rnd(); arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).grantAccess(user, Permissions.RW); + try { + arangoDB.db(getTestDb()).grantAccess(user, Permissions.RW); + } finally { + arangoDB.deleteUser(user); + } } @ParameterizedTest @@ -506,7 +514,11 @@ void grantAccessRW(ArangoDB arangoDB) { void grantAccessRO(ArangoDB arangoDB) { String user = "user-" + rnd(); arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).grantAccess(user, Permissions.RO); + try { + arangoDB.db(getTestDb()).grantAccess(user, Permissions.RO); + } finally { + arangoDB.deleteUser(user); + } } @ParameterizedTest @@ -514,7 +526,11 @@ void grantAccessRO(ArangoDB arangoDB) { void grantAccessNONE(ArangoDB arangoDB) { String user = "user-" + rnd(); arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).grantAccess(user, Permissions.NONE); + try { + arangoDB.db(getTestDb()).grantAccess(user, Permissions.NONE); + } finally { + arangoDB.deleteUser(user); + } } @ParameterizedTest @@ -530,7 +546,11 @@ void grantAccessUserNotFound(ArangoDatabase db) { void revokeAccess(ArangoDB arangoDB) { String user = "user-" + rnd(); arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).revokeAccess(user); + try { + arangoDB.db(getTestDb()).revokeAccess(user); + } finally { + arangoDB.deleteUser(user); + } } @ParameterizedTest @@ -546,7 +566,11 @@ void revokeAccessUserNotFound(ArangoDatabase db) { void resetAccess(ArangoDB arangoDB) { String user = "user-" + rnd(); arangoDB.createUser(user, "1234", null); - arangoDB.db(getTestDb()).resetAccess(user); + try { + arangoDB.db(getTestDb()).resetAccess(user); + } finally { + arangoDB.deleteUser(user); + } } @ParameterizedTest @@ -562,7 +586,11 @@ void resetAccessUserNotFound(ArangoDatabase db) { void grantDefaultCollectionAccess(ArangoDB arangoDB) { String user = "user-" + rnd(); arangoDB.createUser(user, "1234"); - arangoDB.db(getTestDb()).grantDefaultCollectionAccess(user, Permissions.RW); + try { + arangoDB.db(getTestDb()).grantDefaultCollectionAccess(user, Permissions.RW); + } finally { + arangoDB.deleteUser(user); + } } @ParameterizedTest @@ -1022,7 +1050,7 @@ void queryWithBindVars(ArangoDatabase db) { @ParameterizedTest @MethodSource("dbs") void queryWithRawBindVars(ArangoDatabase db) { - final Map bindVars = new HashMap<>(); + final Map bindVars = new HashMap<>(); bindVars.put("foo", RawJson.of("\"fooValue\"")); bindVars.put("bar", RawBytes.of(db.getSerde().serializeUserData(11))); diff --git a/test-functional/src/test/java/com/arangodb/ArangoSearchAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoSearchAsyncTest.java index 27cf4e31e..400c497ca 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoSearchAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoSearchAsyncTest.java @@ -28,6 +28,7 @@ import com.arangodb.model.InvertedIndexOptions; import com.arangodb.model.arangosearch.*; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -740,7 +741,7 @@ void arangoSearchOptions(ArangoDatabaseAsync db) throws ExecutionException, Inte } if (isEnterprise() && isAtLeastVersion(3, 12)) { - assertThat(properties.getOptimizeTopK()).containsExactly(optimizeTopK); + assertThat(properties.getOptimizeTopK()).containsExactly(optimizeTopK); } } @@ -980,6 +981,7 @@ void collationAnalyzer(ArangoDatabaseAsync db) throws ExecutionException, Interr } + @DisabledIfSystemProperty(named = "skipStatefulTests", matches = "^(|true|1)$", disabledReason = "Test requires server with analyzer model located at `/tmp/foo.bin`") @ParameterizedTest @MethodSource("asyncDbs") void classificationAnalyzer(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { @@ -1004,6 +1006,7 @@ void classificationAnalyzer(ArangoDatabaseAsync db) throws ExecutionException, I createGetAndDeleteTypedAnalyzer(db, analyzer); } + @DisabledIfSystemProperty(named = "skipStatefulTests", matches = "^(|true|1)$", disabledReason = "Test requires server with analyzer model located at `/tmp/foo.bin`") @ParameterizedTest @MethodSource("asyncDbs") void nearestNeighborsAnalyzer(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { diff --git a/test-functional/src/test/java/com/arangodb/ArangoSearchTest.java b/test-functional/src/test/java/com/arangodb/ArangoSearchTest.java index 0af1e8941..e29a6907e 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoSearchTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoSearchTest.java @@ -28,6 +28,7 @@ import com.arangodb.model.InvertedIndexOptions; import com.arangodb.model.arangosearch.*; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.condition.DisabledIfSystemProperty; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -986,6 +987,7 @@ void collationAnalyzer(ArangoDatabase db) { } + @DisabledIfSystemProperty(named = "skipStatefulTests", matches = "^(|true|1)$", disabledReason = "Test requires server with analyzer model located at `/tmp/foo.bin`") @ParameterizedTest @MethodSource("dbs") void classificationAnalyzer(ArangoDatabase db) { @@ -1010,6 +1012,7 @@ void classificationAnalyzer(ArangoDatabase db) { createGetAndDeleteTypedAnalyzer(db, analyzer); } + @DisabledIfSystemProperty(named = "skipStatefulTests", matches = "^(|true|1)$", disabledReason = "Test requires server with analyzer model located at `/tmp/foo.bin`") @ParameterizedTest @MethodSource("dbs") void nearestNeighborsAnalyzer(ArangoDatabase db) { diff --git a/test-functional/src/test/java/com/arangodb/ArangoViewAsyncTest.java b/test-functional/src/test/java/com/arangodb/ArangoViewAsyncTest.java index 362d07447..a1cd046f0 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoViewAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoViewAsyncTest.java @@ -22,6 +22,7 @@ import com.arangodb.entity.ViewEntity; import com.arangodb.entity.ViewType; +import com.arangodb.util.TestUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -49,8 +50,13 @@ static void init() { @MethodSource("asyncDbs") void create(ArangoDatabaseAsync db) throws ExecutionException, InterruptedException { String name = rndName(); - db.createView(name, ViewType.ARANGO_SEARCH).get(); - assertThat(db.view(name).exists().get()).isTrue(); + try { + db.createView(name, ViewType.ARANGO_SEARCH).get(); + assertThat(db.view(name).exists().get()).isTrue(); + } catch (Exception e) { + System.err.println("Got exception with name: " + TestUtils.unicodeEscape(name)); + throw e; + } } @ParameterizedTest diff --git a/test-functional/src/test/java/com/arangodb/ArangoViewTest.java b/test-functional/src/test/java/com/arangodb/ArangoViewTest.java index 6a2d67c2d..67482161b 100644 --- a/test-functional/src/test/java/com/arangodb/ArangoViewTest.java +++ b/test-functional/src/test/java/com/arangodb/ArangoViewTest.java @@ -22,6 +22,7 @@ import com.arangodb.entity.ViewEntity; import com.arangodb.entity.ViewType; +import com.arangodb.util.TestUtils; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -48,8 +49,13 @@ static void init() { @MethodSource("dbs") void create(ArangoDatabase db) { String name = rndName(); - db.createView(name, ViewType.ARANGO_SEARCH); - assertThat(db.view(name).exists()).isTrue(); + try { + db.createView(name, ViewType.ARANGO_SEARCH); + assertThat(db.view(name).exists()).isTrue(); + } catch (Exception e) { + System.err.println("Got exception with name: " + TestUtils.unicodeEscape(name)); + throw e; + } } @ParameterizedTest diff --git a/test-functional/src/test/java/com/arangodb/JwtAuthAsyncTest.java b/test-functional/src/test/java/com/arangodb/JwtAuthAsyncTest.java index 895dc8687..f4c63d7d0 100644 --- a/test-functional/src/test/java/com/arangodb/JwtAuthAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/JwtAuthAsyncTest.java @@ -1,5 +1,6 @@ package com.arangodb; +import com.arangodb.config.ArangoConfigProperties; import com.arangodb.config.ConfigUtils; import com.arangodb.internal.ArangoRequestParam; import org.junit.jupiter.api.BeforeAll; @@ -32,9 +33,10 @@ static void init() { } private static String getJwt(ArangoDB arangoDB) { + ArangoConfigProperties conf = ConfigUtils.loadConfig(); Map reqBody = new HashMap<>(); - reqBody.put("username", "root"); - reqBody.put("password", "test"); + reqBody.put("username", conf.getUser().orElse("root")); + reqBody.put("password", conf.getPassword().orElse(null)); Request req = Request.builder() .db(ArangoRequestParam.SYSTEM) diff --git a/test-functional/src/test/java/com/arangodb/JwtAuthTest.java b/test-functional/src/test/java/com/arangodb/JwtAuthTest.java index 1f9185430..b743db4a1 100644 --- a/test-functional/src/test/java/com/arangodb/JwtAuthTest.java +++ b/test-functional/src/test/java/com/arangodb/JwtAuthTest.java @@ -1,5 +1,6 @@ package com.arangodb; +import com.arangodb.config.ArangoConfigProperties; import com.arangodb.config.ConfigUtils; import com.arangodb.internal.ArangoRequestParam; import org.junit.jupiter.api.BeforeAll; @@ -31,9 +32,10 @@ static void init() { } private static String getJwt(ArangoDB arangoDB) { + ArangoConfigProperties conf = ConfigUtils.loadConfig(); Map reqBody = new HashMap<>(); - reqBody.put("username", "root"); - reqBody.put("password", "test"); + reqBody.put("username", conf.getUser().orElse("root")); + reqBody.put("password", conf.getPassword().orElse(null)); Request req = Request.builder() .db(ArangoRequestParam.SYSTEM) diff --git a/test-functional/src/test/java/com/arangodb/StreamTransactionAsyncTest.java b/test-functional/src/test/java/com/arangodb/StreamTransactionAsyncTest.java index 5c28f8b40..2ad090146 100644 --- a/test-functional/src/test/java/com/arangodb/StreamTransactionAsyncTest.java +++ b/test-functional/src/test/java/com/arangodb/StreamTransactionAsyncTest.java @@ -686,7 +686,7 @@ void createCursor(ArangoDatabaseAsync db) throws ExecutionException, Interrupted DocumentCreateEntity externalDoc = collection .insertDocument(new BaseDocument(), null).get(); - final Map bindVars = new HashMap<>(); + final Map bindVars = new HashMap<>(); bindVars.put("@collection", COLLECTION_NAME); bindVars.put("key", externalDoc.getKey()); diff --git a/test-functional/src/test/java/com/arangodb/StreamTransactionTest.java b/test-functional/src/test/java/com/arangodb/StreamTransactionTest.java index dff39ef83..826a6696f 100644 --- a/test-functional/src/test/java/com/arangodb/StreamTransactionTest.java +++ b/test-functional/src/test/java/com/arangodb/StreamTransactionTest.java @@ -691,7 +691,7 @@ void createCursor(ArangoDatabase db) { DocumentCreateEntity externalDoc = collection .insertDocument(new BaseDocument(), null); - final Map bindVars = new HashMap<>(); + final Map bindVars = new HashMap<>(); bindVars.put("@collection", COLLECTION_NAME); bindVars.put("key", externalDoc.getKey()); diff --git a/test-functional/src/test/java/com/arangodb/UserAgentTest.java b/test-functional/src/test/java/com/arangodb/UserAgentTest.java index 5f56d59b4..754663d32 100644 --- a/test-functional/src/test/java/com/arangodb/UserAgentTest.java +++ b/test-functional/src/test/java/com/arangodb/UserAgentTest.java @@ -10,7 +10,7 @@ class UserAgentTest extends BaseJunit5 { - private static final String EXPECTED_VERSION = "7.19.0"; + private static final String EXPECTED_VERSION = "7.22.1"; private static final boolean SHADED = Boolean.parseBoolean(System.getProperty("shaded")); diff --git a/test-functional/src/test/java/com/arangodb/model/AqlQueryOptionsTest.java b/test-functional/src/test/java/com/arangodb/model/AqlQueryOptionsTest.java index 39e9c1c43..c779464a1 100644 --- a/test-functional/src/test/java/com/arangodb/model/AqlQueryOptionsTest.java +++ b/test-functional/src/test/java/com/arangodb/model/AqlQueryOptionsTest.java @@ -15,11 +15,13 @@ void cloneable() { AqlQueryOptions options = new AqlQueryOptions() .cache(true) .stream(true) + .usePlanCache(true) .rules(rules) .shardIds("a", "b"); AqlQueryOptions clone = options.clone(); assertThat(clone.getCache()).isEqualTo(options.getCache()); assertThat(clone.getStream()).isEqualTo(options.getStream()); + assertThat(clone.getUsePlanCache()).isEqualTo(options.getUsePlanCache()); assertThat(clone.getRules()) .isEqualTo(options.getRules()) .isNotSameAs(options.getRules()); diff --git a/test-functional/src/test/java/com/arangodb/util/TestUtils.java b/test-functional/src/test/java/com/arangodb/util/TestUtils.java index 978fe29ee..7ee98b918 100644 --- a/test-functional/src/test/java/com/arangodb/util/TestUtils.java +++ b/test-functional/src/test/java/com/arangodb/util/TestUtils.java @@ -107,4 +107,20 @@ public static String generateRandomName(boolean extendedNames, int length) { } } + public static String unicodeEscape(String s) { + StringBuilder sb = new StringBuilder(); + s.codePoints().forEach(cp -> { + if (cp <= 0xFFFF) { + sb.append(String.format("\\u%04X", cp)); + } else { + // Convert supplementary characters to surrogate pairs + char[] surrogates = Character.toChars(cp); + for (char c : surrogates) { + sb.append(String.format("\\u%04X", (int) c)); + } + } + }); + return sb.toString(); + } + } diff --git a/test-functional/src/test/resources/META-INF/native-image/resource-config.json b/test-functional/src/test/resources/META-INF/native-image/resource-config.json index a6eea307e..9d96e052d 100644 --- a/test-functional/src/test/resources/META-INF/native-image/resource-config.json +++ b/test-functional/src/test/resources/META-INF/native-image/resource-config.json @@ -5,13 +5,13 @@ "pattern": "\\Qarangodb.properties\\E" }, { - "pattern": "\\Qarangodb-bad.properties\\E" + "pattern": "\\Qarangodb-ssl.properties\\E" }, { - "pattern": "\\Qarangodb-bad2.properties\\E" + "pattern": "\\Qarangodb-bad.properties\\E" }, { - "pattern":"\\Qarangodb-with-prefix.properties\\E" + "pattern": "\\Qarangodb-bad2.properties\\E" }, { "pattern": "\\Qlogback-test.xml\\E" diff --git a/test-functional/src/test/resources/allure.properties b/test-functional/src/test/resources/allure.properties new file mode 100644 index 000000000..80b02dde9 --- /dev/null +++ b/test-functional/src/test/resources/allure.properties @@ -0,0 +1 @@ +allure.results.directory=target/allure-results diff --git a/test-functional/src/test/resources/arangodb-ssl.properties b/test-functional/src/test/resources/arangodb-ssl.properties new file mode 100644 index 000000000..eb0c74f48 --- /dev/null +++ b/test-functional/src/test/resources/arangodb-ssl.properties @@ -0,0 +1,7 @@ +arangodb.hosts=172.28.0.1:8529 +arangodb.password=test +arangodb.useSsl=true +arangodb.sslCertValue=MIIDezCCAmOgAwIBAgIEeDCzXzANBgkqhkiG9w0BAQsFADBuMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMjAxMTAxMTg1MTE5WhcNMzAxMDMwMTg1MTE5WjBuMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1WiDnd4+uCmMG539ZNZB8NwI0RZF3sUSQGPx3lkqaFTZVEzMZL76HYvdc9Qg7difyKyQ09RLSpMALX9euSseD7bZGnfQH52BnKcT09eQ3wh7aVQ5sN2omygdHLC7X9usntxAfv7NzmvdogNXoJQyY/hSZff7RIqWH8NnAUKkjqOe6Bf5LDbxHKESmrFBxOCOnhcpvZWetwpiRdJVPwUn5P82CAZzfiBfmBZnB7D0l+/6Cv4jMuH26uAIcixnVekBQzl1RgwczuiZf2MGO64vDMMJJWE9ClZF1uQuQrwXF6qwhuP1Hnkii6wNbTtPWlGSkqeutr004+Hzbf8KnRY4PAgMBAAGjITAfMB0GA1UdDgQWBBTBrv9Awynt3C5IbaCNyOW5v4DNkTANBgkqhkiG9w0BAQsFAAOCAQEAIm9rPvDkYpmzpSIhR3VXG9Y71gxRDrqkEeLsMoEyqGnw/zx1bDCNeGg2PncLlW6zTIipEBooixIE9U7KxHgZxBy0Et6EEWvIUmnr6F4F+dbTD050GHlcZ7eOeqYTPYeQC502G1Fo4tdNi4lDP9L9XZpf7Q1QimRH2qaLS03ZFZa2tY7ah/RQqZL8Dkxx8/zc25sgTHVpxoK853glBVBs/ENMiyGJWmAXQayewY3EPt/9wGwV4KmU3dPDleQeXSUGPUISeQxFjy+jCw21pYviWVJTNBA9l5ny3GhEmcnOT/gQHCvVRLyGLMbaMZ4JrPwb+aAtBgrgeiK4xeSMMvrbhw== +arangodb.sslAlgorithm=SunX509 +arangodb.sslProtocol=TLS +arangodb.verifyHost=false diff --git a/test-non-functional/pom.xml b/test-non-functional/pom.xml index d842f3732..b533dbe59 100644 --- a/test-non-functional/pom.xml +++ b/test-non-functional/pom.xml @@ -8,7 +8,7 @@ ../test-parent com.arangodb test-parent - 7.19.0 + 7.22.1 test-non-functional @@ -17,7 +17,6 @@ 17 17 17 - true @@ -59,7 +58,7 @@ io.smallrye.config smallrye-config-core - 2.13.3 + 3.13.1 test diff --git a/test-non-functional/src/test/java/ConfigurationTest.java b/test-non-functional/src/test/java/ConfigurationTest.java new file mode 100644 index 000000000..b004c9b38 --- /dev/null +++ b/test-non-functional/src/test/java/ConfigurationTest.java @@ -0,0 +1,49 @@ +import com.arangodb.ArangoDB; +import com.arangodb.ContentType; +import com.arangodb.config.ArangoConfigProperties; +import com.arangodb.entity.ArangoDBVersion; +import com.arangodb.serde.jackson.JacksonSerde; +import org.junit.jupiter.api.Test; + +import java.util.Properties; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ConfigurationTest { + + @Test + void fallbackHost() { + final ArangoDB arangoDB = new ArangoDB.Builder() + .loadProperties(ArangoConfigProperties.fromFile()) + .serde(JacksonSerde.of(ContentType.JSON)) + .host("not-accessible", 8529) + .host("172.28.0.1", 8529) + .build(); + final ArangoDBVersion version = arangoDB.getVersion(); + assertThat(version).isNotNull(); + } + + @Test + void loadPropertiesWithPrefix() { + ArangoDB adb = new ArangoDB.Builder() + .loadProperties(ArangoConfigProperties.fromFile("arangodb-with-prefix.properties", "adb")) + .serde(JacksonSerde.of(ContentType.JSON)) + .build(); + adb.getVersion(); + adb.shutdown(); + } + + @Test + void loadConfigFromPropertiesWithPrefix() { + Properties props = new Properties(); + props.setProperty("adb.hosts", "172.28.0.1:8529"); + props.setProperty("adb.password", "test"); + ArangoDB adb = new ArangoDB.Builder() + .loadProperties(ArangoConfigProperties.fromProperties(props, "adb")) + .serde(JacksonSerde.of(ContentType.JSON)) + .build(); + adb.getVersion(); + adb.shutdown(); + } + +} diff --git a/test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java b/test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java index 4cac7a647..136869308 100644 --- a/test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java +++ b/test-non-functional/src/test/java/mp/ArangoConfigPropertiesMPImpl.java @@ -21,6 +21,9 @@ public final class ArangoConfigPropertiesMPImpl implements ArangoConfigPropertie private Optional jwt; private Optional timeout; private Optional useSsl; + private Optional sslCertValue; + private Optional sslAlgorithm; + private Optional sslProtocol; private Optional verifyHost; private Optional chunkSize; private Optional pipelining; @@ -71,6 +74,21 @@ public Optional getUseSsl() { return useSsl; } + @Override + public Optional getSslCertValue() { + return sslCertValue; + } + + @Override + public Optional getSslAlgorithm() { + return sslAlgorithm; + } + + @Override + public Optional getSslProtocol() { + return sslProtocol; + } + @Override public Optional getVerifyHost() { return verifyHost; diff --git a/test-non-functional/src/test/java/mp/ConfigMPDefaultsTest.java b/test-non-functional/src/test/java/mp/ConfigMPDefaultsTest.java index 5a8f861ef..ad98ea4e9 100644 --- a/test-non-functional/src/test/java/mp/ConfigMPDefaultsTest.java +++ b/test-non-functional/src/test/java/mp/ConfigMPDefaultsTest.java @@ -23,6 +23,9 @@ private void checkResult(ArangoConfigProperties config) { assertThat(config.getJwt()).isNotPresent(); assertThat(config.getTimeout()).isEmpty(); assertThat(config.getUseSsl()).isEmpty(); + assertThat(config.getSslCertValue()).isEmpty(); + assertThat(config.getSslAlgorithm()).isEmpty(); + assertThat(config.getSslProtocol()).isEmpty(); assertThat(config.getVerifyHost()).isEmpty(); assertThat(config.getChunkSize()).isEmpty(); assertThat(config.getPipelining()).isEmpty(); diff --git a/test-non-functional/src/test/java/mp/ConfigMPTest.java b/test-non-functional/src/test/java/mp/ConfigMPTest.java index 5d5f605e3..38a556be0 100644 --- a/test-non-functional/src/test/java/mp/ConfigMPTest.java +++ b/test-non-functional/src/test/java/mp/ConfigMPTest.java @@ -21,6 +21,9 @@ class ConfigMPTest { private final String jwt = "testJwt"; private final Integer timeout = 9876; private final Boolean useSsl = true; + private final String sslCertValue = "sslCertValue"; + private final String sslAlgorithm = "sslAlgorithm"; + private final String sslProtocol = "sslProtocol"; private final Boolean verifyHost = false; private final Integer vstChunkSize = 1234; private final Boolean pipelining = true; @@ -57,6 +60,9 @@ private void checkResult(ArangoConfigProperties config) { .hasValue(jwt); assertThat(config.getTimeout()).hasValue(timeout); assertThat(config.getUseSsl()).hasValue(useSsl); + assertThat(config.getSslCertValue()).hasValue(sslCertValue); + assertThat(config.getSslAlgorithm()).hasValue(sslAlgorithm); + assertThat(config.getSslProtocol()).hasValue(sslProtocol); assertThat(config.getVerifyHost()).hasValue(verifyHost); assertThat(config.getChunkSize()).hasValue(vstChunkSize); assertThat(config.getPipelining()).hasValue(pipelining); diff --git a/test-non-functional/src/test/java/mp/ConfigUtilsMP.java b/test-non-functional/src/test/java/mp/ConfigUtilsMP.java index dabd62cde..07277115f 100644 --- a/test-non-functional/src/test/java/mp/ConfigUtilsMP.java +++ b/test-non-functional/src/test/java/mp/ConfigUtilsMP.java @@ -1,7 +1,7 @@ package mp; import com.arangodb.config.ArangoConfigProperties; -import io.smallrye.config.PropertiesConfigSourceProvider; +import io.smallrye.config.PropertiesConfigSourceLoader; import io.smallrye.config.SmallRyeConfig; import io.smallrye.config.SmallRyeConfigBuilder; @@ -17,7 +17,7 @@ public static ArangoConfigProperties loadConfigMP(final String location) { public static ArangoConfigProperties loadConfigMP(final String location, final String prefix) { SmallRyeConfig cfg = new SmallRyeConfigBuilder() - .withSources(new PropertiesConfigSourceProvider(location, ConfigUtilsMP.class.getClassLoader(), false)) + .withSources(PropertiesConfigSourceLoader.inClassPath(location, 0, ConfigUtilsMP.class.getClassLoader())) .withMapping(ArangoConfigPropertiesMPImpl.class, prefix) .build(); return cfg.getConfigMapping(ArangoConfigPropertiesMPImpl.class, prefix); diff --git a/test-non-functional/src/test/resources/arangodb-config-test.properties b/test-non-functional/src/test/resources/arangodb-config-test.properties index 1d5e675af..251b348ae 100644 --- a/test-non-functional/src/test/resources/arangodb-config-test.properties +++ b/test-non-functional/src/test/resources/arangodb-config-test.properties @@ -5,6 +5,9 @@ adb.password=testPassword adb.jwt=testJwt adb.timeout=9876 adb.useSsl=true +adb.sslCertValue=sslCertValue +adb.sslAlgorithm=sslAlgorithm +adb.sslProtocol=sslProtocol adb.verifyHost=false adb.chunkSize=1234 adb.pipelining=true diff --git a/test-functional/src/test/resources/arangodb-with-prefix.properties b/test-non-functional/src/test/resources/arangodb-with-prefix.properties similarity index 100% rename from test-functional/src/test/resources/arangodb-with-prefix.properties rename to test-non-functional/src/test/resources/arangodb-with-prefix.properties diff --git a/test-parent/pom.xml b/test-parent/pom.xml index 09568371d..db836fa0e 100644 --- a/test-parent/pom.xml +++ b/test-parent/pom.xml @@ -7,7 +7,7 @@ com.arangodb arangodb-java-driver-parent - 7.19.0 + 7.22.1 pom @@ -15,9 +15,8 @@ false - 2.18.0 + 2.20.0 true - true 17 17 src/test/java @@ -79,35 +78,35 @@ org.junit junit-bom - 5.10.2 + 5.14.0 pom import org.eclipse yasson - 3.0.3 + 3.0.4 org.slf4j slf4j-simple - 2.0.9 + 2.0.17 org.assertj assertj-core - 3.25.3 + 3.27.6 org.awaitility awaitility - 4.2.1 + 4.3.0 test com.tngtech.archunit archunit-junit5 - 1.2.1 + 1.4.1 @@ -132,7 +131,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 3.3.1 + 3.5.4 true diff --git a/test-perf/pom.xml b/test-perf/pom.xml index a10f0d30c..53a6ca58d 100644 --- a/test-perf/pom.xml +++ b/test-perf/pom.xml @@ -7,13 +7,12 @@ ../test-parent com.arangodb test-parent - 7.19.0 + 7.22.1 test-perf - true 1.37 benchmarks @@ -43,7 +42,6 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.1 package diff --git a/test-resilience/pom.xml b/test-resilience/pom.xml index e278b6319..5b2cd3582 100644 --- a/test-resilience/pom.xml +++ b/test-resilience/pom.xml @@ -6,16 +6,12 @@ ../test-parent com.arangodb test-parent - 7.19.0 + 7.22.1 4.0.0 test-resilience - - true - - org.mock-server @@ -26,7 +22,7 @@ eu.rekawek.toxiproxy toxiproxy-java - 2.1.7 + 2.1.11 test @@ -42,7 +38,7 @@ io.netty netty-bom - 4.1.93.Final + 4.1.125.Final pom import diff --git a/tutorial/gradle/build.gradle b/tutorial/gradle/build.gradle index b7abd1bc9..aa871b6b7 100644 --- a/tutorial/gradle/build.gradle +++ b/tutorial/gradle/build.gradle @@ -12,7 +12,7 @@ repositories { } dependencies { - implementation 'com.arangodb:arangodb-java-driver:7.19.0' + implementation 'com.arangodb:arangodb-java-driver:7.22.1' } ext { diff --git a/tutorial/maven/pom.xml b/tutorial/maven/pom.xml index 845cdd7a1..12a978418 100644 --- a/tutorial/maven/pom.xml +++ b/tutorial/maven/pom.xml @@ -19,7 +19,7 @@ com.arangodb arangodb-java-driver - 7.19.0 + 7.22.1 diff --git a/vst-protocol/pom.xml b/vst-protocol/pom.xml index 342dd8889..33acf7522 100644 --- a/vst-protocol/pom.xml +++ b/vst-protocol/pom.xml @@ -5,10 +5,9 @@ 4.0.0 - ../release-parent com.arangodb - release-parent - 7.19.0 + arangodb-java-driver-parent + 7.22.1 vst-protocol @@ -17,7 +16,6 @@ com.arangodb.vst - false diff --git a/vst-protocol/src/main/java/com/arangodb/vst/internal/VstConnection.java b/vst-protocol/src/main/java/com/arangodb/vst/internal/VstConnection.java index 8b4cdc211..870051fa6 100644 --- a/vst-protocol/src/main/java/com/arangodb/vst/internal/VstConnection.java +++ b/vst-protocol/src/main/java/com/arangodb/vst/internal/VstConnection.java @@ -35,7 +35,6 @@ import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; @@ -150,11 +149,7 @@ public synchronized void open() throws IOException { LOGGER.debug(String.format("[%s]: Open connection to %s", connectionName, host)); } if (Boolean.TRUE.equals(useSsl)) { - if (sslContext != null) { - socket = sslContext.getSocketFactory().createSocket(); - } else { - socket = SSLSocketFactory.getDefault().createSocket(); - } + socket = sslContext.getSocketFactory().createSocket(); } else { socket = SocketFactory.getDefault().createSocket(); }